Whamcloud - gitweb
LU-13773 tests: subscript failure propagation
[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 LU-13314
45 ALWAYS_EXCEPT+=" 407     312     56ob"
46
47 if $SHARED_KEY; then
48         # bug number:    LU-9795 LU-9795 LU-9795 LU-9795
49         ALWAYS_EXCEPT+=" 17n     60a     133g    300f"
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 fi
65
66 # skip nfs tests on kernels >= 4.14.0 until they are fixed
67 if [ $LINUX_VERSION_CODE -ge $(version_code 4.14.0) ]; then
68         # bug number:   LU-12661
69         ALWAYS_EXCEPT+=" 817"
70 fi
71 # skip cgroup tests on RHEL8.1 kernels until they are fixed
72 if (( $LINUX_VERSION_CODE >= $(version_code 4.18.0) &&
73       $LINUX_VERSION_CODE <  $(version_code 5.4.0) )); then
74         # bug number:   LU-13063
75         ALWAYS_EXCEPT+=" 411"
76 fi
77
78 #                                  5          12     8   12  (min)"
79 [ "$SLOW" = "no" ] && EXCEPT_SLOW="27m 64b 68 71 115 135 136 300o"
80
81 if [ "$mds1_FSTYPE" = "zfs" ]; then
82         # bug number for skipped test:
83         ALWAYS_EXCEPT="$ALWAYS_EXCEPT  "
84         #                                               13    (min)"
85         [ "$SLOW" = "no" ] && EXCEPT_SLOW="$EXCEPT_SLOW 51b"
86 fi
87
88 # Get the SLES distro version
89 #
90 # Returns a version string that should only be used in comparing
91 # strings returned by version_code()
92 sles_version_code()
93 {
94         local version=$(grep VERSION_ID /etc/os-release | cut -d'"' -f2)
95
96         # All SuSE Linux versions have one decimal. version_code expects two
97         local sles_version=$version.0
98         version_code $sles_version
99 }
100
101 # Check if we are running on Ubuntu or SLES so we can make decisions on
102 # what tests to run
103 if [ -r /etc/SuSE-release ]; then
104         sles_version=$(sles_version_code)
105         [ $sles_version -lt $(version_code 11.4.0) ] &&
106                 # bug number for skipped test: LU-4341
107                 ALWAYS_EXCEPT="$ALWAYS_EXCEPT  170"
108         [ $sles_version -lt $(version_code 12.0.0) ] &&
109                 # bug number for skipped test: LU-3703
110                 ALWAYS_EXCEPT="$ALWAYS_EXCEPT  234"
111 elif [ -r /etc/os-release ]; then
112         if grep -qi ubuntu /etc/os-release; then
113                 ubuntu_version=$(version_code $(sed -n -e 's/"//g' \
114                                                 -e 's/^VERSION=//p' \
115                                                 /etc/os-release |
116                                                 awk '{ print $1 }'))
117
118                 if [[ $ubuntu_version -gt $(version_code 16.0.0) ]]; then
119                         # bug number for skipped test:
120                         #                LU-10334 LU-10366
121                         ALWAYS_EXCEPT+=" 103a     410"
122                 fi
123         fi
124 fi
125
126 build_test_filter
127 FAIL_ON_ERROR=false
128
129 cleanup() {
130         echo -n "cln.."
131         pgrep ll_sa > /dev/null && { echo "There are ll_sa thread not exit!"; exit 20; }
132         cleanupall ${FORCE} $* || { echo "FAILed to clean up"; exit 20; }
133 }
134 setup() {
135         echo -n "mnt.."
136         load_modules
137         setupall || exit 10
138         echo "done"
139 }
140
141 check_swap_layouts_support()
142 {
143         $LCTL get_param -n llite.*.sbi_flags | grep -q layout ||
144                 skip "Does not support layout lock."
145 }
146
147 check_swap_layout_no_dom()
148 {
149         local FOLDER=$1
150         local SUPP=$(lfs getstripe $FOLDER | grep "pattern:       mdt" | wc -l)
151         [ $SUPP -eq 0 ] || skip "layout swap does not support DOM files so far"
152 }
153
154 check_and_setup_lustre
155 DIR=${DIR:-$MOUNT}
156 assert_DIR
157
158 MAXFREE=${MAXFREE:-$((200000 * $OSTCOUNT))}
159
160 [ -f $DIR/d52a/foo ] && chattr -a $DIR/d52a/foo
161 [ -f $DIR/d52b/foo ] && chattr -i $DIR/d52b/foo
162 rm -rf $DIR/[Rdfs][0-9]*
163
164 # $RUNAS_ID may get set incorrectly somewhere else
165 [ $UID -eq 0 -a $RUNAS_ID -eq 0 ] &&
166         error "\$RUNAS_ID set to 0, but \$UID is also 0!"
167
168 check_runas_id $RUNAS_ID $RUNAS_GID $RUNAS
169
170 if [ "${ONLY}" = "MOUNT" ] ; then
171         echo "Lustre is up, please go on"
172         exit
173 fi
174
175 echo "preparing for tests involving mounts"
176 EXT2_DEV=${EXT2_DEV:-$TMP/SANITY.LOOP}
177 touch $EXT2_DEV
178 mke2fs -j -F $EXT2_DEV 8000 > /dev/null
179 echo # add a newline after mke2fs.
180
181 umask 077
182
183 OLDDEBUG=$(lctl get_param -n debug 2> /dev/null)
184 lctl set_param debug=-1 2> /dev/null || true
185 test_0a() {
186         touch $DIR/$tfile
187         $CHECKSTAT -t file $DIR/$tfile || error "$tfile is not a file"
188         rm $DIR/$tfile
189         $CHECKSTAT -a $DIR/$tfile || error "$tfile was not removed"
190 }
191 run_test 0a "touch; rm ====================="
192
193 test_0b() {
194         chmod 0755 $DIR || error "chmod 0755 $DIR failed"
195         $CHECKSTAT -p 0755 $DIR || error "$DIR permission is not 0755"
196 }
197 run_test 0b "chmod 0755 $DIR ============================="
198
199 test_0c() {
200         $LCTL get_param mdc.*.import | grep "state: FULL" ||
201                 error "import not FULL"
202         $LCTL get_param mdc.*.import | grep "target: $FSNAME-MDT" ||
203                 error "bad target"
204 }
205 run_test 0c "check import proc"
206
207 test_0d() { # LU-3397
208         [ $MGS_VERSION -lt $(version_code 2.10.57) ] &&
209                 skip "proc exports not supported before 2.10.57"
210
211         local mgs_exp="mgs.MGS.exports"
212         local client_uuid=$($LCTL get_param -n mgc.*.uuid)
213         local exp_client_nid
214         local exp_client_version
215         local exp_val
216         local imp_val
217         local temp_imp=$DIR/$tfile.import
218         local temp_exp=$DIR/$tfile.export
219
220         # save mgc import file to $temp_imp
221         $LCTL get_param mgc.*.import | tee $temp_imp
222         # Check if client uuid is found in MGS export
223         for exp_client_nid in $(do_facet mgs $LCTL get_param -N $mgs_exp.*); do
224                 [ $(do_facet mgs $LCTL get_param -n $exp_client_nid.uuid) == \
225                         $client_uuid ] &&
226                         break;
227         done
228         # save mgs export file to $temp_exp
229         do_facet mgs $LCTL get_param $exp_client_nid.export | tee $temp_exp
230
231         # Compare the value of field "connect_flags"
232         imp_val=$(grep "connect_flags" $temp_imp)
233         exp_val=$(grep "connect_flags" $temp_exp)
234         [ "$exp_val" == "$imp_val" ] ||
235                 error "export flags '$exp_val' != import flags '$imp_val'"
236
237         # Compare the value of client version
238         exp_client_version=$(awk '/target_version:/ { print $2 }' $temp_exp)
239         exp_val=$(version_code $exp_client_version)
240         imp_val=$CLIENT_VERSION
241         [ "$exp_val" == "$imp_val" ] ||
242                 error "export client version '$exp_val' != '$imp_val'"
243 }
244 run_test 0d "check export proc ============================="
245
246 test_1() {
247         test_mkdir $DIR/$tdir
248         test_mkdir $DIR/$tdir/d2
249         mkdir $DIR/$tdir/d2 && error "we expect EEXIST, but not returned"
250         $CHECKSTAT -t dir $DIR/$tdir/d2 || error "$tdir/d2 is not a dir"
251         rmdir $DIR/$tdir/d2
252         rmdir $DIR/$tdir
253         $CHECKSTAT -a $DIR/$tdir || error "$tdir was not removed"
254 }
255 run_test 1 "mkdir; remkdir; rmdir"
256
257 test_2() {
258         test_mkdir $DIR/$tdir
259         touch $DIR/$tdir/$tfile || error "touch $tdir/$tfile failed"
260         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "$tdir/$tfile not a file"
261         rm -r $DIR/$tdir
262         $CHECKSTAT -a $DIR/$tdir/$tfile || error "$tdir/$file is not removed"
263 }
264 run_test 2 "mkdir; touch; rmdir; check file"
265
266 test_3() {
267         test_mkdir $DIR/$tdir
268         $CHECKSTAT -t dir $DIR/$tdir || error "$tdir is not a directory"
269         touch $DIR/$tdir/$tfile
270         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "$tdir/$tfile not a file"
271         rm -r $DIR/$tdir
272         $CHECKSTAT -a $DIR/$tdir || error "$tdir is not removed"
273 }
274 run_test 3 "mkdir; touch; rmdir; check dir"
275
276 # LU-4471 - failed rmdir on remote directories still removes directory on MDT0
277 test_4() {
278         test_mkdir -i 1 $DIR/$tdir
279
280         touch $DIR/$tdir/$tfile ||
281                 error "Create file under remote directory failed"
282
283         rmdir $DIR/$tdir &&
284                 error "Expect error removing in-use dir $DIR/$tdir"
285
286         test -d $DIR/$tdir || error "Remote directory disappeared"
287
288         rm -rf $DIR/$tdir || error "remove remote dir error"
289 }
290 run_test 4 "mkdir; touch dir/file; rmdir; checkdir (expect error)"
291
292 test_5() {
293         test_mkdir $DIR/$tdir
294         test_mkdir $DIR/$tdir/d2
295         chmod 0707 $DIR/$tdir/d2 || error "chmod 0707 $tdir/d2 failed"
296         $CHECKSTAT -t dir -p 0707 $DIR/$tdir/d2 || error "$tdir/d2 not mode 707"
297         $CHECKSTAT -t dir $DIR/$tdir/d2 || error "$tdir/d2 is not a directory"
298 }
299 run_test 5 "mkdir .../d5 .../d5/d2; chmod .../d5/d2"
300
301 test_6a() {
302         touch $DIR/$tfile || error "touch $DIR/$tfile failed"
303         chmod 0666 $DIR/$tfile || error "chmod 0666 $tfile failed"
304         $CHECKSTAT -t file -p 0666 -u \#$UID $DIR/$tfile ||
305                 error "$tfile does not have perm 0666 or UID $UID"
306         $RUNAS chmod 0444 $DIR/$tfile && error "chmod $tfile worked on UID $UID"
307         $CHECKSTAT -t file -p 0666 -u \#$UID $DIR/$tfile ||
308                 error "$tfile should be 0666 and owned by UID $UID"
309 }
310 run_test 6a "touch f6a; chmod f6a; $RUNAS chmod f6a (should return error) =="
311
312 test_6c() {
313         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID"
314
315         touch $DIR/$tfile
316         chown $RUNAS_ID $DIR/$tfile || error "chown $RUNAS_ID $file failed"
317         $CHECKSTAT -t file -u \#$RUNAS_ID $DIR/$tfile ||
318                 error "$tfile should be owned by UID $RUNAS_ID"
319         $RUNAS chown $UID $DIR/$tfile && error "chown $UID $file succeeded"
320         $CHECKSTAT -t file -u \#$RUNAS_ID $DIR/$tfile ||
321                 error "$tfile should be owned by UID $RUNAS_ID"
322 }
323 run_test 6c "touch f6c; chown f6c; $RUNAS chown f6c (should return error) =="
324
325 test_6e() {
326         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID"
327
328         touch $DIR/$tfile
329         chgrp $RUNAS_ID $DIR/$tfile || error "chgrp $RUNAS_ID $file failed"
330         $CHECKSTAT -t file -u \#$UID -g \#$RUNAS_ID $DIR/$tfile ||
331                 error "$tfile should be owned by GID $UID"
332         $RUNAS chgrp $UID $DIR/$tfile && error "chgrp $UID $file succeeded"
333         $CHECKSTAT -t file -u \#$UID -g \#$RUNAS_ID $DIR/$tfile ||
334                 error "$tfile should be owned by UID $UID and GID $RUNAS_ID"
335 }
336 run_test 6e "touch+chgrp $tfile; $RUNAS chgrp $tfile (should return error)"
337
338 test_6g() {
339         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID"
340
341         test_mkdir $DIR/$tdir
342         chmod 777 $DIR/$tdir || error "chmod 0777 $tdir failed"
343         $RUNAS mkdir $DIR/$tdir/d || error "mkdir $tdir/d failed"
344         chmod g+s $DIR/$tdir/d || error "chmod g+s $tdir/d failed"
345         test_mkdir $DIR/$tdir/d/subdir
346         $CHECKSTAT -g \#$RUNAS_GID $DIR/$tdir/d/subdir ||
347                 error "$tdir/d/subdir should be GID $RUNAS_GID"
348         if [[ $MDSCOUNT -gt 1 ]]; then
349                 # check remote dir sgid inherite
350                 $LFS mkdir -i 0 $DIR/$tdir.local ||
351                         error "mkdir $tdir.local failed"
352                 chmod g+s $DIR/$tdir.local ||
353                         error "chmod $tdir.local failed"
354                 chgrp $RUNAS_GID $DIR/$tdir.local ||
355                         error "chgrp $tdir.local failed"
356                 $LFS mkdir -i 1 $DIR/$tdir.local/$tdir.remote ||
357                         error "mkdir $tdir.remote failed"
358                 $CHECKSTAT -g \#$RUNAS_GID $DIR/$tdir.local/$tdir.remote ||
359                         error "$tdir.remote should be owned by $UID.$RUNAS_ID"
360                 $CHECKSTAT -p 02755 $DIR/$tdir.local/$tdir.remote ||
361                         error "$tdir.remote should be mode 02755"
362         fi
363 }
364 run_test 6g "verify new dir in sgid dir inherits group"
365
366 test_6h() { # bug 7331
367         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID"
368
369         touch $DIR/$tfile || error "touch failed"
370         chown $RUNAS_ID:$RUNAS_GID $DIR/$tfile || error "initial chown failed"
371         $RUNAS -G$RUNAS_GID chown $RUNAS_ID:0 $DIR/$tfile &&
372                 error "chown $RUNAS_ID:0 $tfile worked as GID $RUNAS_GID"
373         $CHECKSTAT -t file -u \#$RUNAS_ID -g \#$RUNAS_GID $DIR/$tfile ||
374                 error "$tdir/$tfile should be UID $RUNAS_UID GID $RUNAS_GID"
375 }
376 run_test 6h "$RUNAS chown RUNAS_ID.0 .../$tfile (should return error)"
377
378 test_7a() {
379         test_mkdir $DIR/$tdir
380         $MCREATE $DIR/$tdir/$tfile
381         chmod 0666 $DIR/$tdir/$tfile
382         $CHECKSTAT -t file -p 0666 $DIR/$tdir/$tfile ||
383                 error "$tdir/$tfile should be mode 0666"
384 }
385 run_test 7a "mkdir .../d7; mcreate .../d7/f; chmod .../d7/f ===="
386
387 test_7b() {
388         if [ ! -d $DIR/$tdir ]; then
389                 test_mkdir $DIR/$tdir
390         fi
391         $MCREATE $DIR/$tdir/$tfile
392         echo -n foo > $DIR/$tdir/$tfile
393         [ "$(cat $DIR/$tdir/$tfile)" = "foo" ] || error "$tdir/$tfile not 'foo'"
394         $CHECKSTAT -t file -s 3 $DIR/$tdir/$tfile || error "$tfile size not 3"
395 }
396 run_test 7b "mkdir .../d7; mcreate d7/f2; echo foo > d7/f2 ====="
397
398 test_8() {
399         test_mkdir $DIR/$tdir
400         touch $DIR/$tdir/$tfile
401         chmod 0666 $DIR/$tdir/$tfile
402         $CHECKSTAT -t file -p 0666 $DIR/$tdir/$tfile ||
403                 error "$tfile mode not 0666"
404 }
405 run_test 8 "mkdir .../d8; touch .../d8/f; chmod .../d8/f ======="
406
407 test_9() {
408         test_mkdir $DIR/$tdir
409         test_mkdir $DIR/$tdir/d2
410         test_mkdir $DIR/$tdir/d2/d3
411         $CHECKSTAT -t dir $DIR/$tdir/d2/d3 || error "$tdir/d2/d3 not a dir"
412 }
413 run_test 9 "mkdir .../d9 .../d9/d2 .../d9/d2/d3 ================"
414
415 test_10() {
416         test_mkdir $DIR/$tdir
417         test_mkdir $DIR/$tdir/d2
418         touch $DIR/$tdir/d2/$tfile
419         $CHECKSTAT -t file $DIR/$tdir/d2/$tfile ||
420                 error "$tdir/d2/$tfile not a file"
421 }
422 run_test 10 "mkdir .../d10 .../d10/d2; touch .../d10/d2/f ======"
423
424 test_11() {
425         test_mkdir $DIR/$tdir
426         test_mkdir $DIR/$tdir/d2
427         chmod 0666 $DIR/$tdir/d2
428         chmod 0705 $DIR/$tdir/d2
429         $CHECKSTAT -t dir -p 0705 $DIR/$tdir/d2 ||
430                 error "$tdir/d2 mode not 0705"
431 }
432 run_test 11 "mkdir .../d11 d11/d2; chmod .../d11/d2 ============"
433
434 test_12() {
435         test_mkdir $DIR/$tdir
436         touch $DIR/$tdir/$tfile
437         chmod 0666 $DIR/$tdir/$tfile
438         chmod 0654 $DIR/$tdir/$tfile
439         $CHECKSTAT -t file -p 0654 $DIR/$tdir/$tfile ||
440                 error "$tdir/d2 mode not 0654"
441 }
442 run_test 12 "touch .../d12/f; chmod .../d12/f .../d12/f ========"
443
444 test_13() {
445         test_mkdir $DIR/$tdir
446         dd if=/dev/zero of=$DIR/$tdir/$tfile count=10
447         >  $DIR/$tdir/$tfile
448         $CHECKSTAT -t file -s 0 $DIR/$tdir/$tfile ||
449                 error "$tdir/$tfile size not 0 after truncate"
450 }
451 run_test 13 "creat .../d13/f; dd .../d13/f; > .../d13/f ========"
452
453 test_14() {
454         test_mkdir $DIR/$tdir
455         touch $DIR/$tdir/$tfile
456         rm $DIR/$tdir/$tfile
457         $CHECKSTAT -a $DIR/$tdir/$tfile || error "$tdir/$tfile not removed"
458 }
459 run_test 14 "touch .../d14/f; rm .../d14/f; rm .../d14/f ======="
460
461 test_15() {
462         test_mkdir $DIR/$tdir
463         touch $DIR/$tdir/$tfile
464         mv $DIR/$tdir/$tfile $DIR/$tdir/${tfile}_2
465         $CHECKSTAT -t file $DIR/$tdir/${tfile}_2 ||
466                 error "$tdir/${tfile_2} not a file after rename"
467         rm $DIR/$tdir/${tfile}_2 || error "unlink failed after rename"
468 }
469 run_test 15 "touch .../d15/f; mv .../d15/f .../d15/f2 =========="
470
471 test_16() {
472         test_mkdir $DIR/$tdir
473         touch $DIR/$tdir/$tfile
474         rm -rf $DIR/$tdir/$tfile
475         $CHECKSTAT -a $DIR/$tdir/$tfile || error "$tdir/$tfile not removed"
476 }
477 run_test 16 "touch .../d16/f; rm -rf .../d16/f"
478
479 test_17a() {
480         test_mkdir $DIR/$tdir
481         touch $DIR/$tdir/$tfile
482         ln -s $DIR/$tdir/$tfile $DIR/$tdir/l-exist
483         ls -l $DIR/$tdir
484         $CHECKSTAT -l $DIR/$tdir/$tfile $DIR/$tdir/l-exist ||
485                 error "$tdir/l-exist not a symlink"
486         $CHECKSTAT -f -t f $DIR/$tdir/l-exist ||
487                 error "$tdir/l-exist not referencing a file"
488         rm -f $DIR/$tdir/l-exist
489         $CHECKSTAT -a $DIR/$tdir/l-exist || error "$tdir/l-exist not removed"
490 }
491 run_test 17a "symlinks: create, remove (real)"
492
493 test_17b() {
494         test_mkdir $DIR/$tdir
495         ln -s no-such-file $DIR/$tdir/l-dangle
496         ls -l $DIR/$tdir
497         $CHECKSTAT -l no-such-file $DIR/$tdir/l-dangle ||
498                 error "$tdir/l-dangle not referencing no-such-file"
499         $CHECKSTAT -fa $DIR/$tdir/l-dangle ||
500                 error "$tdir/l-dangle not referencing non-existent file"
501         rm -f $DIR/$tdir/l-dangle
502         $CHECKSTAT -a $DIR/$tdir/l-dangle || error "$tdir/l-dangle not removed"
503 }
504 run_test 17b "symlinks: create, remove (dangling)"
505
506 test_17c() { # bug 3440 - don't save failed open RPC for replay
507         test_mkdir $DIR/$tdir
508         ln -s foo $DIR/$tdir/$tfile
509         cat $DIR/$tdir/$tfile && error "opened non-existent symlink" || true
510 }
511 run_test 17c "symlinks: open dangling (should return error)"
512
513 test_17d() {
514         test_mkdir $DIR/$tdir
515         ln -s foo $DIR/$tdir/$tfile
516         touch $DIR/$tdir/$tfile || error "creating to new symlink"
517 }
518 run_test 17d "symlinks: create dangling"
519
520 test_17e() {
521         test_mkdir $DIR/$tdir
522         local foo=$DIR/$tdir/$tfile
523         ln -s $foo $foo || error "create symlink failed"
524         ls -l $foo || error "ls -l failed"
525         ls $foo && error "ls not failed" || true
526 }
527 run_test 17e "symlinks: create recursive symlink (should return error)"
528
529 test_17f() {
530         test_mkdir $DIR/$tdir
531         ln -s 1234567890/2234567890/3234567890/4234567890 $DIR/$tdir/111
532         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890 $DIR/$tdir/222
533         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890/7234567890/8234567890 $DIR/$tdir/333
534         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890/7234567890/8234567890/9234567890/a234567890/b234567890 $DIR/$tdir/444
535         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890/7234567890/8234567890/9234567890/a234567890/b234567890/c234567890/d234567890/f234567890 $DIR/$tdir/555
536         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
537         ls -l  $DIR/$tdir
538 }
539 run_test 17f "symlinks: long and very long symlink name"
540
541 # str_repeat(S, N) generate a string that is string S repeated N times
542 str_repeat() {
543         local s=$1
544         local n=$2
545         local ret=''
546         while [ $((n -= 1)) -ge 0 ]; do
547                 ret=$ret$s
548         done
549         echo $ret
550 }
551
552 # Long symlinks and LU-2241
553 test_17g() {
554         test_mkdir $DIR/$tdir
555         local TESTS="59 60 61 4094 4095"
556
557         # Fix for inode size boundary in 2.1.4
558         [ $MDS1_VERSION -lt $(version_code 2.1.4) ] &&
559                 TESTS="4094 4095"
560
561         # Patch not applied to 2.2 or 2.3 branches
562         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] &&
563         [ $MDS1_VERSION -le $(version_code 2.3.55) ] &&
564                 TESTS="4094 4095"
565
566         for i in $TESTS; do
567                 local SYMNAME=$(str_repeat 'x' $i)
568                 ln -s $SYMNAME $DIR/$tdir/f$i || error "failed $i-char symlink"
569                 readlink $DIR/$tdir/f$i || error "failed $i-char readlink"
570         done
571 }
572 run_test 17g "symlinks: really long symlink name and inode boundaries"
573
574 test_17h() { #bug 17378
575         [ $PARALLEL == "yes" ] && skip "skip parallel run"
576         remote_mds_nodsh && skip "remote MDS with nodsh"
577
578         local mdt_idx
579
580         test_mkdir $DIR/$tdir
581         mdt_idx=$($LFS getdirstripe -i $DIR/$tdir)
582         $LFS setstripe -c -1 $DIR/$tdir
583         #define OBD_FAIL_MDS_LOV_PREP_CREATE 0x141
584         do_facet mds$((mdt_idx + 1)) lctl set_param fail_loc=0x80000141
585         touch $DIR/$tdir/$tfile || true
586 }
587 run_test 17h "create objects: lov_free_memmd() doesn't lbug"
588
589 test_17i() { #bug 20018
590         [ $PARALLEL == "yes" ] && skip "skip parallel run"
591         remote_mds_nodsh && skip "remote MDS with nodsh"
592
593         local foo=$DIR/$tdir/$tfile
594         local mdt_idx
595
596         test_mkdir -c1 $DIR/$tdir
597         mdt_idx=$($LFS getdirstripe -i $DIR/$tdir)
598         ln -s $foo $foo || error "create symlink failed"
599 #define OBD_FAIL_MDS_READLINK_EPROTO     0x143
600         do_facet mds$((mdt_idx + 1)) lctl set_param fail_loc=0x80000143
601         ls -l $foo && error "error not detected"
602         return 0
603 }
604 run_test 17i "don't panic on short symlink (should return error)"
605
606 test_17k() { #bug 22301
607         [ $PARALLEL == "yes" ] && skip "skip parallel run"
608         [[ -z "$(which rsync 2>/dev/null)" ]] &&
609                 skip "no rsync command"
610         rsync --help | grep -q xattr ||
611                 skip_env "$(rsync --version | head -n1) does not support xattrs"
612         test_mkdir $DIR/$tdir
613         test_mkdir $DIR/$tdir.new
614         touch $DIR/$tdir/$tfile
615         ln -s $DIR/$tdir/$tfile $DIR/$tdir/$tfile.lnk
616         rsync -av -X $DIR/$tdir/ $DIR/$tdir.new ||
617                 error "rsync failed with xattrs enabled"
618 }
619 run_test 17k "symlinks: rsync with xattrs enabled"
620
621 test_17l() { # LU-279
622         [[ -z "$(which getfattr 2>/dev/null)" ]] &&
623                 skip "no getfattr command"
624
625         test_mkdir $DIR/$tdir
626         touch $DIR/$tdir/$tfile
627         ln -s $DIR/$tdir/$tfile $DIR/$tdir/$tfile.lnk
628         for path in "$DIR/$tdir" "$DIR/$tdir/$tfile" "$DIR/$tdir/$tfile.lnk"; do
629                 # -h to not follow symlinks. -m '' to list all the xattrs.
630                 # grep to remove first line: '# file: $path'.
631                 for xattr in `getfattr -hm '' $path 2>/dev/null | grep -v '^#'`;
632                 do
633                         lgetxattr_size_check $path $xattr ||
634                                 error "lgetxattr_size_check $path $xattr failed"
635                 done
636         done
637 }
638 run_test 17l "Ensure lgetxattr's returned xattr size is consistent"
639
640 # LU-1540
641 test_17m() {
642         [ $PARALLEL == "yes" ] && skip "skip parallel run"
643         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
644         remote_mds_nodsh && skip "remote MDS with nodsh"
645         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] &&
646         [ $MDS1_VERSION -le $(version_code 2.2.93) ] &&
647                 skip "MDS 2.2.0-2.2.93 do not NUL-terminate symlinks"
648
649         local short_sym="0123456789"
650         local wdir=$DIR/$tdir
651         local i
652
653         test_mkdir $wdir
654         long_sym=$short_sym
655         # create a long symlink file
656         for ((i = 0; i < 4; ++i)); do
657                 long_sym=${long_sym}${long_sym}
658         done
659
660         echo "create 512 short and long symlink files under $wdir"
661         for ((i = 0; i < 256; ++i)); do
662                 ln -sf ${long_sym}"a5a5" $wdir/long-$i
663                 ln -sf ${short_sym}"a5a5" $wdir/short-$i
664         done
665
666         echo "erase them"
667         rm -f $wdir/*
668         sync
669         wait_delete_completed
670
671         echo "recreate the 512 symlink files with a shorter string"
672         for ((i = 0; i < 512; ++i)); do
673                 # rewrite the symlink file with a shorter string
674                 ln -sf ${long_sym} $wdir/long-$i || error "long_sym failed"
675                 ln -sf ${short_sym} $wdir/short-$i || error "short_sym failed"
676         done
677
678         local mds_index=$(($($LFS getstripe -m $wdir) + 1))
679         local devname=$(mdsdevname $mds_index)
680
681         echo "stop and checking mds${mds_index}:"
682         # e2fsck should not return error
683         stop mds${mds_index}
684         run_e2fsck $(facet_active_host mds${mds_index}) $devname -n
685         rc=$?
686
687         start mds${mds_index} $devname $MDS_MOUNT_OPTS ||
688                 error "start mds${mds_index} failed"
689         df $MOUNT > /dev/null 2>&1
690         [ $rc -eq 0 ] ||
691                 error "e2fsck detected error for short/long symlink: rc=$rc"
692         rm -f $wdir/*
693 }
694 run_test 17m "run e2fsck against MDT which contains short/long symlink"
695
696 check_fs_consistency_17n() {
697         local mdt_index
698         local rc=0
699
700         # create/unlink in 17n only change 2 MDTs(MDT1/MDT2),
701         # so it only check MDT1/MDT2 instead of all of MDTs.
702         for mdt_index in 1 2; do
703                 local devname=$(mdsdevname $mdt_index)
704                 # e2fsck should not return error
705                 stop mds${mdt_index}
706                 run_e2fsck $(facet_active_host mds$mdt_index) $devname -n ||
707                         rc=$((rc + $?))
708
709                 start mds${mdt_index} $devname $MDS_MOUNT_OPTS ||
710                         error "mount mds$mdt_index failed"
711                 df $MOUNT > /dev/null 2>&1
712         done
713         return $rc
714 }
715
716 test_17n() {
717         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
718         [ $PARALLEL == "yes" ] && skip "skip parallel run"
719         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
720         remote_mds_nodsh && skip "remote MDS with nodsh"
721         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] &&
722         [ $MDS1_VERSION -le $(version_code 2.2.93) ] &&
723                 skip "MDS 2.2.0-2.2.93 do not NUL-terminate symlinks"
724
725         local i
726
727         test_mkdir $DIR/$tdir
728         for ((i=0; i<10; i++)); do
729                 $LFS mkdir -i1 -c2 $DIR/$tdir/remote_dir_${i} ||
730                         error "create remote dir error $i"
731                 createmany -o $DIR/$tdir/remote_dir_${i}/f 10 ||
732                         error "create files under remote dir failed $i"
733         done
734
735         check_fs_consistency_17n ||
736                 error "e2fsck report error after create files under remote dir"
737
738         for ((i = 0; i < 10; i++)); do
739                 rm -rf $DIR/$tdir/remote_dir_${i} ||
740                         error "destroy remote dir error $i"
741         done
742
743         check_fs_consistency_17n ||
744                 error "e2fsck report error after unlink files under remote dir"
745
746         [ $MDS1_VERSION -lt $(version_code 2.4.50) ] &&
747                 skip "lustre < 2.4.50 does not support migrate mv"
748
749         for ((i = 0; i < 10; i++)); do
750                 mkdir -p $DIR/$tdir/remote_dir_${i}
751                 createmany -o $DIR/$tdir/remote_dir_${i}/f 10 ||
752                         error "create files under remote dir failed $i"
753                 $LFS migrate --mdt-index 1 $DIR/$tdir/remote_dir_${i} ||
754                         error "migrate remote dir error $i"
755         done
756         check_fs_consistency_17n || error "e2fsck report error after migration"
757
758         for ((i = 0; i < 10; i++)); do
759                 rm -rf $DIR/$tdir/remote_dir_${i} ||
760                         error "destroy remote dir error $i"
761         done
762
763         check_fs_consistency_17n || error "e2fsck report error after unlink"
764 }
765 run_test 17n "run e2fsck against master/slave MDT which contains remote dir"
766
767 test_17o() {
768         remote_mds_nodsh && skip "remote MDS with nodsh"
769         [ $MDS1_VERSION -lt $(version_code 2.3.64) ] &&
770                 skip "Need MDS version at least 2.3.64"
771
772         local wdir=$DIR/${tdir}o
773         local mdt_index
774         local rc=0
775
776         test_mkdir $wdir
777         touch $wdir/$tfile
778         mdt_index=$($LFS getstripe -m $wdir/$tfile)
779         mdt_index=$((mdt_index + 1))
780
781         cancel_lru_locks mdc
782         #fail mds will wait the failover finish then set
783         #following fail_loc to avoid interfer the recovery process.
784         fail mds${mdt_index}
785
786         #define OBD_FAIL_OSD_LMA_INCOMPAT 0x194
787         do_facet mds${mdt_index} lctl set_param fail_loc=0x194
788         ls -l $wdir/$tfile && rc=1
789         do_facet mds${mdt_index} lctl set_param fail_loc=0
790         [[ $rc -eq 0 ]] || error "stat file should fail"
791 }
792 run_test 17o "stat file with incompat LMA feature"
793
794 test_18() {
795         touch $DIR/$tfile || error "Failed to touch $DIR/$tfile: $?"
796         ls $DIR || error "Failed to ls $DIR: $?"
797 }
798 run_test 18 "touch .../f ; ls ... =============================="
799
800 test_19a() {
801         touch $DIR/$tfile
802         ls -l $DIR
803         rm $DIR/$tfile
804         $CHECKSTAT -a $DIR/$tfile || error "$tfile was not removed"
805 }
806 run_test 19a "touch .../f19 ; ls -l ... ; rm .../f19 ==========="
807
808 test_19b() {
809         ls -l $DIR/$tfile && error "ls -l $tfile failed"|| true
810 }
811 run_test 19b "ls -l .../f19 (should return error) =============="
812
813 test_19c() {
814         [ $RUNAS_ID -eq $UID ] &&
815                 skip_env "RUNAS_ID = UID = $UID -- skipping"
816
817         $RUNAS touch $DIR/$tfile && error "create non-root file failed" || true
818 }
819 run_test 19c "$RUNAS touch .../f19 (should return error) =="
820
821 test_19d() {
822         cat $DIR/f19 && error || true
823 }
824 run_test 19d "cat .../f19 (should return error) =============="
825
826 test_20() {
827         touch $DIR/$tfile
828         rm $DIR/$tfile
829         touch $DIR/$tfile
830         rm $DIR/$tfile
831         touch $DIR/$tfile
832         rm $DIR/$tfile
833         $CHECKSTAT -a $DIR/$tfile || error "$tfile was not removed"
834 }
835 run_test 20 "touch .../f ; ls -l ..."
836
837 test_21() {
838         test_mkdir $DIR/$tdir
839         [ -f $DIR/$tdir/dangle ] && rm -f $DIR/$tdir/dangle
840         ln -s dangle $DIR/$tdir/link
841         echo foo >> $DIR/$tdir/link
842         cat $DIR/$tdir/dangle
843         $CHECKSTAT -t link $DIR/$tdir/link || error "$tdir/link not a link"
844         $CHECKSTAT -f -t file $DIR/$tdir/link ||
845                 error "$tdir/link not linked to a file"
846 }
847 run_test 21 "write to dangling link"
848
849 test_22() {
850         local wdir=$DIR/$tdir
851         test_mkdir $wdir
852         chown $RUNAS_ID:$RUNAS_GID $wdir
853         (cd $wdir || error "cd $wdir failed";
854                 $RUNAS tar cf - /etc/hosts /etc/sysconfig/network |
855                 $RUNAS tar xf -)
856         ls -lR $wdir/etc || error "ls -lR $wdir/etc failed"
857         $CHECKSTAT -t dir $wdir/etc || error "checkstat -t dir failed"
858         $CHECKSTAT -u \#$RUNAS_ID -g \#$RUNAS_GID $wdir/etc ||
859                 error "checkstat -u failed"
860 }
861 run_test 22 "unpack tar archive as non-root user"
862
863 # was test_23
864 test_23a() {
865         test_mkdir $DIR/$tdir
866         local file=$DIR/$tdir/$tfile
867
868         openfile -f O_CREAT:O_EXCL $file || error "$file create failed"
869         openfile -f O_CREAT:O_EXCL $file &&
870                 error "$file recreate succeeded" || true
871 }
872 run_test 23a "O_CREAT|O_EXCL in subdir"
873
874 test_23b() { # bug 18988
875         test_mkdir $DIR/$tdir
876         local file=$DIR/$tdir/$tfile
877
878         rm -f $file
879         echo foo > $file || error "write filed"
880         echo bar >> $file || error "append filed"
881         $CHECKSTAT -s 8 $file || error "wrong size"
882         rm $file
883 }
884 run_test 23b "O_APPEND check"
885
886 # LU-9409, size with O_APPEND and tiny writes
887 test_23c() {
888         local file=$DIR/$tfile
889
890         # single dd
891         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=8 count=800
892         $CHECKSTAT -s 6400 $file || error "wrong size, expected 6400"
893         rm -f $file
894
895         # racing tiny writes
896         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=8 count=800 &
897         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=8 count=800 &
898         wait
899         $CHECKSTAT -s 12800 $file || error "wrong size, expected 12800"
900         rm -f $file
901
902         #racing tiny & normal writes
903         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=4096 count=4 &
904         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=8 count=100 &
905         wait
906         $CHECKSTAT -s 17184 $file || error "wrong size, expected 17184"
907         rm -f $file
908
909         #racing tiny & normal writes 2, ugly numbers
910         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=4099 count=11 &
911         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=17 count=173 &
912         wait
913         $CHECKSTAT -s 48030 $file || error "wrong size, expected 48030"
914         rm -f $file
915 }
916 run_test 23c "O_APPEND size checks for tiny writes"
917
918 # LU-11069 file offset is correct after appending writes
919 test_23d() {
920         local file=$DIR/$tfile
921         local offset
922
923         echo CentaurHauls > $file
924         offset=$($MULTIOP $file oO_WRONLY:O_APPEND:w13Zp)
925         if ((offset != 26)); then
926                 error "wrong offset, expected 26, got '$offset'"
927         fi
928 }
929 run_test 23d "file offset is correct after appending writes"
930
931 # rename sanity
932 test_24a() {
933         echo '-- same directory rename'
934         test_mkdir $DIR/$tdir
935         touch $DIR/$tdir/$tfile.1
936         mv $DIR/$tdir/$tfile.1 $DIR/$tdir/$tfile.2
937         $CHECKSTAT -t file $DIR/$tdir/$tfile.2 || error "$tfile.2 not a file"
938 }
939 run_test 24a "rename file to non-existent target"
940
941 test_24b() {
942         test_mkdir $DIR/$tdir
943         touch $DIR/$tdir/$tfile.{1,2}
944         mv $DIR/$tdir/$tfile.1 $DIR/$tdir/$tfile.2
945         $CHECKSTAT -a $DIR/$tdir/$tfile.1 || error "$tfile.1 exists"
946         $CHECKSTAT -t file $DIR/$tdir/$tfile.2 || error "$tfile.2 not a file"
947 }
948 run_test 24b "rename file to existing target"
949
950 test_24c() {
951         test_mkdir $DIR/$tdir
952         test_mkdir $DIR/$tdir/d$testnum.1
953         mv $DIR/$tdir/d$testnum.1 $DIR/$tdir/d$testnum.2
954         $CHECKSTAT -a $DIR/$tdir/d$testnum.1 || error "d$testnum.1 exists"
955         $CHECKSTAT -t dir $DIR/$tdir/d$testnum.2 || error "d$testnum.2 not dir"
956 }
957 run_test 24c "rename directory to non-existent target"
958
959 test_24d() {
960         test_mkdir -c1 $DIR/$tdir
961         test_mkdir -c1 $DIR/$tdir/d$testnum.1
962         test_mkdir -c1 $DIR/$tdir/d$testnum.2
963         mrename $DIR/$tdir/d$testnum.1 $DIR/$tdir/d$testnum.2
964         $CHECKSTAT -a $DIR/$tdir/d$testnum.1 || error "d$testnum.1 exists"
965         $CHECKSTAT -t dir $DIR/$tdir/d$testnum.2 || error "d$testnum.2 not dir"
966 }
967 run_test 24d "rename directory to existing target"
968
969 test_24e() {
970         echo '-- cross directory renames --'
971         test_mkdir $DIR/R5a
972         test_mkdir $DIR/R5b
973         touch $DIR/R5a/f
974         mv $DIR/R5a/f $DIR/R5b/g
975         $CHECKSTAT -a $DIR/R5a/f || error "$DIR/R5a/f exists"
976         $CHECKSTAT -t file $DIR/R5b/g || error "$DIR/R5b/g not file type"
977 }
978 run_test 24e "touch .../R5a/f; rename .../R5a/f .../R5b/g ======"
979
980 test_24f() {
981         test_mkdir $DIR/R6a
982         test_mkdir $DIR/R6b
983         touch $DIR/R6a/f $DIR/R6b/g
984         mv $DIR/R6a/f $DIR/R6b/g
985         $CHECKSTAT -a $DIR/R6a/f || error "$DIR/R6a/f exists"
986         $CHECKSTAT -t file $DIR/R6b/g || error "$DIR/R6b/g not file type"
987 }
988 run_test 24f "touch .../R6a/f R6b/g; mv .../R6a/f .../R6b/g ===="
989
990 test_24g() {
991         test_mkdir $DIR/R7a
992         test_mkdir $DIR/R7b
993         test_mkdir $DIR/R7a/d
994         mv $DIR/R7a/d $DIR/R7b/e
995         $CHECKSTAT -a $DIR/R7a/d || error "$DIR/R7a/d exists"
996         $CHECKSTAT -t dir $DIR/R7b/e || error "$DIR/R7b/e not dir type"
997 }
998 run_test 24g "mkdir .../R7{a,b}/d; mv .../R7a/d .../R7b/e ======"
999
1000 test_24h() {
1001         test_mkdir -c1 $DIR/R8a
1002         test_mkdir -c1 $DIR/R8b
1003         test_mkdir -c1 $DIR/R8a/d
1004         test_mkdir -c1 $DIR/R8b/e
1005         mrename $DIR/R8a/d $DIR/R8b/e
1006         $CHECKSTAT -a $DIR/R8a/d || error "$DIR/R8a/d exists"
1007         $CHECKSTAT -t dir $DIR/R8b/e || error "$DIR/R8b/e not dir type"
1008 }
1009 run_test 24h "mkdir .../R8{a,b}/{d,e}; rename .../R8a/d .../R8b/e"
1010
1011 test_24i() {
1012         echo "-- rename error cases"
1013         test_mkdir $DIR/R9
1014         test_mkdir $DIR/R9/a
1015         touch $DIR/R9/f
1016         mrename $DIR/R9/f $DIR/R9/a
1017         $CHECKSTAT -t file $DIR/R9/f || error "$DIR/R9/f not file type"
1018         $CHECKSTAT -t dir  $DIR/R9/a || error "$DIR/R9/a not dir type"
1019         $CHECKSTAT -a $DIR/R9/a/f || error "$DIR/R9/a/f exists"
1020 }
1021 run_test 24i "rename file to dir error: touch f ; mkdir a ; rename f a"
1022
1023 test_24j() {
1024         test_mkdir $DIR/R10
1025         mrename $DIR/R10/f $DIR/R10/g
1026         $CHECKSTAT -t dir $DIR/R10 || error "$DIR/R10 not dir type"
1027         $CHECKSTAT -a $DIR/R10/f || error "$DIR/R10/f exists"
1028         $CHECKSTAT -a $DIR/R10/g || error "$DIR/R10/g exists"
1029 }
1030 run_test 24j "source does not exist ============================"
1031
1032 test_24k() {
1033         test_mkdir $DIR/R11a
1034         test_mkdir $DIR/R11a/d
1035         touch $DIR/R11a/f
1036         mv $DIR/R11a/f $DIR/R11a/d
1037         $CHECKSTAT -a $DIR/R11a/f || error "$DIR/R11a/f exists"
1038         $CHECKSTAT -t file $DIR/R11a/d/f || error "$DIR/R11a/d/f not file type"
1039 }
1040 run_test 24k "touch .../R11a/f; mv .../R11a/f .../R11a/d ======="
1041
1042 # bug 2429 - rename foo foo foo creates invalid file
1043 test_24l() {
1044         f="$DIR/f24l"
1045         $MULTIOP $f OcNs || error "rename of ${f} to itself failed"
1046 }
1047 run_test 24l "Renaming a file to itself ========================"
1048
1049 test_24m() {
1050         f="$DIR/f24m"
1051         $MULTIOP $f OcLN ${f}2 ${f}2 || error "link ${f}2 ${f}2 failed"
1052         # on ext3 this does not remove either the source or target files
1053         # though the "expected" operation would be to remove the source
1054         $CHECKSTAT -t file ${f} || error "${f} missing"
1055         $CHECKSTAT -t file ${f}2 || error "${f}2 missing"
1056 }
1057 run_test 24m "Renaming a file to a hard link to itself ========="
1058
1059 test_24n() {
1060     f="$DIR/f24n"
1061     # this stats the old file after it was renamed, so it should fail
1062     touch ${f}
1063     $CHECKSTAT ${f} || error "${f} missing"
1064     mv ${f} ${f}.rename
1065     $CHECKSTAT ${f}.rename || error "${f}.rename missing"
1066     $CHECKSTAT -a ${f} || error "${f} exists"
1067 }
1068 run_test 24n "Statting the old file after renaming (Posix rename 2)"
1069
1070 test_24o() {
1071         test_mkdir $DIR/$tdir
1072         rename_many -s random -v -n 10 $DIR/$tdir
1073 }
1074 run_test 24o "rename of files during htree split"
1075
1076 test_24p() {
1077         test_mkdir $DIR/R12a
1078         test_mkdir $DIR/R12b
1079         DIRINO=`ls -lid $DIR/R12a | awk '{ print $1 }'`
1080         mrename $DIR/R12a $DIR/R12b
1081         $CHECKSTAT -a $DIR/R12a || error "$DIR/R12a exists"
1082         $CHECKSTAT -t dir $DIR/R12b || error "$DIR/R12b not dir type"
1083         DIRINO2=`ls -lid $DIR/R12b | awk '{ print $1 }'`
1084         [ "$DIRINO" = "$DIRINO2" ] || error "R12a $DIRINO != R12b $DIRINO2"
1085 }
1086 run_test 24p "mkdir .../R12{a,b}; rename .../R12a .../R12b"
1087
1088 cleanup_multiop_pause() {
1089         trap 0
1090         kill -USR1 $MULTIPID
1091 }
1092
1093 test_24q() {
1094         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1095
1096         test_mkdir $DIR/R13a
1097         test_mkdir $DIR/R13b
1098         local DIRINO=$(ls -lid $DIR/R13a | awk '{ print $1 }')
1099         multiop_bg_pause $DIR/R13b D_c || error "multiop failed to start"
1100         MULTIPID=$!
1101
1102         trap cleanup_multiop_pause EXIT
1103         mrename $DIR/R13a $DIR/R13b
1104         $CHECKSTAT -a $DIR/R13a || error "R13a still exists"
1105         $CHECKSTAT -t dir $DIR/R13b || error "R13b does not exist"
1106         local DIRINO2=$(ls -lid $DIR/R13b | awk '{ print $1 }')
1107         [ "$DIRINO" = "$DIRINO2" ] || error "R13a $DIRINO != R13b $DIRINO2"
1108         cleanup_multiop_pause
1109         wait $MULTIPID || error "multiop close failed"
1110 }
1111 run_test 24q "mkdir .../R13{a,b}; open R13b rename R13a R13b ==="
1112
1113 test_24r() { #bug 3789
1114         test_mkdir $DIR/R14a
1115         test_mkdir $DIR/R14a/b
1116         mrename $DIR/R14a $DIR/R14a/b && error "rename to subdir worked!"
1117         $CHECKSTAT -t dir $DIR/R14a || error "$DIR/R14a missing"
1118         $CHECKSTAT -t dir $DIR/R14a/b || error "$DIR/R14a/b missing"
1119 }
1120 run_test 24r "mkdir .../R14a/b; rename .../R14a .../R14a/b ====="
1121
1122 test_24s() {
1123         test_mkdir $DIR/R15a
1124         test_mkdir $DIR/R15a/b
1125         test_mkdir $DIR/R15a/b/c
1126         mrename $DIR/R15a $DIR/R15a/b/c && error "rename to sub-subdir worked!"
1127         $CHECKSTAT -t dir $DIR/R15a || error "$DIR/R15a missing"
1128         $CHECKSTAT -t dir $DIR/R15a/b/c || error "$DIR/R15a/b/c missing"
1129 }
1130 run_test 24s "mkdir .../R15a/b/c; rename .../R15a .../R15a/b/c ="
1131 test_24t() {
1132         test_mkdir $DIR/R16a
1133         test_mkdir $DIR/R16a/b
1134         test_mkdir $DIR/R16a/b/c
1135         mrename $DIR/R16a/b/c $DIR/R16a && error "rename to sub-subdir worked!"
1136         $CHECKSTAT -t dir $DIR/R16a || error "$DIR/R16a missing"
1137         $CHECKSTAT -t dir $DIR/R16a/b/c || error "$DIR/R16a/b/c missing"
1138 }
1139 run_test 24t "mkdir .../R16a/b/c; rename .../R16a/b/c .../R16a ="
1140
1141 test_24u() { # bug12192
1142         $MULTIOP $DIR/$tfile C2w$((2048 * 1024))c || error "multiop failed"
1143         $CHECKSTAT -s $((2048 * 1024)) $DIR/$tfile || error "wrong file size"
1144 }
1145 run_test 24u "create stripe file"
1146
1147 simple_cleanup_common() {
1148         local rc=0
1149         trap 0
1150         [ -z "$DIR" ] || [ -z "$tdir" ] && return 0
1151
1152         local start=$SECONDS
1153         rm -rf $DIR/$tdir
1154         rc=$?
1155         wait_delete_completed
1156         echo "cleanup time $((SECONDS - start))"
1157         return $rc
1158 }
1159
1160 max_pages_per_rpc() {
1161         local mdtname="$(printf "MDT%04x" ${1:-0})"
1162         $LCTL get_param -n mdc.*$mdtname*.max_pages_per_rpc
1163 }
1164
1165 test_24v() {
1166         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1167
1168         local nrfiles=${COUNT:-100000}
1169         local fname="$DIR/$tdir/$tfile"
1170
1171         # Performance issue on ZFS see LU-4072 (c.f. LU-2887)
1172         [ "$mds1_FSTYPE" = "zfs" ] && nrfiles=${COUNT:-10000}
1173
1174         test_mkdir "$(dirname $fname)"
1175         # assume MDT0000 has the fewest inodes
1176         local stripes=$($LFS getdirstripe -c $(dirname $fname))
1177         local free_inodes=$(($(mdt_free_inodes 0) * stripes))
1178         [[ $free_inodes -lt $nrfiles ]] && nrfiles=$free_inodes
1179
1180         trap simple_cleanup_common EXIT
1181
1182         createmany -m "$fname" $nrfiles
1183
1184         cancel_lru_locks mdc
1185         lctl set_param mdc.*.stats clear
1186
1187         # was previously test_24D: LU-6101
1188         # readdir() returns correct number of entries after cursor reload
1189         local num_ls=$(ls $DIR/$tdir | wc -l)
1190         local num_uniq=$(ls $DIR/$tdir | sort -u | wc -l)
1191         local num_all=$(ls -a $DIR/$tdir | wc -l)
1192         if [ $num_ls -ne $nrfiles ] || [ $num_uniq -ne $nrfiles ] ||
1193                 [ $num_all -ne $((nrfiles + 2)) ]; then
1194                         error "Expected $nrfiles files, got $num_ls " \
1195                                 "($num_uniq unique $num_all .&..)"
1196         fi
1197         # LU-5 large readdir
1198         # dirent_size = 32 bytes for sizeof(struct lu_dirent) +
1199         #               N bytes for name (len($nrfiles) rounded to 8 bytes) +
1200         #               8 bytes for luda_type (4 bytes rounded to 8 bytes)
1201         # take into account of overhead in lu_dirpage header and end mark in
1202         # each page, plus one in rpc_num calculation.
1203         local dirent_size=$((32 + (${#tfile} | 7) + 1 + 8))
1204         local page_entries=$(((PAGE_SIZE - 24) / dirent_size))
1205         local mdt_idx=$($LFS getdirstripe -i $(dirname $fname))
1206         local rpc_pages=$(max_pages_per_rpc $mdt_idx)
1207         local rpc_max=$((nrfiles / (page_entries * rpc_pages) + stripes))
1208         local mds_readpage=$(calc_stats mdc.*.stats mds_readpage)
1209         echo "readpages: $mds_readpage rpc_max: $rpc_max"
1210         (( $mds_readpage < $rpc_max - 2 || $mds_readpage > $rpc_max + 1)) &&
1211                 error "large readdir doesn't take effect: " \
1212                       "$mds_readpage should be about $rpc_max"
1213
1214         simple_cleanup_common
1215 }
1216 run_test 24v "list large directory (test hash collision, b=17560)"
1217
1218 test_24w() { # bug21506
1219         SZ1=234852
1220         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=4096 || return 1
1221         dd if=/dev/zero bs=$SZ1 count=1 >> $DIR/$tfile || return 2
1222         dd if=$DIR/$tfile of=$DIR/${tfile}_left bs=1M skip=4097 || return 3
1223         SZ2=`ls -l $DIR/${tfile}_left | awk '{print $5}'`
1224         [[ "$SZ1" -eq "$SZ2" ]] ||
1225                 error "Error reading at the end of the file $tfile"
1226 }
1227 run_test 24w "Reading a file larger than 4Gb"
1228
1229 test_24x() {
1230         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
1231         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1232         [[ $MDS1_VERSION -lt $(version_code 2.7.56) ]] &&
1233                 skip "Need MDS version at least 2.7.56"
1234
1235         local MDTIDX=1
1236         local remote_dir=$DIR/$tdir/remote_dir
1237
1238         test_mkdir $DIR/$tdir
1239         $LFS mkdir -i $MDTIDX $remote_dir ||
1240                 error "create remote directory failed"
1241
1242         test_mkdir $DIR/$tdir/src_dir
1243         touch $DIR/$tdir/src_file
1244         test_mkdir $remote_dir/tgt_dir
1245         touch $remote_dir/tgt_file
1246
1247         mrename $DIR/$tdir/src_dir $remote_dir/tgt_dir ||
1248                 error "rename dir cross MDT failed!"
1249
1250         mrename $DIR/$tdir/src_file $remote_dir/tgt_file ||
1251                 error "rename file cross MDT failed!"
1252
1253         touch $DIR/$tdir/ln_file
1254         ln $DIR/$tdir/ln_file $remote_dir/ln_name ||
1255                 error "ln file cross MDT failed"
1256
1257         rm -rf $DIR/$tdir || error "Can not delete directories"
1258 }
1259 run_test 24x "cross MDT rename/link"
1260
1261 test_24y() {
1262         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
1263         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1264
1265         local remote_dir=$DIR/$tdir/remote_dir
1266         local mdtidx=1
1267
1268         test_mkdir $DIR/$tdir
1269         $LFS mkdir -i $mdtidx $remote_dir ||
1270                 error "create remote directory failed"
1271
1272         test_mkdir $remote_dir/src_dir
1273         touch $remote_dir/src_file
1274         test_mkdir $remote_dir/tgt_dir
1275         touch $remote_dir/tgt_file
1276
1277         mrename $remote_dir/src_dir $remote_dir/tgt_dir ||
1278                 error "rename subdir in the same remote dir failed!"
1279
1280         mrename $remote_dir/src_file $remote_dir/tgt_file ||
1281                 error "rename files in the same remote dir failed!"
1282
1283         ln $remote_dir/tgt_file $remote_dir/tgt_file1 ||
1284                 error "link files in the same remote dir failed!"
1285
1286         rm -rf $DIR/$tdir || error "Can not delete directories"
1287 }
1288 run_test 24y "rename/link on the same dir should succeed"
1289
1290 test_24z() {
1291         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
1292         [[ $MDS1_VERSION -lt $(version_code 2.12.51) ]] &&
1293                 skip "Need MDS version at least 2.12.51"
1294
1295         local index
1296
1297         for index in 0 1; do
1298                 $LFS mkdir -i $index $DIR/$tdir.$index || error "mkdir failed"
1299                 touch $DIR/$tdir.0/$tfile.$index || error "touch failed"
1300         done
1301
1302         mv $DIR/$tdir.0/$tfile.0 $DIR/$tdir.1 || error "mv $tfile.0 failed"
1303
1304         index=$($LFS getstripe -m $DIR/$tdir.1/$tfile.0)
1305         [ $index -eq 0 ] || error "$tfile.0 is on MDT$index"
1306
1307         local mdts=$(comma_list $(mdts_nodes))
1308
1309         do_nodes $mdts $LCTL set_param mdt.*.enable_remote_rename=0
1310         stack_trap "do_nodes $mdts $LCTL \
1311                 set_param mdt.*.enable_remote_rename=1" EXIT
1312
1313         mv $DIR/$tdir.0/$tfile.1 $DIR/$tdir.1 || error "mv $tfile.1 failed"
1314
1315         index=$($LFS getstripe -m $DIR/$tdir.1/$tfile.1)
1316         [ $index -eq 1 ] || error "$tfile.1 is on MDT$index"
1317 }
1318 run_test 24z "cross-MDT rename is done as cp"
1319
1320 test_24A() { # LU-3182
1321         local NFILES=5000
1322
1323         rm -rf $DIR/$tdir
1324         test_mkdir $DIR/$tdir
1325         trap simple_cleanup_common EXIT
1326         createmany -m $DIR/$tdir/$tfile $NFILES
1327         local t=$(ls $DIR/$tdir | wc -l)
1328         local u=$(ls $DIR/$tdir | sort -u | wc -l)
1329         local v=$(ls -ai $DIR/$tdir | sort -u | wc -l)
1330         if [ $t -ne $NFILES ] || [ $u -ne $NFILES ] ||
1331            [ $v -ne $((NFILES + 2)) ] ; then
1332                 error "Expected $NFILES files, got $t ($u unique $v .&..)"
1333         fi
1334
1335         simple_cleanup_common || error "Can not delete directories"
1336 }
1337 run_test 24A "readdir() returns correct number of entries."
1338
1339 test_24B() { # LU-4805
1340         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
1341
1342         local count
1343
1344         test_mkdir $DIR/$tdir
1345         $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir ||
1346                 error "create striped dir failed"
1347
1348         count=$(ls -ai $DIR/$tdir/striped_dir | wc -l)
1349         [ $count -eq 2 ] || error "Expected 2, got $count"
1350
1351         touch $DIR/$tdir/striped_dir/a
1352
1353         count=$(ls -ai $DIR/$tdir/striped_dir | wc -l)
1354         [ $count -eq 3 ] || error "Expected 3, got $count"
1355
1356         touch $DIR/$tdir/striped_dir/.f
1357
1358         count=$(ls -ai $DIR/$tdir/striped_dir | wc -l)
1359         [ $count -eq 4 ] || error "Expected 4, got $count"
1360
1361         rm -rf $DIR/$tdir || error "Can not delete directories"
1362 }
1363 run_test 24B "readdir for striped dir return correct number of entries"
1364
1365 test_24C() {
1366         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
1367
1368         mkdir $DIR/$tdir
1369         mkdir $DIR/$tdir/d0
1370         mkdir $DIR/$tdir/d1
1371
1372         $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/d0/striped_dir ||
1373                 error "create striped dir failed"
1374
1375         cd $DIR/$tdir/d0/striped_dir
1376
1377         local d0_ino=$(ls -i -l -a $DIR/$tdir | grep "d0" | awk '{print $1}')
1378         local d1_ino=$(ls -i -l -a $DIR/$tdir | grep "d1" | awk '{print $1}')
1379         local parent_ino=$(ls -i -l -a | grep "\.\." | awk '{print $1}')
1380
1381         [ "$d0_ino" = "$parent_ino" ] ||
1382                 error ".. wrong, expect $d0_ino, get $parent_ino"
1383
1384         mv $DIR/$tdir/d0/striped_dir $DIR/$tdir/d1/ ||
1385                 error "mv striped dir failed"
1386
1387         parent_ino=$(ls -i -l -a | grep "\.\." | awk '{print $1}')
1388
1389         [ "$d1_ino" = "$parent_ino" ] ||
1390                 error ".. wrong after mv, expect $d1_ino, get $parent_ino"
1391 }
1392 run_test 24C "check .. in striped dir"
1393
1394 test_24E() {
1395         [[ $MDSCOUNT -lt 4 ]] && skip_env "needs >= 4 MDTs"
1396         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1397
1398         mkdir -p $DIR/$tdir
1399         mkdir $DIR/$tdir/src_dir
1400         $LFS mkdir -i 1 $DIR/$tdir/src_dir/src_child ||
1401                 error "create remote source failed"
1402
1403         touch $DIR/$tdir/src_dir/src_child/a
1404
1405         $LFS mkdir -i 2 $DIR/$tdir/tgt_dir ||
1406                 error "create remote target dir failed"
1407
1408         $LFS mkdir -i 3 $DIR/$tdir/tgt_dir/tgt_child ||
1409                 error "create remote target child failed"
1410
1411         mrename $DIR/$tdir/src_dir/src_child $DIR/$tdir/tgt_dir/tgt_child ||
1412                 error "rename dir cross MDT failed!"
1413
1414         find $DIR/$tdir
1415
1416         $CHECKSTAT -t dir $DIR/$tdir/src_dir/src_child &&
1417                 error "src_child still exists after rename"
1418
1419         $CHECKSTAT -t file $DIR/$tdir/tgt_dir/tgt_child/a ||
1420                 error "missing file(a) after rename"
1421
1422         rm -rf $DIR/$tdir || error "Can not delete directories"
1423 }
1424 run_test 24E "cross MDT rename/link"
1425
1426 test_24F () {
1427         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return 0
1428
1429         local repeats=1000
1430         [ "$SLOW" = "no" ] && repeats=100
1431
1432         mkdir -p $DIR/$tdir
1433
1434         echo "$repeats repeats"
1435         for ((i = 0; i < repeats; i++)); do
1436                 $LFS mkdir -i0 -c2 $DIR/$tdir/test || error "mkdir fails"
1437                 touch $DIR/$tdir/test/a || error "touch fails"
1438                 mkdir $DIR/$tdir/test/b || error "mkdir fails"
1439                 rm -rf $DIR/$tdir/test || error "rmdir fails"
1440         done
1441
1442         true
1443 }
1444 run_test 24F "hash order vs readdir (LU-11330)"
1445
1446 test_25a() {
1447         echo '== symlink sanity ============================================='
1448
1449         test_mkdir $DIR/d25
1450         ln -s d25 $DIR/s25
1451         touch $DIR/s25/foo ||
1452                 error "File creation in symlinked directory failed"
1453 }
1454 run_test 25a "create file in symlinked directory ==============="
1455
1456 test_25b() {
1457         [ ! -d $DIR/d25 ] && test_25a
1458         $CHECKSTAT -t file $DIR/s25/foo || error "$DIR/s25/foo not file type"
1459 }
1460 run_test 25b "lookup file in symlinked directory ==============="
1461
1462 test_26a() {
1463         test_mkdir $DIR/d26
1464         test_mkdir $DIR/d26/d26-2
1465         ln -s d26/d26-2 $DIR/s26
1466         touch $DIR/s26/foo || error "File creation failed"
1467 }
1468 run_test 26a "multiple component symlink ======================="
1469
1470 test_26b() {
1471         test_mkdir -p $DIR/$tdir/d26-2
1472         ln -s $tdir/d26-2/foo $DIR/s26-2
1473         touch $DIR/s26-2 || error "File creation failed"
1474 }
1475 run_test 26b "multiple component symlink at end of lookup ======"
1476
1477 test_26c() {
1478         test_mkdir $DIR/d26.2
1479         touch $DIR/d26.2/foo
1480         ln -s d26.2 $DIR/s26.2-1
1481         ln -s s26.2-1 $DIR/s26.2-2
1482         ln -s s26.2-2 $DIR/s26.2-3
1483         chmod 0666 $DIR/s26.2-3/foo
1484 }
1485 run_test 26c "chain of symlinks"
1486
1487 # recursive symlinks (bug 439)
1488 test_26d() {
1489         ln -s d26-3/foo $DIR/d26-3
1490 }
1491 run_test 26d "create multiple component recursive symlink"
1492
1493 test_26e() {
1494         [ ! -h $DIR/d26-3 ] && test_26d
1495         rm $DIR/d26-3
1496 }
1497 run_test 26e "unlink multiple component recursive symlink"
1498
1499 # recursive symlinks (bug 7022)
1500 test_26f() {
1501         test_mkdir $DIR/$tdir
1502         test_mkdir $DIR/$tdir/$tfile
1503         cd $DIR/$tdir/$tfile           || error "cd $DIR/$tdir/$tfile failed"
1504         test_mkdir -p lndir/bar1
1505         test_mkdir $DIR/$tdir/$tfile/$tfile
1506         cd $tfile                || error "cd $tfile failed"
1507         ln -s .. dotdot          || error "ln dotdot failed"
1508         ln -s dotdot/lndir lndir || error "ln lndir failed"
1509         cd $DIR/$tdir                 || error "cd $DIR/$tdir failed"
1510         output=`ls $tfile/$tfile/lndir/bar1`
1511         [ "$output" = bar1 ] && error "unexpected output"
1512         rm -r $tfile             || error "rm $tfile failed"
1513         $CHECKSTAT -a $DIR/$tfile || error "$tfile not gone"
1514 }
1515 run_test 26f "rm -r of a directory which has recursive symlink"
1516
1517 test_27a() {
1518         test_mkdir $DIR/$tdir
1519         $LFS getstripe $DIR/$tdir
1520         $LFS setstripe -c 1 $DIR/$tdir/$tfile || error "setstripe failed"
1521         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "checkstat failed"
1522         cp /etc/hosts $DIR/$tdir/$tfile || error "Can't copy to one stripe file"
1523 }
1524 run_test 27a "one stripe file"
1525
1526 test_27b() {
1527         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1528
1529         test_mkdir $DIR/$tdir
1530         $LFS setstripe -c 2 $DIR/$tdir/$tfile || error "setstripe failed"
1531         $LFS getstripe -c $DIR/$tdir/$tfile
1532         [ $($LFS getstripe -c $DIR/$tdir/$tfile) -eq 2 ] ||
1533                 error "two-stripe file doesn't have two stripes"
1534
1535         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
1536 }
1537 run_test 27b "create and write to two stripe file"
1538
1539 # 27c family tests specific striping, setstripe -o
1540 test_27ca() {
1541         [[ $OSTCOUNT -lt 2 ]] && skip_env "skipping 2-stripe test"
1542         test_mkdir -p $DIR/$tdir
1543         local osts="1"
1544
1545         $LFS setstripe -o $osts $DIR/$tdir/$tfile  || error "setstripe failed"
1546         $LFS getstripe -i $DIR/$tdir/$tfile
1547         [ $($LFS getstripe -i $DIR/$tdir/$tfile ) -eq $osts ] ||
1548                 error "stripe not on specified OST"
1549
1550         dd if=/dev/zero of=$DIR/$tdir/$tfile  bs=1M count=4 || error "dd failed"
1551 }
1552 run_test 27ca "one stripe on specified OST"
1553
1554 test_27cb() {
1555         [[ $OSTCOUNT -lt 2 ]] && skip_env "skipping 2-stripe test"
1556         test_mkdir -p $DIR/$tdir
1557         local osts="1,0"
1558         $LFS setstripe -o $osts $DIR/$tdir/$tfile || error "setstripe failed"
1559         local getstripe=$($LFS getstripe $DIR/$tdir/$tfile)
1560         echo "$getstripe"
1561
1562         # Strip getstripe output to a space separated list of OSTs
1563         local getstripe_osts=$(echo "$getstripe" | sed -e '1,/obdidx/d' |\
1564                 awk '{print $1}' | tr '\n' '\ ' | sed -e 's/[[:space:]]*$//')
1565         [ "$getstripe_osts" = "${osts//,/ }" ] ||
1566                 error "stripes not on specified OSTs"
1567
1568         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 || error "dd failed"
1569 }
1570 run_test 27cb "two stripes on specified OSTs"
1571
1572 test_27cc() {
1573         [[ $OSTCOUNT -lt 2 ]] && skip_env "skipping 2-stripe test"
1574         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
1575                 skip "server does not support overstriping"
1576
1577         test_mkdir -p $DIR/$tdir
1578         local osts="0,0"
1579         $LFS setstripe -o $osts $DIR/$tdir/$tfile || error "setstripe failed"
1580         local getstripe=$($LFS getstripe $DIR/$tdir/$tfile)
1581         echo "$getstripe"
1582
1583         # Strip getstripe output to a space separated list of OSTs
1584         local getstripe_osts=$(echo "$getstripe" | sed -e '1,/obdidx/d' |\
1585                 awk '{print $1}' | tr '\n' '\ ' | sed -e 's/[[:space:]]*$//')
1586         [ "$getstripe_osts" = "${osts//,/ }" ] ||
1587                 error "stripes not on specified OSTs"
1588
1589         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 || error "dd failed"
1590 }
1591 run_test 27cc "two stripes on the same OST"
1592
1593 test_27cd() {
1594         [[ $OSTCOUNT -lt 2 ]] && skip_env "skipping 2-stripe test"
1595         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
1596                 skip "server does not support overstriping"
1597         test_mkdir -p $DIR/$tdir
1598         local osts="0,1,1,0"
1599         $LFS setstripe -o $osts $DIR/$tdir/$tfile || error "setstripe failed"
1600         local getstripe=$($LFS getstripe $DIR/$tdir/$tfile)
1601         echo "$getstripe"
1602
1603         # Strip getstripe output to a space separated list of OSTs
1604         local getstripe_osts=$(echo "$getstripe" | sed -e '1,/obdidx/d' |\
1605                 awk '{print $1}' | tr '\n' '\ ' | sed -e 's/[[:space:]]*$//')
1606         [ "$getstripe_osts" = "${osts//,/ }" ] ||
1607                 error "stripes not on specified OSTs"
1608
1609         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 || error "dd failed"
1610 }
1611 run_test 27cd "four stripes on two OSTs"
1612
1613 test_27ce() {
1614         [[ $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
1615                 skip_env "too many osts, skipping"
1616         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
1617                 skip "server does not support overstriping"
1618         # We do one more stripe than we have OSTs
1619         [ $OSTCOUNT -ge 159 ] || large_xattr_enabled ||
1620                 skip_env "ea_inode feature disabled"
1621
1622         test_mkdir -p $DIR/$tdir
1623         local osts=""
1624         for i in $(seq 0 $OSTCOUNT);
1625         do
1626                 osts=$osts"0"
1627                 if [ $i -ne $OSTCOUNT ]; then
1628                         osts=$osts","
1629                 fi
1630         done
1631         $LFS setstripe -o $osts $DIR/$tdir/$tfile || error "setstripe failed"
1632         local getstripe=$($LFS getstripe $DIR/$tdir/$tfile)
1633         echo "$getstripe"
1634
1635         # Strip getstripe output to a space separated list of OSTs
1636         local getstripe_osts=$(echo "$getstripe" | sed -e '1,/obdidx/d' |\
1637                 awk '{print $1}' | tr '\n' '\ ' | sed -e 's/[[:space:]]*$//')
1638         [ "$getstripe_osts" = "${osts//,/ }" ] ||
1639                 error "stripes not on specified OSTs"
1640
1641         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 || error "dd failed"
1642 }
1643 run_test 27ce "more stripes than OSTs with -o"
1644
1645 test_27cf() {
1646         local osp_proc="osp.$FSNAME-OST0000-osc-MDT000*.active"
1647         local pid=0
1648
1649         test_mkdir -p $DIR/$tdir || error "failed to mkdir $DIR/$tdir"
1650         do_facet $SINGLEMDS "$LCTL set_param -n $osp_proc=0"
1651         stack_trap "do_facet $SINGLEMDS $LCTL set_param -n $osp_proc=1" EXIT
1652         wait_update_facet $SINGLEMDS "$LCTL get_param -n $osp_proc | grep 1" ||
1653                 error "failed to set $osp_proc=0"
1654
1655         $LFS setstripe -o 0 $DIR/$tdir/$tfile &
1656         pid=$!
1657         sleep 1
1658         do_facet $SINGLEMDS "$LCTL set_param -n $osp_proc=1"
1659         wait_update_facet $SINGLEMDS "$LCTL get_param -n $osp_proc | grep 0" ||
1660                 error "failed to set $osp_proc=1"
1661         wait $pid
1662         [[ $pid -ne 0 ]] ||
1663                 error "should return error due to $osp_proc=0"
1664 }
1665 run_test 27cf "'setstripe -o' on inactive OSTs should return error"
1666
1667 test_27d() {
1668         test_mkdir $DIR/$tdir
1669         $LFS setstripe -c 0 -i -1 -S 0 $DIR/$tdir/$tfile ||
1670                 error "setstripe failed"
1671         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "checkstat failed"
1672         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
1673 }
1674 run_test 27d "create file with default settings"
1675
1676 test_27e() {
1677         # LU-5839 adds check for existed layout before setting it
1678         [[ $MDS1_VERSION -lt $(version_code 2.7.56) ]] &&
1679                 skip "Need MDS version at least 2.7.56"
1680
1681         test_mkdir $DIR/$tdir
1682         $LFS setstripe -c 2 $DIR/$tdir/$tfile || error "setstripe failed"
1683         $LFS setstripe -c 2 $DIR/$tdir/$tfile && error "setstripe worked twice"
1684         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "checkstat failed"
1685 }
1686 run_test 27e "setstripe existing file (should return error)"
1687
1688 test_27f() {
1689         test_mkdir $DIR/$tdir
1690         $LFS setstripe -S 100 -i 0 -c 1 $DIR/$tdir/$tfile &&
1691                 error "$LFS setstripe $DIR/$tdir/$tfile failed"
1692         $CHECKSTAT -t file $DIR/$tdir/$tfile &&
1693                 error "$CHECKSTAT -t file $DIR/$tdir/$tfile should fail"
1694         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
1695         $LFS getstripe $DIR/$tdir/$tfile || error "$LFS getstripe failed"
1696 }
1697 run_test 27f "setstripe with bad stripe size (should return error)"
1698
1699 test_27g() {
1700         test_mkdir $DIR/$tdir
1701         $MCREATE $DIR/$tdir/$tfile || error "mcreate failed"
1702         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "no stripe info" ||
1703                 error "$DIR/$tdir/$tfile has object"
1704 }
1705 run_test 27g "$LFS getstripe with no objects"
1706
1707 test_27ga() {
1708         test_mkdir $DIR/$tdir
1709         touch $DIR/$tdir/$tfile || error "touch failed"
1710         ln -s bogus $DIR/$tdir/$tfile.2 || error "ln failed"
1711         $LFS getstripe -m $DIR/$tdir/$tfile $DIR/$tdir/$tfile.2
1712         local rc=$?
1713         (( rc == 2 )) || error "getstripe did not return ENOENT"
1714 }
1715 run_test 27ga "$LFS getstripe with missing file (should return error)"
1716
1717 test_27i() {
1718         test_mkdir $DIR/$tdir
1719         touch $DIR/$tdir/$tfile || error "touch failed"
1720         [[ $($LFS getstripe -c $DIR/$tdir/$tfile) -gt 0 ]] ||
1721                 error "missing objects"
1722 }
1723 run_test 27i "$LFS getstripe with some objects"
1724
1725 test_27j() {
1726         test_mkdir $DIR/$tdir
1727         $LFS setstripe -i $OSTCOUNT $DIR/$tdir/$tfile &&
1728                 error "setstripe failed" || true
1729 }
1730 run_test 27j "setstripe with bad stripe offset (should return error)"
1731
1732 test_27k() { # bug 2844
1733         test_mkdir $DIR/$tdir
1734         local file=$DIR/$tdir/$tfile
1735         local ll_max_blksize=$((4 * 1024 * 1024))
1736         $LFS setstripe -S 67108864 $file || error "setstripe failed"
1737         local blksize=$(stat $file | awk '/IO Block:/ { print $7 }')
1738         [ $blksize -le $ll_max_blksize ] || error "1:$blksize > $ll_max_blksize"
1739         dd if=/dev/zero of=$file bs=4k count=1
1740         blksize=$(stat $file | awk '/IO Block:/ { print $7 }')
1741         [ $blksize -le $ll_max_blksize ] || error "2:$blksize > $ll_max_blksize"
1742 }
1743 run_test 27k "limit i_blksize for broken user apps"
1744
1745 test_27l() {
1746         mcreate $DIR/$tfile || error "creating file"
1747         $RUNAS $LFS setstripe -c 1 $DIR/$tfile &&
1748                 error "setstripe should have failed" || true
1749 }
1750 run_test 27l "check setstripe permissions (should return error)"
1751
1752 test_27m() {
1753         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1754
1755         [ -n "$RCLIENTS" -o -n "$MOUNT_2" ] &&
1756                 skip_env "multiple clients -- skipping"
1757
1758         ORIGFREE=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
1759                    head -n1)
1760         if [[ $ORIGFREE -gt $MAXFREE ]]; then
1761                 skip "$ORIGFREE > $MAXFREE skipping out-of-space test on OST0"
1762         fi
1763         trap simple_cleanup_common EXIT
1764         test_mkdir $DIR/$tdir
1765         $LFS setstripe -i 0 -c 1 $DIR/$tdir/$tfile.1
1766         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=1024 count=$MAXFREE &&
1767                 error "dd should fill OST0"
1768         i=2
1769         while $LFS setstripe -i 0 -c 1 $DIR/$tdir/$tfile.$i; do
1770                 i=$((i + 1))
1771                 [ $i -gt 256 ] && break
1772         done
1773         i=$((i + 1))
1774         touch $DIR/$tdir/$tfile.$i
1775         [ $($LFS getstripe $DIR/$tdir/$tfile.$i | grep -A 10 obdidx |
1776             awk '{print $1}'| grep -w "0") ] &&
1777                 error "OST0 was full but new created file still use it"
1778         i=$((i + 1))
1779         touch $DIR/$tdir/$tfile.$i
1780         [ $($LFS getstripe $DIR/$tdir/$tfile.$i | grep -A 10 obdidx |
1781             awk '{print $1}'| grep -w "0") ] &&
1782                 error "OST0 was full but new created file still use it"
1783         simple_cleanup_common
1784 }
1785 run_test 27m "create file while OST0 was full"
1786
1787 # OSCs keep a NOSPC flag that will be reset after ~5s (qos_maxage)
1788 # if the OST isn't full anymore.
1789 reset_enospc() {
1790         local ostidx=${1:-""}
1791         local delay
1792         local ready
1793         local get_prealloc
1794
1795         local list=$(comma_list $(osts_nodes))
1796         [ "$ostidx" ] && list=$(facet_host ost$((ostidx + 1)))
1797
1798         do_nodes $list lctl set_param fail_loc=0
1799         wait_delete_completed   # initiate all OST_DESTROYs from MDS to OST
1800         delay=$(do_facet $SINGLEMDS lctl get_param -n lov.*.qos_maxage |
1801                 awk '{print $1 * 2;exit;}')
1802         get_prealloc="$LCTL get_param -n osc.*MDT*.prealloc_status |
1803                         grep -v \"^0$\""
1804         wait_update_facet $SINGLEMDS "$get_prealloc" "" $delay
1805 }
1806
1807 __exhaust_precreations() {
1808         local OSTIDX=$1
1809         local FAILLOC=$2
1810         local FAILIDX=${3:-$OSTIDX}
1811         local ofacet=ost$((OSTIDX + 1))
1812
1813         test_mkdir -p -c1 $DIR/$tdir
1814         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
1815         local mfacet=mds$((mdtidx + 1))
1816         echo OSTIDX=$OSTIDX MDTIDX=$mdtidx
1817
1818         local OST=$(ostname_from_index $OSTIDX)
1819
1820         # on the mdt's osc
1821         local mdtosc_proc1=$(get_mdtosc_proc_path $mfacet $OST)
1822         local last_id=$(do_facet $mfacet lctl get_param -n \
1823                         osp.$mdtosc_proc1.prealloc_last_id)
1824         local next_id=$(do_facet $mfacet lctl get_param -n \
1825                         osp.$mdtosc_proc1.prealloc_next_id)
1826
1827         local mdtosc_proc2=$(get_mdtosc_proc_path $mfacet)
1828         do_facet $mfacet lctl get_param osp.$mdtosc_proc2.prealloc*
1829
1830         test_mkdir -p $DIR/$tdir/${OST}
1831         $LFS setstripe -i $OSTIDX -c 1 $DIR/$tdir/${OST}
1832 #define OBD_FAIL_OST_ENOSPC              0x215
1833         do_facet $ofacet lctl set_param fail_val=$FAILIDX fail_loc=0x215
1834         echo "Creating to objid $last_id on ost $OST..."
1835         createmany -o $DIR/$tdir/${OST}/f $next_id $((last_id - next_id + 2))
1836         do_facet $mfacet lctl get_param osp.$mdtosc_proc2.prealloc*
1837         do_facet $ofacet lctl set_param fail_loc=$FAILLOC
1838 }
1839
1840 exhaust_precreations() {
1841         __exhaust_precreations $1 $2 $3
1842         sleep_maxage
1843 }
1844
1845 exhaust_all_precreations() {
1846         local i
1847         for (( i=0; i < OSTCOUNT; i++ )) ; do
1848                 __exhaust_precreations $i $1 -1
1849         done
1850         sleep_maxage
1851 }
1852
1853 test_27n() {
1854         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1855         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1856         remote_mds_nodsh && skip "remote MDS with nodsh"
1857         remote_ost_nodsh && skip "remote OST with nodsh"
1858
1859         reset_enospc
1860         rm -f $DIR/$tdir/$tfile
1861         exhaust_precreations 0 0x80000215
1862         $LFS setstripe -c -1 $DIR/$tdir || error "setstripe failed"
1863         touch $DIR/$tdir/$tfile || error "touch failed"
1864         $LFS getstripe $DIR/$tdir/$tfile
1865         reset_enospc
1866 }
1867 run_test 27n "create file with some full OSTs"
1868
1869 test_27o() {
1870         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1871         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1872         remote_mds_nodsh && skip "remote MDS with nodsh"
1873         remote_ost_nodsh && skip "remote OST with nodsh"
1874
1875         reset_enospc
1876         rm -f $DIR/$tdir/$tfile
1877         exhaust_all_precreations 0x215
1878
1879         touch $DIR/$tdir/$tfile && error "able to create $DIR/$tdir/$tfile"
1880
1881         reset_enospc
1882         rm -rf $DIR/$tdir/*
1883 }
1884 run_test 27o "create file with all full OSTs (should error)"
1885
1886 test_27p() {
1887         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1888         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1889         remote_mds_nodsh && skip "remote MDS with nodsh"
1890         remote_ost_nodsh && skip "remote OST with nodsh"
1891
1892         reset_enospc
1893         rm -f $DIR/$tdir/$tfile
1894         test_mkdir $DIR/$tdir
1895
1896         $MCREATE $DIR/$tdir/$tfile || error "mcreate failed"
1897         $TRUNCATE $DIR/$tdir/$tfile 80000000 || error "truncate failed"
1898         $CHECKSTAT -s 80000000 $DIR/$tdir/$tfile || error "checkstat failed"
1899
1900         exhaust_precreations 0 0x80000215
1901         echo foo >> $DIR/$tdir/$tfile || error "append failed"
1902         $CHECKSTAT -s 80000004 $DIR/$tdir/$tfile || error "checkstat failed"
1903         $LFS getstripe $DIR/$tdir/$tfile
1904
1905         reset_enospc
1906 }
1907 run_test 27p "append to a truncated file with some full OSTs"
1908
1909 test_27q() {
1910         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1911         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1912         remote_mds_nodsh && skip "remote MDS with nodsh"
1913         remote_ost_nodsh && skip "remote OST with nodsh"
1914
1915         reset_enospc
1916         rm -f $DIR/$tdir/$tfile
1917
1918         test_mkdir $DIR/$tdir
1919         $MCREATE $DIR/$tdir/$tfile || error "mcreate $DIR/$tdir/$tfile failed"
1920         $TRUNCATE $DIR/$tdir/$tfile 80000000 ||
1921                 error "truncate $DIR/$tdir/$tfile failed"
1922         $CHECKSTAT -s 80000000 $DIR/$tdir/$tfile || error "checkstat failed"
1923
1924         exhaust_all_precreations 0x215
1925
1926         echo foo >> $DIR/$tdir/$tfile && error "append succeeded"
1927         $CHECKSTAT -s 80000000 $DIR/$tdir/$tfile || error "checkstat 2 failed"
1928
1929         reset_enospc
1930 }
1931 run_test 27q "append to truncated file with all OSTs full (should error)"
1932
1933 test_27r() {
1934         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1935         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1936         remote_mds_nodsh && skip "remote MDS with nodsh"
1937         remote_ost_nodsh && skip "remote OST with nodsh"
1938
1939         reset_enospc
1940         rm -f $DIR/$tdir/$tfile
1941         exhaust_precreations 0 0x80000215
1942
1943         $LFS setstripe -i 0 -c 2 $DIR/$tdir/$tfile || error "setstripe failed"
1944
1945         reset_enospc
1946 }
1947 run_test 27r "stripe file with some full OSTs (shouldn't LBUG) ="
1948
1949 test_27s() { # bug 10725
1950         test_mkdir $DIR/$tdir
1951         local stripe_size=$((4096 * 1024 * 1024))       # 2^32
1952         local stripe_count=0
1953         [ $OSTCOUNT -eq 1 ] || stripe_count=2
1954         $LFS setstripe -S $stripe_size -c $stripe_count $DIR/$tdir &&
1955                 error "stripe width >= 2^32 succeeded" || true
1956
1957 }
1958 run_test 27s "lsm_xfersize overflow (should error) (bug 10725)"
1959
1960 test_27t() { # bug 10864
1961         WDIR=$(pwd)
1962         WLFS=$(which lfs)
1963         cd $DIR
1964         touch $tfile
1965         $WLFS getstripe $tfile
1966         cd $WDIR
1967 }
1968 run_test 27t "check that utils parse path correctly"
1969
1970 test_27u() { # bug 4900
1971         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1972         remote_mds_nodsh && skip "remote MDS with nodsh"
1973
1974         local index
1975         local list=$(comma_list $(mdts_nodes))
1976
1977 #define OBD_FAIL_MDS_OSC_PRECREATE      0x139
1978         do_nodes $list $LCTL set_param fail_loc=0x139
1979         test_mkdir -p $DIR/$tdir
1980         trap simple_cleanup_common EXIT
1981         createmany -o $DIR/$tdir/t- 1000
1982         do_nodes $list $LCTL set_param fail_loc=0
1983
1984         TLOG=$TMP/$tfile.getstripe
1985         $LFS getstripe $DIR/$tdir > $TLOG
1986         OBJS=$(awk -vobj=0 '($1 == 0) { obj += 1 } END { print obj; }' $TLOG)
1987         unlinkmany $DIR/$tdir/t- 1000
1988         trap 0
1989         [[ $OBJS -gt 0 ]] &&
1990                 error "$OBJS objects created on OST-0. See $TLOG" ||
1991                 rm -f $TLOG
1992 }
1993 run_test 27u "skip object creation on OSC w/o objects"
1994
1995 test_27v() { # bug 4900
1996         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1997         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1998         remote_mds_nodsh && skip "remote MDS with nodsh"
1999         remote_ost_nodsh && skip "remote OST with nodsh"
2000
2001         exhaust_all_precreations 0x215
2002         reset_enospc
2003
2004         $LFS setstripe -c 1 $DIR/$tdir         # 1 stripe / file
2005
2006         touch $DIR/$tdir/$tfile
2007         #define OBD_FAIL_TGT_DELAY_PRECREATE     0x705
2008         # all except ost1
2009         for (( i=1; i < OSTCOUNT; i++ )); do
2010                 do_facet ost$i lctl set_param fail_loc=0x705
2011         done
2012         local START=`date +%s`
2013         createmany -o $DIR/$tdir/$tfile 32
2014
2015         local FINISH=`date +%s`
2016         local TIMEOUT=`lctl get_param -n timeout`
2017         local PROCESS=$((FINISH - START))
2018         [ $PROCESS -ge $((TIMEOUT / 2)) ] && \
2019                error "$FINISH - $START >= $TIMEOUT / 2"
2020         sleep $((TIMEOUT / 2 - PROCESS))
2021         reset_enospc
2022 }
2023 run_test 27v "skip object creation on slow OST"
2024
2025 test_27w() { # bug 10997
2026         test_mkdir $DIR/$tdir
2027         $LFS setstripe -S 65536 $DIR/$tdir/f0 || error "setstripe failed"
2028         [ $($LFS getstripe -S $DIR/$tdir/f0) -ne 65536 ] &&
2029                 error "stripe size $size != 65536" || true
2030         [ $($LFS getstripe -d $DIR/$tdir | grep -c "stripe_count") -eq 0 ] &&
2031                 error "$LFS getstripe -d $DIR/$tdir no 'stripe_count'" || true
2032 }
2033 run_test 27w "check $LFS setstripe -S and getstrip -d options"
2034
2035 test_27wa() {
2036         [[ $OSTCOUNT -lt 2 ]] &&
2037                 skip_env "skipping multiple stripe count/offset test"
2038
2039         test_mkdir $DIR/$tdir
2040         for i in $(seq 1 $OSTCOUNT); do
2041                 offset=$((i - 1))
2042                 $LFS setstripe -c $i -i $offset $DIR/$tdir/f$i ||
2043                         error "setstripe -c $i -i $offset failed"
2044                 count=$($LFS getstripe -c $DIR/$tdir/f$i)
2045                 index=$($LFS getstripe -i $DIR/$tdir/f$i)
2046                 [ $count -ne $i ] && error "stripe count $count != $i" || true
2047                 [ $index -ne $offset ] &&
2048                         error "stripe offset $index != $offset" || true
2049         done
2050 }
2051 run_test 27wa "check $LFS setstripe -c -i options"
2052
2053 test_27x() {
2054         remote_ost_nodsh && skip "remote OST with nodsh"
2055         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2056         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2057
2058         OFFSET=$(($OSTCOUNT - 1))
2059         OSTIDX=0
2060         local OST=$(ostname_from_index $OSTIDX)
2061
2062         test_mkdir $DIR/$tdir
2063         $LFS setstripe -c 1 $DIR/$tdir  # 1 stripe per file
2064         do_facet ost$((OSTIDX + 1)) lctl set_param -n obdfilter.$OST.degraded 1
2065         sleep_maxage
2066         createmany -o $DIR/$tdir/$tfile $OSTCOUNT
2067         for i in $(seq 0 $OFFSET); do
2068                 [ $($LFS getstripe $DIR/$tdir/$tfile$i | grep -A 10 obdidx |
2069                         awk '{print $1}' | grep -w "$OSTIDX") ] &&
2070                 error "OST0 was degraded but new created file still use it"
2071         done
2072         do_facet ost$((OSTIDX + 1)) lctl set_param -n obdfilter.$OST.degraded 0
2073 }
2074 run_test 27x "create files while OST0 is degraded"
2075
2076 test_27y() {
2077         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2078         remote_mds_nodsh && skip "remote MDS with nodsh"
2079         remote_ost_nodsh && skip "remote OST with nodsh"
2080         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2081
2082         local mdtosc=$(get_mdtosc_proc_path $SINGLEMDS $FSNAME-OST0000)
2083         local last_id=$(do_facet $SINGLEMDS lctl get_param -n \
2084                 osp.$mdtosc.prealloc_last_id)
2085         local next_id=$(do_facet $SINGLEMDS lctl get_param -n \
2086                 osp.$mdtosc.prealloc_next_id)
2087         local fcount=$((last_id - next_id))
2088         [[ $fcount -eq 0 ]] && skip "not enough space on OST0"
2089         [[ $fcount -gt $OSTCOUNT ]] && fcount=$OSTCOUNT
2090
2091         local MDS_OSCS=$(do_facet $SINGLEMDS lctl dl |
2092                          awk '/[oO][sS][cC].*md[ts]/ { print $4 }')
2093         local OST_DEACTIVE_IDX=-1
2094         local OSC
2095         local OSTIDX
2096         local OST
2097
2098         for OSC in $MDS_OSCS; do
2099                 OST=$(osc_to_ost $OSC)
2100                 OSTIDX=$(index_from_ostuuid $OST)
2101                 if [ $OST_DEACTIVE_IDX == -1 ]; then
2102                         OST_DEACTIVE_IDX=$OSTIDX
2103                 fi
2104                 if [ $OSTIDX != $OST_DEACTIVE_IDX ]; then
2105                         echo $OSC "is Deactivated:"
2106                         do_facet $SINGLEMDS lctl --device  %$OSC deactivate
2107                 fi
2108         done
2109
2110         OSTIDX=$(index_from_ostuuid $OST)
2111         test_mkdir $DIR/$tdir
2112         $LFS setstripe -c 1 $DIR/$tdir      # 1 stripe / file
2113
2114         for OSC in $MDS_OSCS; do
2115                 OST=$(osc_to_ost $OSC)
2116                 OSTIDX=$(index_from_ostuuid $OST)
2117                 if [ $OSTIDX == $OST_DEACTIVE_IDX ]; then
2118                         echo $OST "is degraded:"
2119                         do_facet ost$((OSTIDX+1)) lctl set_param -n \
2120                                                 obdfilter.$OST.degraded=1
2121                 fi
2122         done
2123
2124         sleep_maxage
2125         createmany -o $DIR/$tdir/$tfile $fcount
2126
2127         for OSC in $MDS_OSCS; do
2128                 OST=$(osc_to_ost $OSC)
2129                 OSTIDX=$(index_from_ostuuid $OST)
2130                 if [ $OSTIDX == $OST_DEACTIVE_IDX ]; then
2131                         echo $OST "is recovered from degraded:"
2132                         do_facet ost$((OSTIDX+1)) lctl set_param -n \
2133                                                 obdfilter.$OST.degraded=0
2134                 else
2135                         do_facet $SINGLEMDS lctl --device %$OSC activate
2136                 fi
2137         done
2138
2139         # all osp devices get activated, hence -1 stripe count restored
2140         local stripe_count=0
2141
2142         # sleep 2*lod_qos_maxage seconds waiting for lod qos to notice osp
2143         # devices get activated.
2144         sleep_maxage
2145         $LFS setstripe -c -1 $DIR/$tfile
2146         stripe_count=$($LFS getstripe -c $DIR/$tfile)
2147         rm -f $DIR/$tfile
2148         [ $stripe_count -ne $OSTCOUNT ] &&
2149                 error "Of $OSTCOUNT OSTs, only $stripe_count is available"
2150         return 0
2151 }
2152 run_test 27y "create files while OST0 is degraded and the rest inactive"
2153
2154 check_seq_oid()
2155 {
2156         log "check file $1"
2157
2158         lmm_count=$($LFS getstripe -c $1)
2159         lmm_seq=$($LFS getstripe -v $1 | awk '/lmm_seq/ { print $2 }')
2160         lmm_oid=$($LFS getstripe -v $1 | awk '/lmm_object_id/ { print $2 }')
2161
2162         local old_ifs="$IFS"
2163         IFS=$'[:]'
2164         fid=($($LFS path2fid $1))
2165         IFS="$old_ifs"
2166
2167         log "FID seq ${fid[1]}, oid ${fid[2]} ver ${fid[3]}"
2168         log "LOV seq $lmm_seq, oid $lmm_oid, count: $lmm_count"
2169
2170         # compare lmm_seq and lu_fid->f_seq
2171         [ $lmm_seq = ${fid[1]} ] || { error "SEQ mismatch"; return 1; }
2172         # compare lmm_object_id and lu_fid->oid
2173         [ $lmm_oid = ${fid[2]} ] || { error "OID mismatch"; return 2; }
2174
2175         # check the trusted.fid attribute of the OST objects of the file
2176         local have_obdidx=false
2177         local stripe_nr=0
2178         $LFS getstripe $1 | while read obdidx oid hex seq; do
2179                 # skip lines up to and including "obdidx"
2180                 [ -z "$obdidx" ] && break
2181                 [ "$obdidx" = "obdidx" ] && have_obdidx=true && continue
2182                 $have_obdidx || continue
2183
2184                 local ost=$((obdidx + 1))
2185                 local dev=$(ostdevname $ost)
2186                 local oid_hex
2187
2188                 log "want: stripe:$stripe_nr ost:$obdidx oid:$oid/$hex seq:$seq"
2189
2190                 seq=$(echo $seq | sed -e "s/^0x//g")
2191                 if [ $seq == 0 ] || [ $(facet_fstype ost$ost) == zfs ]; then
2192                         oid_hex=$(echo $oid)
2193                 else
2194                         oid_hex=$(echo $hex | sed -e "s/^0x//g")
2195                 fi
2196                 local obj_file="O/$seq/d$((oid %32))/$oid_hex"
2197
2198                 local ff=""
2199                 #
2200                 # Don't unmount/remount the OSTs if we don't need to do that.
2201                 # LU-2577 changes filter_fid to be smaller, so debugfs needs
2202                 # update too, until that use mount/ll_decode_filter_fid/mount.
2203                 # Re-enable when debugfs will understand new filter_fid.
2204                 #
2205                 if [ $(facet_fstype ost$ost) == ldiskfs ]; then
2206                         ff=$(do_facet ost$ost "$DEBUGFS -c -R 'stat $obj_file' \
2207                                 $dev 2>/dev/null" | grep "parent=")
2208                 fi
2209                 if [ -z "$ff" ]; then
2210                         stop ost$ost
2211                         mount_fstype ost$ost
2212                         ff=$(do_facet ost$ost $LL_DECODE_FILTER_FID \
2213                                 $(facet_mntpt ost$ost)/$obj_file)
2214                         unmount_fstype ost$ost
2215                         start ost$ost $dev $OST_MOUNT_OPTS
2216                         clients_up
2217                 fi
2218
2219                 [ -z "$ff" ] && error "$obj_file: no filter_fid info"
2220
2221                 echo "$ff" | sed -e 's#.*objid=#got: objid=#'
2222
2223                 # /mnt/O/0/d23/23: objid=23 seq=0 parent=[0x200000400:0x1e:0x1]
2224                 # fid: objid=23 seq=0 parent=[0x200000400:0x1e:0x0] stripe=1
2225                 #
2226                 # fid: parent=[0x200000400:0x1e:0x0] stripe=1 stripe_count=2 \
2227                 #       stripe_size=1048576 component_id=1 component_start=0 \
2228                 #       component_end=33554432
2229                 local ff_parent=$(sed -e 's/.*parent=.//' <<<$ff)
2230                 local ff_pseq=$(cut -d: -f1 <<<$ff_parent)
2231                 local ff_poid=$(cut -d: -f2 <<<$ff_parent)
2232                 local ff_pstripe
2233                 if grep -q 'stripe=' <<<$ff; then
2234                         ff_pstripe=$(sed -e 's/.*stripe=//' -e 's/ .*//' <<<$ff)
2235                 else
2236                         # $LL_DECODE_FILTER_FID does not print "stripe="; look
2237                         # into f_ver in this case.  See comment on ff_parent.
2238                         ff_pstripe=$(cut -d: -f3 <<<$ff_parent | sed -e 's/]//')
2239                 fi
2240
2241                 # compare lmm_seq and filter_fid->ff_parent.f_seq
2242                 [ $ff_pseq = $lmm_seq ] ||
2243                         error "FF parent SEQ $ff_pseq != $lmm_seq"
2244                 # compare lmm_object_id and filter_fid->ff_parent.f_oid
2245                 [ $ff_poid = $lmm_oid ] ||
2246                         error "FF parent OID $ff_poid != $lmm_oid"
2247                 (($ff_pstripe == $stripe_nr)) ||
2248                         error "FF stripe $ff_pstripe != $stripe_nr"
2249
2250                 stripe_nr=$((stripe_nr + 1))
2251                 [ $CLIENT_VERSION -lt $(version_code 2.9.55) ] &&
2252                         continue
2253                 if grep -q 'stripe_count=' <<<$ff; then
2254                         local ff_scnt=$(sed -e 's/.*stripe_count=//' \
2255                                             -e 's/ .*//' <<<$ff)
2256                         [ $lmm_count = $ff_scnt ] ||
2257                                 error "FF stripe count $lmm_count != $ff_scnt"
2258                 fi
2259         done
2260 }
2261
2262 test_27z() {
2263         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2264         remote_ost_nodsh && skip "remote OST with nodsh"
2265
2266         test_mkdir $DIR/$tdir
2267         $LFS setstripe -c 1 -i 0 -S 64k $DIR/$tdir/$tfile-1 ||
2268                 { error "setstripe -c -1 failed"; return 1; }
2269         # We need to send a write to every object to get parent FID info set.
2270         # This _should_ also work for setattr, but does not currently.
2271         # touch $DIR/$tdir/$tfile-1 ||
2272         dd if=/dev/zero of=$DIR/$tdir/$tfile-1 bs=1M count=1 ||
2273                 { error "dd $tfile-1 failed"; return 2; }
2274         $LFS setstripe -c -1 -i $((OSTCOUNT - 1)) -S 1M $DIR/$tdir/$tfile-2 ||
2275                 { error "setstripe -c -1 failed"; return 3; }
2276         dd if=/dev/zero of=$DIR/$tdir/$tfile-2 bs=1M count=$OSTCOUNT ||
2277                 { error "dd $tfile-2 failed"; return 4; }
2278
2279         # make sure write RPCs have been sent to OSTs
2280         sync; sleep 5; sync
2281
2282         check_seq_oid $DIR/$tdir/$tfile-1 || return 5
2283         check_seq_oid $DIR/$tdir/$tfile-2 || return 6
2284 }
2285 run_test 27z "check SEQ/OID on the MDT and OST filesystems"
2286
2287 test_27A() { # b=19102
2288         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2289
2290         save_layout_restore_at_exit $MOUNT
2291         $LFS setstripe -c 0 -i -1 -S 0 $MOUNT
2292         wait_update $HOSTNAME "$LFS getstripe -c $MOUNT | sed 's/  *//g'" "1" 20 ||
2293                 error "stripe count $($LFS getstripe -c $MOUNT) != 1"
2294         local default_size=$($LFS getstripe -S $MOUNT)
2295         local default_offset=$($LFS getstripe -i $MOUNT)
2296         local dsize=$(do_facet $SINGLEMDS \
2297                 "$LCTL get_param -n lod.$(facet_svc $SINGLEMDS)*.stripesize")
2298         [ $default_size -eq $dsize ] ||
2299                 error "stripe size $default_size != $dsize"
2300         [ $default_offset -eq -1 ] ||
2301                 error "stripe offset $default_offset != -1"
2302 }
2303 run_test 27A "check filesystem-wide default LOV EA values"
2304
2305 test_27B() { # LU-2523
2306         test_mkdir $DIR/$tdir
2307         rm -f $DIR/$tdir/f0 $DIR/$tdir/f1
2308         touch $DIR/$tdir/f0
2309         # open f1 with O_LOV_DELAY_CREATE
2310         # rename f0 onto f1
2311         # call setstripe ioctl on open file descriptor for f1
2312         # close
2313         multiop $DIR/$tdir/f1 oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:nB1c \
2314                 $DIR/$tdir/f0
2315
2316         rm -f $DIR/$tdir/f1
2317         # open f1 with O_LOV_DELAY_CREATE
2318         # unlink f1
2319         # call setstripe ioctl on open file descriptor for f1
2320         # close
2321         multiop $DIR/$tdir/f1 oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:uB1c
2322
2323         # Allow multiop to fail in imitation of NFS's busted semantics.
2324         true
2325 }
2326 run_test 27B "call setstripe on open unlinked file/rename victim"
2327
2328 # 27C family tests full striping and overstriping
2329 test_27Ca() { #LU-2871
2330         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2331
2332         declare -a ost_idx
2333         local index
2334         local found
2335         local i
2336         local j
2337
2338         test_mkdir $DIR/$tdir
2339         cd $DIR/$tdir
2340         for i in $(seq 0 $((OSTCOUNT - 1))); do
2341                 # set stripe across all OSTs starting from OST$i
2342                 $LFS setstripe -i $i -c -1 $tfile$i
2343                 # get striping information
2344                 ost_idx=($($LFS getstripe $tfile$i |
2345                          tail -n $((OSTCOUNT + 1)) | awk '{print $1}'))
2346                 echo ${ost_idx[@]}
2347
2348                 # check the layout
2349                 [ ${#ost_idx[@]} -eq $OSTCOUNT ] ||
2350                         error "${#ost_idx[@]} != $OSTCOUNT"
2351
2352                 for index in $(seq 0 $((OSTCOUNT - 1))); do
2353                         found=0
2354                         for j in $(echo ${ost_idx[@]}); do
2355                                 if [ $index -eq $j ]; then
2356                                         found=1
2357                                         break
2358                                 fi
2359                         done
2360                         [ $found = 1 ] ||
2361                                 error "Can not find $index in ${ost_idx[@]}"
2362                 done
2363         done
2364 }
2365 run_test 27Ca "check full striping across all OSTs"
2366
2367 test_27Cb() {
2368         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2369                 skip "server does not support overstriping"
2370         [[ $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
2371                 skip_env "too many osts, skipping"
2372
2373         test_mkdir -p $DIR/$tdir
2374         local setcount=$(($OSTCOUNT * 2))
2375         [ $setcount -ge 160 ] || large_xattr_enabled ||
2376                 skip_env "ea_inode feature disabled"
2377
2378         $LFS setstripe -C $setcount $DIR/$tdir/$tfile ||
2379                 error "setstripe failed"
2380
2381         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2382         [ $count -eq $setcount ] ||
2383                 error "stripe count $count, should be $setcount"
2384
2385         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" ||
2386                 error "overstriped should be set in pattern"
2387
2388         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2389                 error "dd failed"
2390 }
2391 run_test 27Cb "more stripes than OSTs with -C"
2392
2393 test_27Cc() {
2394         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2395                 skip "server does not support overstriping"
2396         [[ $OSTCOUNT -lt 2 ]] && skip_env "need > 1 OST"
2397
2398         test_mkdir -p $DIR/$tdir
2399         local setcount=$(($OSTCOUNT - 1))
2400
2401         [ $setcount -ge 160 ] || large_xattr_enabled ||
2402                 skip_env "ea_inode feature disabled"
2403
2404         $LFS setstripe -C $setcount $DIR/$tdir/$tfile ||
2405                 error "setstripe failed"
2406
2407         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2408         [ $count -eq $setcount ] ||
2409                 error "stripe count $count, should be $setcount"
2410
2411         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" &&
2412                 error "overstriped should not be set in pattern"
2413
2414         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2415                 error "dd failed"
2416 }
2417 run_test 27Cc "fewer stripes than OSTs does not set overstriping"
2418
2419 test_27Cd() {
2420         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2421                 skip "server does not support overstriping"
2422         [[ $OSTCOUNT -lt 2 ]] && skip_env "need > 1 OST"
2423         large_xattr_enabled || skip_env "ea_inode feature disabled"
2424
2425         test_mkdir -p $DIR/$tdir
2426         local setcount=$LOV_MAX_STRIPE_COUNT
2427
2428         $LFS setstripe -C $setcount $DIR/$tdir/$tfile ||
2429                 error "setstripe failed"
2430
2431         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2432         [ $count -eq $setcount ] ||
2433                 error "stripe count $count, should be $setcount"
2434
2435         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" ||
2436                 error "overstriped should be set in pattern"
2437
2438         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2439                 error "dd failed"
2440
2441         rm -f $DIR/$tdir/$tfile || error "Delete $tfile failed"
2442 }
2443 run_test 27Cd "test maximum stripe count"
2444
2445 test_27Ce() {
2446         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2447                 skip "server does not support overstriping"
2448         test_mkdir -p $DIR/$tdir
2449
2450         pool_add $TESTNAME || error "Pool creation failed"
2451         pool_add_targets $TESTNAME 0 || error "pool_add_targets failed"
2452
2453         local setcount=8
2454
2455         $LFS setstripe  -C $setcount -p "$TESTNAME" $DIR/$tdir/$tfile ||
2456                 error "setstripe failed"
2457
2458         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2459         [ $count -eq $setcount ] ||
2460                 error "stripe count $count, should be $setcount"
2461
2462         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" ||
2463                 error "overstriped should be set in pattern"
2464
2465         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2466                 error "dd failed"
2467
2468         rm -f $DIR/$tdir/$tfile || error "Delete $tfile failed"
2469 }
2470 run_test 27Ce "test pool with overstriping"
2471
2472 test_27Cf() {
2473         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2474                 skip "server does not support overstriping"
2475         [[ $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
2476                 skip_env "too many osts, skipping"
2477
2478         test_mkdir -p $DIR/$tdir
2479
2480         local setcount=$(($OSTCOUNT * 2))
2481         [ $setcount -ge 160 ] || large_xattr_enabled ||
2482                 skip_env "ea_inode feature disabled"
2483
2484         $LFS setstripe  -C $setcount $DIR/$tdir/ ||
2485                 error "setstripe failed"
2486
2487         echo 1 > $DIR/$tdir/$tfile
2488
2489         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2490         [ $count -eq $setcount ] ||
2491                 error "stripe count $count, should be $setcount"
2492
2493         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" ||
2494                 error "overstriped should be set in pattern"
2495
2496         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2497                 error "dd failed"
2498
2499         rm -f $DIR/$tdir/$tfile || error "Delete $tfile failed"
2500 }
2501 run_test 27Cf "test default inheritance with overstriping"
2502
2503 test_27D() {
2504         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
2505         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
2506         remote_mds_nodsh && skip "remote MDS with nodsh"
2507
2508         local POOL=${POOL:-testpool}
2509         local first_ost=0
2510         local last_ost=$(($OSTCOUNT - 1))
2511         local ost_step=1
2512         local ost_list=$(seq $first_ost $ost_step $last_ost)
2513         local ost_range="$first_ost $last_ost $ost_step"
2514
2515         test_mkdir $DIR/$tdir
2516         pool_add $POOL || error "pool_add failed"
2517         pool_add_targets $POOL $ost_range || error "pool_add_targets failed"
2518
2519         local skip27D
2520         [ $MDS1_VERSION -lt $(version_code 2.8.55) ] &&
2521                 skip27D+="-s 29"
2522         [ $MDS1_VERSION -lt $(version_code 2.9.55) ] ||
2523                 [ $CLIENT_VERSION -lt $(version_code 2.9.55) ] &&
2524                         skip27D+=" -s 30,31"
2525         [[ ! $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ||
2526           $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
2527                 skip27D+=" -s 32,33"
2528         [[ $MDS_VERSION -lt $(version_code $SEL_VER) ]] &&
2529                 skip27D+=" -s 34"
2530         llapi_layout_test -d$DIR/$tdir -p$POOL -o$OSTCOUNT $skip27D ||
2531                 error "llapi_layout_test failed"
2532
2533         destroy_test_pools || error "destroy test pools failed"
2534 }
2535 run_test 27D "validate llapi_layout API"
2536
2537 # Verify that default_easize is increased from its initial value after
2538 # accessing a widely striped file.
2539 test_27E() {
2540         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
2541         [ $CLIENT_VERSION -lt $(version_code 2.5.57) ] &&
2542                 skip "client does not have LU-3338 fix"
2543
2544         # 72 bytes is the minimum space required to store striping
2545         # information for a file striped across one OST:
2546         # (sizeof(struct lov_user_md_v3) +
2547         #  sizeof(struct lov_user_ost_data_v1))
2548         local min_easize=72
2549         $LCTL set_param -n llite.*.default_easize $min_easize ||
2550                 error "lctl set_param failed"
2551         local easize=$($LCTL get_param -n llite.*.default_easize)
2552
2553         [ $easize -eq $min_easize ] ||
2554                 error "failed to set default_easize"
2555
2556         $LFS setstripe -c $OSTCOUNT $DIR/$tfile ||
2557                 error "setstripe failed"
2558         # In order to ensure stat() call actually talks to MDS we need to
2559         # do something drastic to this file to shake off all lock, e.g.
2560         # rename it (kills lookup lock forcing cache cleaning)
2561         mv $DIR/$tfile $DIR/${tfile}-1
2562         ls -l $DIR/${tfile}-1
2563         rm $DIR/${tfile}-1
2564
2565         easize=$($LCTL get_param -n llite.*.default_easize)
2566
2567         [ $easize -gt $min_easize ] ||
2568                 error "default_easize not updated"
2569 }
2570 run_test 27E "check that default extended attribute size properly increases"
2571
2572 test_27F() { # LU-5346/LU-7975
2573         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2574         [[ $OSTCOUNT -lt 2 ]] && skip "needs >= 2 OSTs"
2575         [[ $MDS1_VERSION -lt $(version_code 2.8.51) ]] &&
2576                 skip "Need MDS version at least 2.8.51"
2577         remote_ost_nodsh && skip "remote OST with nodsh"
2578
2579         test_mkdir $DIR/$tdir
2580         rm -f $DIR/$tdir/f0
2581         $LFS setstripe -c 2 $DIR/$tdir
2582
2583         # stop all OSTs to reproduce situation for LU-7975 ticket
2584         for num in $(seq $OSTCOUNT); do
2585                 stop ost$num
2586         done
2587
2588         # open/create f0 with O_LOV_DELAY_CREATE
2589         # truncate f0 to a non-0 size
2590         # close
2591         multiop $DIR/$tdir/f0 oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:T1050000c
2592
2593         $CHECKSTAT -s 1050000 $DIR/$tdir/f0 || error "checkstat failed"
2594         # open/write it again to force delayed layout creation
2595         cat /etc/hosts > $DIR/$tdir/f0 &
2596         catpid=$!
2597
2598         # restart OSTs
2599         for num in $(seq $OSTCOUNT); do
2600                 start ost$num $(ostdevname $num) $OST_MOUNT_OPTS ||
2601                         error "ost$num failed to start"
2602         done
2603
2604         wait $catpid || error "cat failed"
2605
2606         cmp /etc/hosts $DIR/$tdir/f0 || error "cmp failed"
2607         [[ $($LFS getstripe -c $DIR/$tdir/f0) == 2 ]] ||
2608                 error "wrong stripecount"
2609
2610 }
2611 run_test 27F "Client resend delayed layout creation with non-zero size"
2612
2613 test_27G() { #LU-10629
2614         [ $MDS1_VERSION -lt $(version_code 2.11.51) ] &&
2615                 skip "Need MDS version at least 2.11.51"
2616         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
2617         remote_mds_nodsh && skip "remote MDS with nodsh"
2618         local POOL=${POOL:-testpool}
2619         local ostrange="0 0 1"
2620
2621         test_mkdir $DIR/$tdir
2622         touch $DIR/$tdir/$tfile.nopool
2623         pool_add $POOL || error "pool_add failed"
2624         pool_add_targets $POOL $ostrange || error "pool_add_targets failed"
2625         $LFS setstripe -p $POOL $DIR/$tdir
2626
2627         local pool=$($LFS getstripe -p $DIR/$tdir)
2628
2629         [ "$pool" = "$POOL" ] || error "Striping failed got '$pool' not '$POOL'"
2630         touch $DIR/$tdir/$tfile.default
2631         $LFS setstripe -E 1M --pool $POOL -c 1 -E eof -c 1 $DIR/$tdir/$tfile.pfl
2632         $LFS find $DIR/$tdir -type f --pool $POOL
2633         local found=$($LFS find $DIR/$tdir -type f --pool $POOL | wc -l)
2634         [[ "$found" == "2" ]] ||
2635                 error "found $found != 2 files in '$DIR/$tdir' in '$POOL'"
2636
2637         $LFS setstripe -d $DIR/$tdir
2638
2639         pool=$($LFS getstripe -p -d $DIR/$tdir)
2640
2641         [[ "$pool" != "$POOL" ]] || error "$DIR/$tdir is still '$pool'"
2642 }
2643 run_test 27G "Clear OST pool from stripe"
2644
2645 test_27H() {
2646         [[ $MDS1_VERSION -le $(version_code 2.11.54) ]] &&
2647                 skip "Need MDS version newer than 2.11.54"
2648         [[ $OSTCOUNT -lt 3 ]] && skip_env "needs >= 3 OSTs"
2649         test_mkdir $DIR/$tdir
2650         $LFS setstripe -o 0 -o 2 $DIR/$tdir || error "setstripe failed"
2651         touch $DIR/$tdir/$tfile
2652         $LFS getstripe -c $DIR/$tdir/$tfile
2653         [ $($LFS getstripe -c $DIR/$tdir/$tfile) -eq 2 ] ||
2654                 error "two-stripe file doesn't have two stripes"
2655
2656         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
2657         $LFS getstripe -y $DIR/$tdir/$tfile
2658         (( $($LFS getstripe -y $DIR/$tdir/$tfile |
2659              egrep -c "l_ost_idx: [02]$") == "2" )) ||
2660                 error "expected l_ost_idx: [02]$ not matched"
2661
2662         # make sure ost list has been cleared
2663         local stripesize=$($LFS getstripe -S $DIR/$tdir)
2664         $LFS setstripe -S $((stripesize * 4)) -i 1 \
2665                 -c $((OSTCOUNT - 1)) $DIR/$tdir || error "setstripe"
2666         touch $DIR/$tdir/f3
2667         $LVERIFY $DIR/$tdir $DIR/$tdir/f3 || error "lverify failed"
2668 }
2669 run_test 27H "Set specific OSTs stripe"
2670
2671 test_27I() {
2672         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2673         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2674         [[ $MDS1_VERSION -gt $(version_code 2.12.52) ]] ||
2675                 skip "Need MDS version newer than 2.12.52"
2676         local pool=$TESTNAME
2677         local ostrange="1 1 1"
2678
2679         save_layout_restore_at_exit $MOUNT
2680         $LFS setstripe -c 2 -i 0 $MOUNT
2681         pool_add $pool || error "pool_add failed"
2682         pool_add_targets $pool $ostrange || "pool_add_targets failed"
2683         test_mkdir $DIR/$tdir
2684         $LFS setstripe -p $pool $DIR/$tdir
2685         $MULTIOP $DIR/$tdir/$tfile Oc || error "multiop failed"
2686         $LFS getstripe $DIR/$tdir/$tfile
2687 }
2688 run_test 27I "check that root dir striping does not break parent dir one"
2689
2690 test_27J() {
2691         [[ $MDS1_VERSION -le $(version_code 2.12.51) ]] &&
2692                 skip "Need MDS version newer than 2.12.51"
2693
2694         test_mkdir $DIR/$tdir
2695         local uuid1=$(cat /proc/sys/kernel/random/uuid)
2696         local uuid2=$(cat /proc/sys/kernel/random/uuid)
2697
2698         # create foreign file (raw way)
2699         create_foreign_file -f $DIR/$tdir/$tfile -x "${uuid1}@${uuid2}" \
2700                 -t 1 -F 0xda08 || error "create_foreign_file failed"
2701
2702         # verify foreign file (raw way)
2703         parse_foreign_file -f $DIR/$tdir/$tfile |
2704                 grep "lov_foreign_magic: 0x0BD70BD0" ||
2705                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign magic"
2706         parse_foreign_file -f $DIR/$tdir/$tfile | grep "lov_xattr_size: 89" ||
2707                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign size"
2708         parse_foreign_file -f $DIR/$tdir/$tfile |
2709                 grep "lov_foreign_size: 73" ||
2710                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign size"
2711         parse_foreign_file -f $DIR/$tdir/$tfile |
2712                 grep "lov_foreign_type: 1" ||
2713                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign type"
2714         parse_foreign_file -f $DIR/$tdir/$tfile |
2715                 grep "lov_foreign_flags: 0x0000DA08" ||
2716                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign flags"
2717         local lov=$(parse_foreign_file -f $DIR/$tdir/$tfile |
2718                 grep "lov_foreign_value: 0x" |
2719                 sed -e 's/lov_foreign_value: 0x//')
2720         local lov2=$(echo -n "${uuid1}@${uuid2}" | od -A n -t x1 -w160)
2721         [[ $lov = ${lov2// /} ]] ||
2722                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign value"
2723
2724         # create foreign file (lfs + API)
2725         $LFS setstripe --foreign=daos --flags 0xda08 \
2726                 -x "${uuid1}@${uuid2}" $DIR/$tdir/${tfile}2 ||
2727                 error "$DIR/$tdir/${tfile}2: create failed"
2728
2729         $LFS getstripe -v $DIR/$tdir/${tfile}2 |
2730                 grep "lfm_magic:.*0x0BD70BD0" ||
2731                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign magic"
2732         # lfm_length is LOV EA size - sizeof(lfm_magic) - sizeof(lfm_length)
2733         $LFS getstripe -v $DIR/$tdir/${tfile}2 | grep "lfm_length:.*73" ||
2734                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign size"
2735         $LFS getstripe -v $DIR/$tdir/${tfile}2 | grep "lfm_type:.*daos" ||
2736                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign type"
2737         $LFS getstripe -v $DIR/$tdir/${tfile}2 |
2738                 grep "lfm_flags:.*0x0000DA08" ||
2739                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign flags"
2740         $LFS getstripe $DIR/$tdir/${tfile}2 |
2741                 grep "lfm_value:.*${uuid1}@${uuid2}" ||
2742                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign value"
2743
2744         # modify striping should fail
2745         $LFS setstripe -c 2 $DIR/$tdir/$tfile &&
2746                 error "$DIR/$tdir/$tfile: setstripe should fail"
2747         $LFS setstripe -c 2 $DIR/$tdir/${tfile}2 &&
2748                 error "$DIR/$tdir/${tfile}2: setstripe should fail"
2749
2750         # R/W should fail
2751         cat $DIR/$tdir/$tfile && error "$DIR/$tdir/$tfile: read should fail"
2752         cat $DIR/$tdir/${tfile}2 &&
2753                 error "$DIR/$tdir/${tfile}2: read should fail"
2754         cat /etc/passwd > $DIR/$tdir/$tfile &&
2755                 error "$DIR/$tdir/$tfile: write should fail"
2756         cat /etc/passwd > $DIR/$tdir/${tfile}2 &&
2757                 error "$DIR/$tdir/${tfile}2: write should fail"
2758
2759         # chmod should work
2760         chmod 222 $DIR/$tdir/$tfile ||
2761                 error "$DIR/$tdir/$tfile: chmod failed"
2762         chmod 222 $DIR/$tdir/${tfile}2 ||
2763                 error "$DIR/$tdir/${tfile}2: chmod failed"
2764
2765         # chown should work
2766         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/$tfile ||
2767                 error "$DIR/$tdir/$tfile: chown failed"
2768         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/${tfile}2 ||
2769                 error "$DIR/$tdir/${tfile}2: chown failed"
2770
2771         # rename should work
2772         mv $DIR/$tdir/$tfile $DIR/$tdir/${tfile}.new ||
2773                 error "$DIR/$tdir/$tfile: rename of foreign file has failed"
2774         mv $DIR/$tdir/${tfile}2 $DIR/$tdir/${tfile}2.new ||
2775                 error "$DIR/$tdir/${tfile}2: rename of foreign file has failed"
2776
2777         #remove foreign file
2778         rm $DIR/$tdir/${tfile}.new ||
2779                 error "$DIR/$tdir/${tfile}.new: remove of foreign file has failed"
2780         rm $DIR/$tdir/${tfile}2.new ||
2781                 error "$DIR/$tdir/${tfile}2.new: remove of foreign file has failed"
2782 }
2783 run_test 27J "basic ops on file with foreign LOV"
2784
2785 test_27K() {
2786         [[ $MDS1_VERSION -le $(version_code 2.12.49) ]] &&
2787                 skip "Need MDS version newer than 2.12.49"
2788
2789         test_mkdir $DIR/$tdir
2790         local uuid1=$(cat /proc/sys/kernel/random/uuid)
2791         local uuid2=$(cat /proc/sys/kernel/random/uuid)
2792
2793         # create foreign dir (raw way)
2794         create_foreign_dir -d $DIR/$tdir/$tdir -x "${uuid1}@${uuid2}" -t 1 ||
2795                 error "create_foreign_dir FAILED"
2796
2797         # verify foreign dir (raw way)
2798         parse_foreign_dir -d $DIR/$tdir/$tdir |
2799                 grep "lmv_foreign_magic:.*0xcd50cd0" ||
2800                 error "$DIR/$tdir/$tfile: invalid LMV EA magic"
2801         parse_foreign_dir -d $DIR/$tdir/$tdir | grep "lmv_xattr_size:.*89$" ||
2802                 error "$DIR/$tdir/$tdir: invalid LMV EA size"
2803         parse_foreign_dir -d $DIR/$tdir/$tdir | grep "lmv_foreign_type: 1$" ||
2804                 error "$DIR/$tdir/$tdir: invalid LMV EA type"
2805         parse_foreign_dir -d $DIR/$tdir/$tdir | grep "lmv_foreign_flags: 0$" ||
2806                 error "$DIR/$tdir/$tdir: invalid LMV EA flags"
2807         local lmv=$(parse_foreign_dir -d $DIR/$tdir/$tdir |
2808                 grep "lmv_foreign_value: 0x" |
2809                 sed 's/lmv_foreign_value: 0x//')
2810         local lmv2=$(echo -n "${uuid1}@${uuid2}" | od -A n -t x1 -w160 |
2811                 sed 's/ //g')
2812         [[ $lmv == $lmv2 ]] || error "$DIR/$tdir/$tdir: invalid LMV EA value"
2813
2814         # create foreign dir (lfs + API)
2815         $LFS mkdir --foreign=daos --xattr="${uuid1}@${uuid2}" --flags=0xda05 \
2816                 $DIR/$tdir/${tdir}2 ||
2817                 error "$DIR/$tdir/${tdir}2: create failed"
2818
2819         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 |
2820                 grep "lfm_magic:.*0x0CD50CD0" ||
2821                 error "$DIR/$tdir/${tdir}2: invalid LMV EA magic"
2822         # lfm_length is LMV EA size - sizeof(lfm_magic) - sizeof(lfm_length)
2823         # - sizeof(lfm_type) - sizeof(lfm_flags)
2824         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 | grep "lfm_length:.*73" ||
2825                 error "$DIR/$tdir/${tdir}2: invalid LMV EA size"
2826         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 | grep "lfm_type:.*daos" ||
2827                 error "$DIR/$tdir/${tdir}2: invalid LMV EA type"
2828         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 |
2829                 grep "lfm_flags:.*0x0000DA05" ||
2830                 error "$DIR/$tdir/${tdir}2: invalid LMV EA flags"
2831         $LFS getdirstripe $DIR/$tdir/${tdir}2 |
2832                 grep "lfm_value.*${uuid1}@${uuid2}" ||
2833                 error "$DIR/$tdir/${tdir}2: invalid LMV EA value"
2834
2835         # file create in dir should fail
2836         touch $DIR/$tdir/$tdir/$tfile && "$DIR/$tdir: file create should fail"
2837         touch $DIR/$tdir/${tdir}2/$tfile &&
2838                 "$DIR/${tdir}2: file create should fail"
2839
2840         # chmod should work
2841         chmod 777 $DIR/$tdir/$tdir ||
2842                 error "$DIR/$tdir: chmod failed"
2843         chmod 777 $DIR/$tdir/${tdir}2 ||
2844                 error "$DIR/${tdir}2: chmod failed"
2845
2846         # chown should work
2847         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/$tdir ||
2848                 error "$DIR/$tdir: chown failed"
2849         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/${tdir}2 ||
2850                 error "$DIR/${tdir}2: chown failed"
2851
2852         # rename should work
2853         mv $DIR/$tdir/$tdir $DIR/$tdir/${tdir}.new ||
2854                 error "$DIR/$tdir/$tdir: rename of foreign dir has failed"
2855         mv $DIR/$tdir/${tdir}2 $DIR/$tdir/${tdir}2.new ||
2856                 error "$DIR/$tdir/${tdir}2: rename of foreign dir has failed"
2857
2858         #remove foreign dir
2859         rmdir $DIR/$tdir/${tdir}.new ||
2860                 error "$DIR/$tdir/${tdir}.new: remove of foreign dir has failed"
2861         rmdir $DIR/$tdir/${tdir}2.new ||
2862                 error "$DIR/$tdir/${tdir}2.new: remove of foreign dir has failed"
2863 }
2864 run_test 27K "basic ops on dir with foreign LMV"
2865
2866 test_27L() {
2867         remote_mds_nodsh && skip "remote MDS with nodsh"
2868
2869         local POOL=${POOL:-$TESTNAME}
2870
2871         pool_add $POOL || error "pool_add failed"
2872
2873         lfs pool_list $MOUNT | grep -Fx "${FSNAME}.${POOL}" ||
2874                  error "pool_list does not contain ${FSNAME}.${POOL}:" \
2875                        "$(lfs pool_list $MOUNT | grep -F "${POOL}")"
2876 }
2877 run_test 27L "lfs pool_list gives correct pool name"
2878
2879 test_27M() {
2880         [[ $(lustre_version_code $SINGLEMDS) -lt $(version_code 2.12.57) ]] &&
2881                 skip "Need MDS version >= than 2.12.57"
2882         remote_mds_nodsh && skip "remote MDS with nodsh"
2883         [[ $OSTCOUNT -lt 2 ]] && skip_env "need > 1 OST"
2884
2885         test_mkdir $DIR/$tdir
2886
2887         # Set default striping on directory
2888         $LFS setstripe -C 4 $DIR/$tdir
2889
2890         echo 1 > $DIR/$tdir/${tfile}.1
2891         local count=$($LFS getstripe -c $DIR/$tdir/${tfile}.1)
2892         local setcount=4
2893         [ $count -eq $setcount ] ||
2894                 error "(1) stripe count $count, should be $setcount"
2895
2896         # Capture existing append_stripe_count setting for restore
2897         local orig_count=$(do_facet mds1 $LCTL get_param -n mdd.$FSNAME-MDT0000.append_stripe_count)
2898         local mdts=$(comma_list $(mdts_nodes))
2899         stack_trap "do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=$orig_count" EXIT
2900
2901         local appendcount=$orig_count
2902         echo 1 >> $DIR/$tdir/${tfile}.2_append
2903         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.2_append)
2904         [ $count -eq $appendcount ] ||
2905                 error "(2)stripe count $count, should be $appendcount for append"
2906
2907         # Disable O_APPEND striping, verify it works
2908         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=0
2909
2910         # Should now get the default striping, which is 4
2911         setcount=4
2912         echo 1 >> $DIR/$tdir/${tfile}.3_append
2913         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.3_append)
2914         [ $count -eq $setcount ] ||
2915                 error "(3) stripe count $count, should be $setcount"
2916
2917         # Try changing the stripe count for append files
2918         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=2
2919
2920         # Append striping is now 2 (directory default is still 4)
2921         appendcount=2
2922         echo 1 >> $DIR/$tdir/${tfile}.4_append
2923         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.4_append)
2924         [ $count -eq $appendcount ] ||
2925                 error "(4) stripe count $count, should be $appendcount for append"
2926
2927         # Test append stripe count of -1
2928         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=-1
2929         appendcount=$OSTCOUNT
2930         echo 1 >> $DIR/$tdir/${tfile}.5
2931         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.5)
2932         [ $count -eq $appendcount ] ||
2933                 error "(5) stripe count $count, should be $appendcount for append"
2934
2935         # Set append striping back to default of 1
2936         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=1
2937
2938         # Try a new default striping, PFL + DOM
2939         $LFS setstripe -L mdt -E 1M -E -1 -c 2 $DIR/$tdir
2940
2941         # Create normal DOM file, DOM returns stripe count == 0
2942         setcount=0
2943         touch $DIR/$tdir/${tfile}.6
2944         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.6)
2945         [ $count -eq $setcount ] ||
2946                 error "(6) stripe count $count, should be $setcount"
2947
2948         # Show
2949         appendcount=1
2950         echo 1 >> $DIR/$tdir/${tfile}.7_append
2951         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.7_append)
2952         [ $count -eq $appendcount ] ||
2953                 error "(7) stripe count $count, should be $appendcount for append"
2954
2955         # Clean up DOM layout
2956         $LFS setstripe -d $DIR/$tdir
2957
2958         # Now test that append striping works when layout is from root
2959         $LFS setstripe -c 2 $MOUNT
2960         # Make a special directory for this
2961         mkdir $DIR/${tdir}/${tdir}.2
2962         stack_trap "$LFS setstripe -d $MOUNT" EXIT
2963
2964         # Verify for normal file
2965         setcount=2
2966         echo 1 > $DIR/${tdir}/${tdir}.2/${tfile}.8
2967         count=$($LFS getstripe -c $DIR/$tdir/${tdir}.2/${tfile}.8)
2968         [ $count -eq $setcount ] ||
2969                 error "(8) stripe count $count, should be $setcount"
2970
2971         appendcount=1
2972         echo 1 >> $DIR/${tdir}/${tdir}.2/${tfile}.9_append
2973         count=$($LFS getstripe -c $DIR/${tdir}/${tdir}.2/${tfile}.9_append)
2974         [ $count -eq $appendcount ] ||
2975                 error "(9) stripe count $count, should be $appendcount for append"
2976
2977         # Now test O_APPEND striping with pools
2978         do_nodes $mdts $LCTL set_param mdd.*.append_pool="$TESTNAME"
2979         stack_trap "do_nodes $mdts $LCTL set_param mdd.*.append_pool='none'" EXIT
2980
2981         # Create the pool
2982         pool_add $TESTNAME || error "pool creation failed"
2983         pool_add_targets $TESTNAME 0 1 || error "Pool add targets failed"
2984
2985         echo 1 >> $DIR/$tdir/${tfile}.10_append
2986
2987         pool=$($LFS getstripe -p $DIR/$tdir/${tfile}.10_append)
2988         [ "$pool" = "$TESTNAME" ] || error "(10) incorrect pool: $pool"
2989
2990         # Check that count is still correct
2991         appendcount=1
2992         echo 1 >> $DIR/$tdir/${tfile}.11_append
2993         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.11_append)
2994         [ $count -eq $appendcount ] ||
2995                 error "(11) stripe count $count, should be $appendcount for append"
2996
2997         # Disable O_APPEND stripe count, verify pool works separately
2998         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=0
2999
3000         echo 1 >> $DIR/$tdir/${tfile}.12_append
3001
3002         pool=$($LFS getstripe -p $DIR/$tdir/${tfile}.12_append)
3003         [ "$pool" = "$TESTNAME" ] || error "(12) incorrect pool: $pool"
3004
3005         # Remove pool setting, verify it's not applied
3006         do_nodes $mdts $LCTL set_param mdd.*.append_pool='none'
3007
3008         echo 1 >> $DIR/$tdir/${tfile}.13_append
3009
3010         pool=$($LFS getstripe -p $DIR/$tdir/${tfile}.13_append)
3011         [ "$pool" = "" ] || error "(13) pool found: $pool"
3012 }
3013 run_test 27M "test O_APPEND striping"
3014
3015 test_27N() {
3016         combined_mgs_mds && skip "needs separate MGS/MDT"
3017
3018         pool_add $TESTNAME || error "pool_add failed"
3019         do_facet mgs "$LCTL pool_list $FSNAME" |
3020                 grep -Fx "${FSNAME}.${TESTNAME}" ||
3021                 error "lctl pool_list on MGS failed"
3022 }
3023 run_test 27N "lctl pool_list on separate MGS gives correct pool name"
3024
3025 # createtest also checks that device nodes are created and
3026 # then visible correctly (#2091)
3027 test_28() { # bug 2091
3028         test_mkdir $DIR/d28
3029         $CREATETEST $DIR/d28/ct || error "createtest failed"
3030 }
3031 run_test 28 "create/mknod/mkdir with bad file types ============"
3032
3033 test_29() {
3034         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3035
3036         sync; sleep 1; sync # flush out any dirty pages from previous tests
3037         cancel_lru_locks
3038         test_mkdir $DIR/d29
3039         touch $DIR/d29/foo
3040         log 'first d29'
3041         ls -l $DIR/d29
3042
3043         declare -i LOCKCOUNTORIG=0
3044         for lock_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_count); do
3045                 let LOCKCOUNTORIG=$LOCKCOUNTORIG+$lock_count
3046         done
3047         [ $LOCKCOUNTORIG -eq 0 ] && error "No mdc lock count" && return 1
3048
3049         declare -i LOCKUNUSEDCOUNTORIG=0
3050         for unused_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_unused_count); do
3051                 let LOCKUNUSEDCOUNTORIG=$LOCKUNUSEDCOUNTORIG+$unused_count
3052         done
3053
3054         log 'second d29'
3055         ls -l $DIR/d29
3056         log 'done'
3057
3058         declare -i LOCKCOUNTCURRENT=0
3059         for lock_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_count); do
3060                 let LOCKCOUNTCURRENT=$LOCKCOUNTCURRENT+$lock_count
3061         done
3062
3063         declare -i LOCKUNUSEDCOUNTCURRENT=0
3064         for unused_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_unused_count); do
3065                 let LOCKUNUSEDCOUNTCURRENT=$LOCKUNUSEDCOUNTCURRENT+$unused_count
3066         done
3067
3068         if [[ $LOCKCOUNTCURRENT -gt $LOCKCOUNTORIG ]]; then
3069                 $LCTL set_param -n ldlm.dump_namespaces ""
3070                 error "CURRENT: $LOCKCOUNTCURRENT > $LOCKCOUNTORIG"
3071                 $LCTL dk | sort -k4 -t: > $TMP/test_29.dk
3072                 log "dumped log to $TMP/test_29.dk (bug 5793)"
3073                 return 2
3074         fi
3075         if [[ $LOCKUNUSEDCOUNTCURRENT -gt $LOCKUNUSEDCOUNTORIG ]]; then
3076                 error "UNUSED: $LOCKUNUSEDCOUNTCURRENT > $LOCKUNUSEDCOUNTORIG"
3077                 $LCTL dk | sort -k4 -t: > $TMP/test_29.dk
3078                 log "dumped log to $TMP/test_29.dk (bug 5793)"
3079                 return 3
3080         fi
3081 }
3082 run_test 29 "IT_GETATTR regression  ============================"
3083
3084 test_30a() { # was test_30
3085         cp $(which ls) $DIR || cp /bin/ls $DIR
3086         $DIR/ls / || error "Can't execute binary from lustre"
3087         rm $DIR/ls
3088 }
3089 run_test 30a "execute binary from Lustre (execve) =============="
3090
3091 test_30b() {
3092         cp `which ls` $DIR || cp /bin/ls $DIR
3093         chmod go+rx $DIR/ls
3094         $RUNAS $DIR/ls / || error "Can't execute binary from lustre as non-root"
3095         rm $DIR/ls
3096 }
3097 run_test 30b "execute binary from Lustre as non-root ==========="
3098
3099 test_30c() { # b=22376
3100         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3101
3102         cp $(which ls) $DIR || cp /bin/ls $DIR
3103         chmod a-rw $DIR/ls
3104         cancel_lru_locks mdc
3105         cancel_lru_locks osc
3106         $RUNAS $DIR/ls / || error "Can't execute binary from lustre"
3107         rm -f $DIR/ls
3108 }
3109 run_test 30c "execute binary from Lustre without read perms ===="
3110
3111 test_30d() {
3112         cp $(which dd) $DIR || error "failed to copy dd to $DIR/dd"
3113
3114         for i in {1..10}; do
3115                 $DIR/dd bs=1M count=128 if=/dev/zero of=$DIR/$tfile &
3116                 local PID=$!
3117                 sleep 1
3118                 $LCTL set_param ldlm.namespaces.*MDT*.lru_size=clear
3119                 wait $PID || error "executing dd from Lustre failed"
3120                 rm -f $DIR/$tfile
3121         done
3122
3123         rm -f $DIR/dd
3124 }
3125 run_test 30d "execute binary from Lustre while clear locks"
3126
3127 test_31a() {
3128         $OPENUNLINK $DIR/f31 $DIR/f31 || error "openunlink failed"
3129         $CHECKSTAT -a $DIR/f31 || error "$DIR/f31 exists"
3130 }
3131 run_test 31a "open-unlink file =================================="
3132
3133 test_31b() {
3134         touch $DIR/f31 || error "touch $DIR/f31 failed"
3135         ln $DIR/f31 $DIR/f31b || error "ln failed"
3136         $MULTIOP $DIR/f31b Ouc || error "multiop failed"
3137         $CHECKSTAT -t file $DIR/f31 || error "$DIR/f31 not file type"
3138 }
3139 run_test 31b "unlink file with multiple links while open ======="
3140
3141 test_31c() {
3142         touch $DIR/f31 || error "touch $DIR/f31 failed"
3143         ln $DIR/f31 $DIR/f31c || error "ln failed"
3144         multiop_bg_pause $DIR/f31 O_uc ||
3145                 error "multiop_bg_pause for $DIR/f31 failed"
3146         MULTIPID=$!
3147         $MULTIOP $DIR/f31c Ouc
3148         kill -USR1 $MULTIPID
3149         wait $MULTIPID
3150 }
3151 run_test 31c "open-unlink file with multiple links ============="
3152
3153 test_31d() {
3154         opendirunlink $DIR/d31d $DIR/d31d || error "opendirunlink failed"
3155         $CHECKSTAT -a $DIR/d31d || error "$DIR/d31d exists"
3156 }
3157 run_test 31d "remove of open directory ========================="
3158
3159 test_31e() { # bug 2904
3160         openfilleddirunlink $DIR/d31e || error "openfilleddirunlink failed"
3161 }
3162 run_test 31e "remove of open non-empty directory ==============="
3163
3164 test_31f() { # bug 4554
3165         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3166
3167         set -vx
3168         test_mkdir $DIR/d31f
3169         $LFS setstripe -S 1048576 -c 1 $DIR/d31f
3170         cp /etc/hosts $DIR/d31f
3171         ls -l $DIR/d31f
3172         $LFS getstripe $DIR/d31f/hosts
3173         multiop_bg_pause $DIR/d31f D_c || return 1
3174         MULTIPID=$!
3175
3176         rm -rv $DIR/d31f || error "first of $DIR/d31f"
3177         test_mkdir $DIR/d31f
3178         $LFS setstripe -S 1048576 -c 1 $DIR/d31f
3179         cp /etc/hosts $DIR/d31f
3180         ls -l $DIR/d31f
3181         $LFS getstripe $DIR/d31f/hosts
3182         multiop_bg_pause $DIR/d31f D_c || return 1
3183         MULTIPID2=$!
3184
3185         kill -USR1 $MULTIPID || error "first opendir $MULTIPID not running"
3186         wait $MULTIPID || error "first opendir $MULTIPID failed"
3187
3188         sleep 6
3189
3190         kill -USR1 $MULTIPID2 || error "second opendir $MULTIPID not running"
3191         wait $MULTIPID2 || error "second opendir $MULTIPID2 failed"
3192         set +vx
3193 }
3194 run_test 31f "remove of open directory with open-unlink file ==="
3195
3196 test_31g() {
3197         echo "-- cross directory link --"
3198         test_mkdir -c1 $DIR/${tdir}ga
3199         test_mkdir -c1 $DIR/${tdir}gb
3200         touch $DIR/${tdir}ga/f
3201         ln $DIR/${tdir}ga/f $DIR/${tdir}gb/g
3202         $CHECKSTAT -t file $DIR/${tdir}ga/f || error "source"
3203         [ `stat -c%h $DIR/${tdir}ga/f` == '2' ] || error "source nlink"
3204         $CHECKSTAT -t file $DIR/${tdir}gb/g || error "target"
3205         [ `stat -c%h $DIR/${tdir}gb/g` == '2' ] || error "target nlink"
3206 }
3207 run_test 31g "cross directory link==============="
3208
3209 test_31h() {
3210         echo "-- cross directory link --"
3211         test_mkdir -c1 $DIR/${tdir}
3212         test_mkdir -c1 $DIR/${tdir}/dir
3213         touch $DIR/${tdir}/f
3214         ln $DIR/${tdir}/f $DIR/${tdir}/dir/g
3215         $CHECKSTAT -t file $DIR/${tdir}/f || error "source"
3216         [ `stat -c%h $DIR/${tdir}/f` == '2' ] || error "source nlink"
3217         $CHECKSTAT -t file $DIR/${tdir}/dir/g || error "target"
3218         [ `stat -c%h $DIR/${tdir}/dir/g` == '2' ] || error "target nlink"
3219 }
3220 run_test 31h "cross directory link under child==============="
3221
3222 test_31i() {
3223         echo "-- cross directory link --"
3224         test_mkdir -c1 $DIR/$tdir
3225         test_mkdir -c1 $DIR/$tdir/dir
3226         touch $DIR/$tdir/dir/f
3227         ln $DIR/$tdir/dir/f $DIR/$tdir/g
3228         $CHECKSTAT -t file $DIR/$tdir/dir/f || error "source"
3229         [ `stat -c%h $DIR/$tdir/dir/f` == '2' ] || error "source nlink"
3230         $CHECKSTAT -t file $DIR/$tdir/g || error "target"
3231         [ `stat -c%h $DIR/$tdir/g` == '2' ] || error "target nlink"
3232 }
3233 run_test 31i "cross directory link under parent==============="
3234
3235 test_31j() {
3236         test_mkdir -c1 -p $DIR/$tdir
3237         test_mkdir -c1 -p $DIR/$tdir/dir1
3238         ln $DIR/$tdir/dir1 $DIR/$tdir/dir2 && error "ln for dir"
3239         link $DIR/$tdir/dir1 $DIR/$tdir/dir3 && error "link for dir"
3240         mlink $DIR/$tdir/dir1 $DIR/$tdir/dir4 && error "mlink for dir"
3241         mlink $DIR/$tdir/dir1 $DIR/$tdir/dir1 && error "mlink to the same dir"
3242         return 0
3243 }
3244 run_test 31j "link for directory==============="
3245
3246 test_31k() {
3247         test_mkdir -c1 -p $DIR/$tdir
3248         touch $DIR/$tdir/s
3249         touch $DIR/$tdir/exist
3250         mlink $DIR/$tdir/s $DIR/$tdir/t || error "mlink"
3251         mlink $DIR/$tdir/s $DIR/$tdir/exist && error "mlink to exist file"
3252         mlink $DIR/$tdir/s $DIR/$tdir/s && error "mlink to the same file"
3253         mlink $DIR/$tdir/s $DIR/$tdir && error "mlink to parent dir"
3254         mlink $DIR/$tdir $DIR/$tdir/s && error "mlink parent dir to target"
3255         mlink $DIR/$tdir/not-exist $DIR/$tdir/foo && error "mlink non-existing to new"
3256         mlink $DIR/$tdir/not-exist $DIR/$tdir/s && error "mlink non-existing to exist"
3257         return 0
3258 }
3259 run_test 31k "link to file: the same, non-existing, dir==============="
3260
3261 test_31m() {
3262         mkdir $DIR/d31m
3263         touch $DIR/d31m/s
3264         mkdir $DIR/d31m2
3265         touch $DIR/d31m2/exist
3266         mlink $DIR/d31m/s $DIR/d31m2/t || error "mlink"
3267         mlink $DIR/d31m/s $DIR/d31m2/exist && error "mlink to exist file"
3268         mlink $DIR/d31m/s $DIR/d31m2 && error "mlink to parent dir"
3269         mlink $DIR/d31m2 $DIR/d31m/s && error "mlink parent dir to target"
3270         mlink $DIR/d31m/not-exist $DIR/d31m2/foo && error "mlink non-existing to new"
3271         mlink $DIR/d31m/not-exist $DIR/d31m2/s && error "mlink non-existing to exist"
3272         return 0
3273 }
3274 run_test 31m "link to file: the same, non-existing, dir==============="
3275
3276 test_31n() {
3277         touch $DIR/$tfile || error "cannot create '$DIR/$tfile'"
3278         nlink=$(stat --format=%h $DIR/$tfile)
3279         [ ${nlink:--1} -eq 1 ] || error "nlink is $nlink, expected 1"
3280         local fd=$(free_fd)
3281         local cmd="exec $fd<$DIR/$tfile"
3282         eval $cmd
3283         cmd="exec $fd<&-"
3284         trap "eval $cmd" EXIT
3285         nlink=$(stat --dereference --format=%h /proc/self/fd/$fd)
3286         [ ${nlink:--1} -eq 1 ] || error "nlink is $nlink, expected 1"
3287         rm $DIR/$tfile || error "cannot remove '$DIR/$tfile'"
3288         nlink=$(stat --dereference --format=%h /proc/self/fd/$fd)
3289         [ ${nlink:--1} -eq 0 ] || error "nlink is $nlink, expected 0"
3290         eval $cmd
3291 }
3292 run_test 31n "check link count of unlinked file"
3293
3294 link_one() {
3295         local tempfile=$(mktemp $1_XXXXXX)
3296         mlink $tempfile $1 2> /dev/null &&
3297                 echo "$BASHPID: link $tempfile to $1 succeeded"
3298         munlink $tempfile
3299 }
3300
3301 test_31o() { # LU-2901
3302         test_mkdir $DIR/$tdir
3303         for LOOP in $(seq 100); do
3304                 rm -f $DIR/$tdir/$tfile*
3305                 for THREAD in $(seq 8); do
3306                         link_one $DIR/$tdir/$tfile.$LOOP &
3307                 done
3308                 wait
3309                 local LINKS=$(ls -1 $DIR/$tdir | grep -c $tfile.$LOOP)
3310                 [[ $LINKS -gt 1 ]] && ls $DIR/$tdir &&
3311                         error "$LINKS duplicate links to $tfile.$LOOP" &&
3312                         break || true
3313         done
3314 }
3315 run_test 31o "duplicate hard links with same filename"
3316
3317 test_31p() {
3318         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
3319
3320         test_mkdir $DIR/$tdir
3321         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
3322         $LFS setdirstripe -D -c2 -H all_char $DIR/$tdir/striped_dir
3323
3324         opendirunlink $DIR/$tdir/striped_dir/test1 ||
3325                 error "open unlink test1 failed"
3326         opendirunlink $DIR/$tdir/striped_dir/test2 ||
3327                 error "open unlink test2 failed"
3328
3329         $CHECKSTAT -a $DIR/$tdir/striped_dir/test1 ||
3330                 error "test1 still exists"
3331         $CHECKSTAT -a $DIR/$tdir/striped_dir/test2 ||
3332                 error "test2 still exists"
3333 }
3334 run_test 31p "remove of open striped directory"
3335
3336 cleanup_test32_mount() {
3337         local rc=0
3338         trap 0
3339         local loopdev=$(losetup -a | grep $EXT2_DEV | sed -ne 's/:.*$//p')
3340         $UMOUNT $DIR/$tdir/ext2-mountpoint || rc=$?
3341         losetup -d $loopdev || true
3342         rm -rf $DIR/$tdir
3343         return $rc
3344 }
3345
3346 test_32a() {
3347         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3348
3349         echo "== more mountpoints and symlinks ================="
3350         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3351         trap cleanup_test32_mount EXIT
3352         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3353         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3354                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3355         $CHECKSTAT -t dir $DIR/$tdir/ext2-mountpoint/.. ||
3356                 error "$DIR/$tdir/ext2-mountpoint/.. not dir type"
3357         cleanup_test32_mount
3358 }
3359 run_test 32a "stat d32a/ext2-mountpoint/.. ====================="
3360
3361 test_32b() {
3362         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3363
3364         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3365         trap cleanup_test32_mount EXIT
3366         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3367         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3368                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3369         ls -al $DIR/$tdir/ext2-mountpoint/.. ||
3370                 error "Can't list $DIR/$tdir/ext2-mountpoint/.."
3371         cleanup_test32_mount
3372 }
3373 run_test 32b "open d32b/ext2-mountpoint/.. ====================="
3374
3375 test_32c() {
3376         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3377
3378         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3379         trap cleanup_test32_mount EXIT
3380         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3381         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3382                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3383         test_mkdir -p $DIR/$tdir/d2/test_dir
3384         $CHECKSTAT -t dir $DIR/$tdir/ext2-mountpoint/../d2/test_dir ||
3385                 error "$DIR/$tdir/ext2-mountpoint/../d2/test_dir not dir type"
3386         cleanup_test32_mount
3387 }
3388 run_test 32c "stat d32c/ext2-mountpoint/../d2/test_dir ========="
3389
3390 test_32d() {
3391         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3392
3393         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3394         trap cleanup_test32_mount EXIT
3395         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3396         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3397                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3398         test_mkdir -p $DIR/$tdir/d2/test_dir
3399         ls -al $DIR/$tdir/ext2-mountpoint/../d2/test_dir ||
3400                 error "Can't list $DIR/$tdir/ext2-mountpoint/../d2/test_dir"
3401         cleanup_test32_mount
3402 }
3403 run_test 32d "open d32d/ext2-mountpoint/../d2/test_dir"
3404
3405 test_32e() {
3406         rm -fr $DIR/$tdir
3407         test_mkdir -p $DIR/$tdir/tmp
3408         local tmp_dir=$DIR/$tdir/tmp
3409         ln -s $DIR/$tdir $tmp_dir/symlink11
3410         ln -s $tmp_dir/symlink11 $tmp_dir/../symlink01
3411         $CHECKSTAT -t link $DIR/$tdir/tmp/symlink11 || error "symlink11 bad"
3412         $CHECKSTAT -t link $DIR/$tdir/symlink01 || error "symlink01 bad"
3413 }
3414 run_test 32e "stat d32e/symlink->tmp/symlink->lustre-subdir"
3415
3416 test_32f() {
3417         rm -fr $DIR/$tdir
3418         test_mkdir -p $DIR/$tdir/tmp
3419         local tmp_dir=$DIR/$tdir/tmp
3420         ln -s $DIR/$tdir $tmp_dir/symlink11
3421         ln -s $tmp_dir/symlink11 $tmp_dir/../symlink01
3422         ls $DIR/$tdir/tmp/symlink11  || error "symlink11 bad"
3423         ls $DIR/$tdir/symlink01 || error "symlink01 bad"
3424 }
3425 run_test 32f "open d32f/symlink->tmp/symlink->lustre-subdir"
3426
3427 test_32g() {
3428         local tmp_dir=$DIR/$tdir/tmp
3429         test_mkdir -p $tmp_dir
3430         test_mkdir $DIR/${tdir}2
3431         ln -s $DIR/${tdir}2 $tmp_dir/symlink12
3432         ln -s $tmp_dir/symlink12 $tmp_dir/../symlink02
3433         $CHECKSTAT -t link $tmp_dir/symlink12 || error "symlink12 not a link"
3434         $CHECKSTAT -t link $DIR/$tdir/symlink02 || error "symlink02 not a link"
3435         $CHECKSTAT -t dir -f $tmp_dir/symlink12 || error "symlink12 not a dir"
3436         $CHECKSTAT -t dir -f $DIR/$tdir/symlink02 || error "symlink12 not a dir"
3437 }
3438 run_test 32g "stat d32g/symlink->tmp/symlink->lustre-subdir/${tdir}2"
3439
3440 test_32h() {
3441         rm -fr $DIR/$tdir $DIR/${tdir}2
3442         tmp_dir=$DIR/$tdir/tmp
3443         test_mkdir -p $tmp_dir
3444         test_mkdir $DIR/${tdir}2
3445         ln -s $DIR/${tdir}2 $tmp_dir/symlink12
3446         ln -s $tmp_dir/symlink12 $tmp_dir/../symlink02
3447         ls $tmp_dir/symlink12 || error "listing symlink12"
3448         ls $DIR/$tdir/symlink02  || error "listing symlink02"
3449 }
3450 run_test 32h "open d32h/symlink->tmp/symlink->lustre-subdir/${tdir}2"
3451
3452 test_32i() {
3453         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3454
3455         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3456         trap cleanup_test32_mount EXIT
3457         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3458         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3459                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3460         touch $DIR/$tdir/test_file
3461         $CHECKSTAT -t file $DIR/$tdir/ext2-mountpoint/../test_file ||
3462                 error "$DIR/$tdir/ext2-mountpoint/../test_file not file type"
3463         cleanup_test32_mount
3464 }
3465 run_test 32i "stat d32i/ext2-mountpoint/../test_file ==========="
3466
3467 test_32j() {
3468         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3469
3470         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3471         trap cleanup_test32_mount EXIT
3472         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3473         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3474                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3475         touch $DIR/$tdir/test_file
3476         cat $DIR/$tdir/ext2-mountpoint/../test_file ||
3477                 error "Can't open $DIR/$tdir/ext2-mountpoint/../test_file"
3478         cleanup_test32_mount
3479 }
3480 run_test 32j "open d32j/ext2-mountpoint/../test_file ==========="
3481
3482 test_32k() {
3483         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3484
3485         rm -fr $DIR/$tdir
3486         trap cleanup_test32_mount EXIT
3487         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3488         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3489                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3490         test_mkdir -p $DIR/$tdir/d2
3491         touch $DIR/$tdir/d2/test_file || error "touch failed"
3492         $CHECKSTAT -t file $DIR/$tdir/ext2-mountpoint/../d2/test_file ||
3493                 error "$DIR/$tdir/ext2-mountpoint/../d2/test_file not file type"
3494         cleanup_test32_mount
3495 }
3496 run_test 32k "stat d32k/ext2-mountpoint/../d2/test_file ========"
3497
3498 test_32l() {
3499         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3500
3501         rm -fr $DIR/$tdir
3502         trap cleanup_test32_mount EXIT
3503         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3504         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3505                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3506         test_mkdir -p $DIR/$tdir/d2
3507         touch $DIR/$tdir/d2/test_file || error "touch failed"
3508         cat  $DIR/$tdir/ext2-mountpoint/../d2/test_file ||
3509                 error "Can't open $DIR/$tdir/ext2-mountpoint/../d2/test_file"
3510         cleanup_test32_mount
3511 }
3512 run_test 32l "open d32l/ext2-mountpoint/../d2/test_file ========"
3513
3514 test_32m() {
3515         rm -fr $DIR/d32m
3516         test_mkdir -p $DIR/d32m/tmp
3517         TMP_DIR=$DIR/d32m/tmp
3518         ln -s $DIR $TMP_DIR/symlink11
3519         ln -s $TMP_DIR/symlink11 $TMP_DIR/../symlink01
3520         $CHECKSTAT -t link $DIR/d32m/tmp/symlink11 ||
3521                 error "symlink11 not a link"
3522         $CHECKSTAT -t link $DIR/d32m/symlink01 ||
3523                 error "symlink01 not a link"
3524 }
3525 run_test 32m "stat d32m/symlink->tmp/symlink->lustre-root ======"
3526
3527 test_32n() {
3528         rm -fr $DIR/d32n
3529         test_mkdir -p $DIR/d32n/tmp
3530         TMP_DIR=$DIR/d32n/tmp
3531         ln -s $DIR $TMP_DIR/symlink11
3532         ln -s $TMP_DIR/symlink11 $TMP_DIR/../symlink01
3533         ls -l $DIR/d32n/tmp/symlink11  || error "listing symlink11"
3534         ls -l $DIR/d32n/symlink01 || error "listing symlink01"
3535 }
3536 run_test 32n "open d32n/symlink->tmp/symlink->lustre-root ======"
3537
3538 test_32o() {
3539         touch $DIR/$tfile
3540         test_mkdir -p $DIR/d32o/tmp
3541         TMP_DIR=$DIR/d32o/tmp
3542         ln -s $DIR/$tfile $TMP_DIR/symlink12
3543         ln -s $TMP_DIR/symlink12 $TMP_DIR/../symlink02
3544         $CHECKSTAT -t link $DIR/d32o/tmp/symlink12 ||
3545                 error "symlink12 not a link"
3546         $CHECKSTAT -t link $DIR/d32o/symlink02 || error "symlink02 not a link"
3547         $CHECKSTAT -t file -f $DIR/d32o/tmp/symlink12 ||
3548                 error "$DIR/d32o/tmp/symlink12 not file type"
3549         $CHECKSTAT -t file -f $DIR/d32o/symlink02 ||
3550                 error "$DIR/d32o/symlink02 not file type"
3551 }
3552 run_test 32o "stat d32o/symlink->tmp/symlink->lustre-root/$tfile"
3553
3554 test_32p() {
3555         log 32p_1
3556         rm -fr $DIR/d32p
3557         log 32p_2
3558         rm -f $DIR/$tfile
3559         log 32p_3
3560         touch $DIR/$tfile
3561         log 32p_4
3562         test_mkdir -p $DIR/d32p/tmp
3563         log 32p_5
3564         TMP_DIR=$DIR/d32p/tmp
3565         log 32p_6
3566         ln -s $DIR/$tfile $TMP_DIR/symlink12
3567         log 32p_7
3568         ln -s $TMP_DIR/symlink12 $TMP_DIR/../symlink02
3569         log 32p_8
3570         cat $DIR/d32p/tmp/symlink12 ||
3571                 error "Can't open $DIR/d32p/tmp/symlink12"
3572         log 32p_9
3573         cat $DIR/d32p/symlink02 || error "Can't open $DIR/d32p/symlink02"
3574         log 32p_10
3575 }
3576 run_test 32p "open d32p/symlink->tmp/symlink->lustre-root/$tfile"
3577
3578 test_32q() {
3579         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3580
3581         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3582         trap cleanup_test32_mount EXIT
3583         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3584         touch $DIR/$tdir/ext2-mountpoint/under_the_mount || error "touch failed"
3585         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3586                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3587         ls $DIR/$tdir/ext2-mountpoint | grep "\<under_the_mount\>" && error
3588         cleanup_test32_mount
3589 }
3590 run_test 32q "stat follows mountpoints in Lustre (should return error)"
3591
3592 test_32r() {
3593         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3594
3595         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3596         trap cleanup_test32_mount EXIT
3597         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3598         touch $DIR/$tdir/ext2-mountpoint/under_the_mount || error "touch failed"
3599         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3600                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3601         ls $DIR/$tdir/ext2-mountpoint | grep -q under_the_mount && error || true
3602         cleanup_test32_mount
3603 }
3604 run_test 32r "opendir follows mountpoints in Lustre (should return error)"
3605
3606 test_33aa() {
3607         rm -f $DIR/$tfile
3608         touch $DIR/$tfile
3609         chmod 444 $DIR/$tfile
3610         chown $RUNAS_ID $DIR/$tfile
3611         log 33_1
3612         $RUNAS $OPENFILE -f O_RDWR $DIR/$tfile && error || true
3613         log 33_2
3614 }
3615 run_test 33aa "write file with mode 444 (should return error)"
3616
3617 test_33a() {
3618         rm -fr $DIR/$tdir
3619         test_mkdir $DIR/$tdir
3620         chown $RUNAS_ID $DIR/$tdir
3621         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $DIR/$tdir/$tfile ||
3622                 error "$RUNAS create $tdir/$tfile failed"
3623         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $DIR/$tdir/$tfile &&
3624                 error "open RDWR" || true
3625 }
3626 run_test 33a "test open file(mode=0444) with O_RDWR (should return error)"
3627
3628 test_33b() {
3629         rm -fr $DIR/$tdir
3630         test_mkdir $DIR/$tdir
3631         chown $RUNAS_ID $DIR/$tdir
3632         $RUNAS $OPENFILE -f 1286739555 $DIR/$tdir/$tfile || true
3633 }
3634 run_test 33b "test open file with malformed flags (No panic)"
3635
3636 test_33c() {
3637         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3638         remote_ost_nodsh && skip "remote OST with nodsh"
3639
3640         local ostnum
3641         local ostname
3642         local write_bytes
3643         local all_zeros
3644
3645         all_zeros=:
3646         rm -fr $DIR/$tdir
3647         test_mkdir $DIR/$tdir
3648         # Read: 0, Write: 4, create/destroy: 2/0, stat: 1, punch: 0
3649
3650         sync
3651         for ostnum in $(seq $OSTCOUNT); do
3652                 # test-framework's OST numbering is one-based, while Lustre's
3653                 # is zero-based
3654                 ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
3655                 # Parsing llobdstat's output sucks; we could grep the /proc
3656                 # path, but that's likely to not be as portable as using the
3657                 # llobdstat utility.  So we parse lctl output instead.
3658                 write_bytes=$(do_facet ost$ostnum lctl get_param -n \
3659                         obdfilter/$ostname/stats |
3660                         awk '/^write_bytes/ {print $7}' )
3661                 echo "baseline_write_bytes@$OSTnum/$ostname=$write_bytes"
3662                 if (( ${write_bytes:-0} > 0 ))
3663                 then
3664                         all_zeros=false
3665                         break;
3666                 fi
3667         done
3668
3669         $all_zeros || return 0
3670
3671         # Write four bytes
3672         echo foo > $DIR/$tdir/bar
3673         # Really write them
3674         sync
3675
3676         # Total up write_bytes after writing.  We'd better find non-zeros.
3677         for ostnum in $(seq $OSTCOUNT); do
3678                 ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
3679                 write_bytes=$(do_facet ost$ostnum lctl get_param -n \
3680                         obdfilter/$ostname/stats |
3681                         awk '/^write_bytes/ {print $7}' )
3682                 echo "write_bytes@$OSTnum/$ostname=$write_bytes"
3683                 if (( ${write_bytes:-0} > 0 ))
3684                 then
3685                         all_zeros=false
3686                         break;
3687                 fi
3688         done
3689
3690         if $all_zeros
3691         then
3692                 for ostnum in $(seq $OSTCOUNT); do
3693                         ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
3694                         echo "Check that write_bytes is present in obdfilter/*/stats:"
3695                         do_facet ost$ostnum lctl get_param -n \
3696                                 obdfilter/$ostname/stats
3697                 done
3698                 error "OST not keeping write_bytes stats (b22312)"
3699         fi
3700 }
3701 run_test 33c "test llobdstat and write_bytes"
3702
3703 test_33d() {
3704         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
3705         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3706
3707         local MDTIDX=1
3708         local remote_dir=$DIR/$tdir/remote_dir
3709
3710         test_mkdir $DIR/$tdir
3711         $LFS mkdir -i $MDTIDX $remote_dir ||
3712                 error "create remote directory failed"
3713
3714         touch $remote_dir/$tfile
3715         chmod 444 $remote_dir/$tfile
3716         chown $RUNAS_ID $remote_dir/$tfile
3717
3718         $RUNAS $OPENFILE -f O_RDWR $DIR/$tfile && error || true
3719
3720         chown $RUNAS_ID $remote_dir
3721         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $remote_dir/f33 ||
3722                                         error "create" || true
3723         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $remote_dir/f33 &&
3724                                     error "open RDWR" || true
3725         $RUNAS $OPENFILE -f 1286739555 $remote_dir/f33 || true
3726 }
3727 run_test 33d "openfile with 444 modes and malformed flags under remote dir"
3728
3729 test_33e() {
3730         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
3731
3732         mkdir $DIR/$tdir
3733
3734         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
3735         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
3736         mkdir $DIR/$tdir/local_dir
3737
3738         local s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
3739         local s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
3740         local l_mode=$(stat -c%f $DIR/$tdir/local_dir)
3741
3742         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
3743                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode"
3744
3745         rmdir $DIR/$tdir/* || error "rmdir failed"
3746
3747         umask 777
3748         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
3749         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
3750         mkdir $DIR/$tdir/local_dir
3751
3752         s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
3753         s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
3754         l_mode=$(stat -c%f $DIR/$tdir/local_dir)
3755
3756         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
3757                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode 777"
3758
3759         rmdir $DIR/$tdir/* || error "rmdir(umask 777) failed"
3760
3761         umask 000
3762         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
3763         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
3764         mkdir $DIR/$tdir/local_dir
3765
3766         s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
3767         s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
3768         l_mode=$(stat -c%f $DIR/$tdir/local_dir)
3769
3770         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
3771                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode 0"
3772 }
3773 run_test 33e "mkdir and striped directory should have same mode"
3774
3775 cleanup_33f() {
3776         trap 0
3777         do_facet $SINGLEMDS $LCTL set_param mdt.*.enable_remote_dir_gid=0
3778 }
3779
3780 test_33f() {
3781         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
3782         remote_mds_nodsh && skip "remote MDS with nodsh"
3783
3784         mkdir $DIR/$tdir
3785         chmod go+rwx $DIR/$tdir
3786         do_facet $SINGLEMDS $LCTL set_param mdt.*.enable_remote_dir_gid=-1
3787         trap cleanup_33f EXIT
3788
3789         $RUNAS lfs mkdir -i 0 -c$MDSCOUNT $DIR/$tdir/striped_dir ||
3790                 error "cannot create striped directory"
3791
3792         $RUNAS touch $DIR/$tdir/striped_dir/{0..16} ||
3793                 error "cannot create files in striped directory"
3794
3795         $RUNAS rm $DIR/$tdir/striped_dir/{0..16} ||
3796                 error "cannot remove files in striped directory"
3797
3798         $RUNAS rmdir $DIR/$tdir/striped_dir ||
3799                 error "cannot remove striped directory"
3800
3801         cleanup_33f
3802 }
3803 run_test 33f "nonroot user can create, access, and remove a striped directory"
3804
3805 test_33g() {
3806         mkdir -p $DIR/$tdir/dir2
3807
3808         local err=$($RUNAS mkdir $DIR/$tdir/dir2 2>&1)
3809         echo $err
3810         [[ $err =~ "exists" ]] || error "Not exists error"
3811 }
3812 run_test 33g "nonroot user create already existing root created file"
3813
3814 test_33h() {
3815         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
3816         [ $MDS1_VERSION -lt $(version_code 2.13.50) ] &&
3817                 skip "Need MDS version at least 2.13.50"
3818
3819         test_mkdir -c $MDSCOUNT -H crush $DIR/$tdir ||
3820                 error "mkdir $tdir failed"
3821         touch $DIR/$tdir/$tfile || error "touch $tfile failed"
3822
3823         local index=$($LFS getstripe -m $DIR/$tdir/$tfile)
3824         local index2
3825
3826         for fname in $DIR/$tdir/$tfile.bak \
3827                      $DIR/$tdir/$tfile.SAV \
3828                      $DIR/$tdir/$tfile.orig \
3829                      $DIR/$tdir/$tfile~; do
3830                 touch $fname  || error "touch $fname failed"
3831                 index2=$($LFS getstripe -m $fname)
3832                 [ $index -eq $index2 ] ||
3833                         error "$fname MDT index mismatch $index != $index2"
3834         done
3835
3836         local failed=0
3837         for i in {1..250}; do
3838                 for fname in $(mktemp -u $DIR/$tdir/.$tfile.XXXXXX) \
3839                              $(mktemp $DIR/$tdir/$tfile.XXXXXXXX); do
3840                         touch $fname  || error "touch $fname failed"
3841                         index2=$($LFS getstripe -m $fname)
3842                         if [[ $index != $index2 ]]; then
3843                                 failed=$((failed + 1))
3844                                 echo "$fname MDT index mismatch $index != $index2"
3845                         fi
3846                 done
3847         done
3848         echo "$failed MDT index mismatches"
3849         (( failed < 20 )) || error "MDT index mismatch $failed times"
3850
3851 }
3852 run_test 33h "temp file is located on the same MDT as target"
3853
3854 TEST_34_SIZE=${TEST_34_SIZE:-2000000000000}
3855 test_34a() {
3856         rm -f $DIR/f34
3857         $MCREATE $DIR/f34 || error "mcreate failed"
3858         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
3859                 error "getstripe failed"
3860         $TRUNCATE $DIR/f34 $TEST_34_SIZE || error "truncate failed"
3861         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
3862                 error "getstripe failed"
3863         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
3864                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
3865 }
3866 run_test 34a "truncate file that has not been opened ==========="
3867
3868 test_34b() {
3869         [ ! -f $DIR/f34 ] && test_34a
3870         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
3871                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
3872         $OPENFILE -f O_RDONLY $DIR/f34
3873         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
3874                 error "getstripe failed"
3875         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
3876                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
3877 }
3878 run_test 34b "O_RDONLY opening file doesn't create objects ====="
3879
3880 test_34c() {
3881         [ ! -f $DIR/f34 ] && test_34a
3882         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
3883                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
3884         $OPENFILE -f O_RDWR $DIR/f34
3885         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" &&
3886                 error "$LFS getstripe failed"
3887         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
3888                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
3889 }
3890 run_test 34c "O_RDWR opening file-with-size works =============="
3891
3892 test_34d() {
3893         [ ! -f $DIR/f34 ] && test_34a
3894         dd if=/dev/zero of=$DIR/f34 conv=notrunc bs=4k count=1 ||
3895                 error "dd failed"
3896         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
3897                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
3898         rm $DIR/f34
3899 }
3900 run_test 34d "write to sparse file ============================="
3901
3902 test_34e() {
3903         rm -f $DIR/f34e
3904         $MCREATE $DIR/f34e || error "mcreate failed"
3905         $TRUNCATE $DIR/f34e 1000 || error "truncate failed"
3906         $CHECKSTAT -s 1000 $DIR/f34e ||
3907                 error "Size of $DIR/f34e not equal to 1000 bytes"
3908         $OPENFILE -f O_RDWR $DIR/f34e
3909         $CHECKSTAT -s 1000 $DIR/f34e ||
3910                 error "Size of $DIR/f34e not equal to 1000 bytes"
3911 }
3912 run_test 34e "create objects, some with size and some without =="
3913
3914 test_34f() { # bug 6242, 6243
3915         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3916
3917         SIZE34F=48000
3918         rm -f $DIR/f34f
3919         $MCREATE $DIR/f34f || error "mcreate failed"
3920         $TRUNCATE $DIR/f34f $SIZE34F || error "truncating $DIR/f3f to $SIZE34F"
3921         dd if=$DIR/f34f of=$TMP/f34f
3922         $CHECKSTAT -s $SIZE34F $TMP/f34f || error "$TMP/f34f not $SIZE34F bytes"
3923         dd if=/dev/zero of=$TMP/f34fzero bs=$SIZE34F count=1
3924         cmp $DIR/f34f $TMP/f34fzero || error "$DIR/f34f not all zero"
3925         cmp $TMP/f34f $TMP/f34fzero || error "$TMP/f34f not all zero"
3926         rm $TMP/f34f $TMP/f34fzero $DIR/f34f
3927 }
3928 run_test 34f "read from a file with no objects until EOF ======="
3929
3930 test_34g() {
3931         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3932
3933         dd if=/dev/zero of=$DIR/$tfile bs=1 count=100 seek=$TEST_34_SIZE ||
3934                 error "dd failed"
3935         $TRUNCATE $DIR/$tfile $((TEST_34_SIZE / 2))|| error "truncate failed"
3936         $CHECKSTAT -s $((TEST_34_SIZE / 2)) $DIR/$tfile ||
3937                 error "Size of $DIR/$tfile not equal to $((TEST_34_SIZE / 2))"
3938         cancel_lru_locks osc
3939         $CHECKSTAT -s $((TEST_34_SIZE / 2)) $DIR/$tfile ||
3940                 error "wrong size after lock cancel"
3941
3942         $TRUNCATE $DIR/$tfile $TEST_34_SIZE || error "truncate failed"
3943         $CHECKSTAT -s $TEST_34_SIZE $DIR/$tfile ||
3944                 error "expanding truncate failed"
3945         cancel_lru_locks osc
3946         $CHECKSTAT -s $TEST_34_SIZE $DIR/$tfile ||
3947                 error "wrong expanded size after lock cancel"
3948 }
3949 run_test 34g "truncate long file ==============================="
3950
3951 test_34h() {
3952         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3953
3954         local gid=10
3955         local sz=1000
3956
3957         dd if=/dev/zero of=$DIR/$tfile bs=1M count=10 || error "dd failed"
3958         sync # Flush the cache so that multiop below does not block on cache
3959              # flush when getting the group lock
3960         $MULTIOP $DIR/$tfile OG${gid}T${sz}g${gid}c &
3961         MULTIPID=$!
3962
3963         # Since just timed wait is not good enough, let's do a sync write
3964         # that way we are sure enough time for a roundtrip + processing
3965         # passed + 2 seconds of extra margin.
3966         dd if=/dev/zero of=$DIR/${tfile}-1 bs=$PAGE_SIZE oflag=direct count=1
3967         rm $DIR/${tfile}-1
3968         sleep 2
3969
3970         if [[ `ps h -o comm -p $MULTIPID` == "multiop" ]]; then
3971                 error "Multiop blocked on ftruncate, pid=$MULTIPID"
3972                 kill -9 $MULTIPID
3973         fi
3974         wait $MULTIPID
3975         local nsz=`stat -c %s $DIR/$tfile`
3976         [[ $nsz == $sz ]] || error "New size wrong $nsz != $sz"
3977 }
3978 run_test 34h "ftruncate file under grouplock should not block"
3979
3980 test_35a() {
3981         cp /bin/sh $DIR/f35a
3982         chmod 444 $DIR/f35a
3983         chown $RUNAS_ID $DIR/f35a
3984         $RUNAS $DIR/f35a && error || true
3985         rm $DIR/f35a
3986 }
3987 run_test 35a "exec file with mode 444 (should return and not leak)"
3988
3989 test_36a() {
3990         rm -f $DIR/f36
3991         utime $DIR/f36 || error "utime failed for MDS"
3992 }
3993 run_test 36a "MDS utime check (mknod, utime)"
3994
3995 test_36b() {
3996         echo "" > $DIR/f36
3997         utime $DIR/f36 || error "utime failed for OST"
3998 }
3999 run_test 36b "OST utime check (open, utime)"
4000
4001 test_36c() {
4002         rm -f $DIR/d36/f36
4003         test_mkdir $DIR/d36
4004         chown $RUNAS_ID $DIR/d36
4005         $RUNAS utime $DIR/d36/f36 || error "utime failed for MDS as non-root"
4006 }
4007 run_test 36c "non-root MDS utime check (mknod, utime)"
4008
4009 test_36d() {
4010         [ ! -d $DIR/d36 ] && test_36c
4011         echo "" > $DIR/d36/f36
4012         $RUNAS utime $DIR/d36/f36 || error "utime failed for OST as non-root"
4013 }
4014 run_test 36d "non-root OST utime check (open, utime)"
4015
4016 test_36e() {
4017         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID -- skipping"
4018
4019         test_mkdir $DIR/$tdir
4020         touch $DIR/$tdir/$tfile
4021         $RUNAS utime $DIR/$tdir/$tfile &&
4022                 error "utime worked, expected failure" || true
4023 }
4024 run_test 36e "utime on non-owned file (should return error)"
4025
4026 subr_36fh() {
4027         local fl="$1"
4028         local LANG_SAVE=$LANG
4029         local LC_LANG_SAVE=$LC_LANG
4030         export LANG=C LC_LANG=C # for date language
4031
4032         DATESTR="Dec 20  2000"
4033         test_mkdir $DIR/$tdir
4034         lctl set_param fail_loc=$fl
4035         date; date +%s
4036         cp /etc/hosts $DIR/$tdir/$tfile
4037         sync & # write RPC generated with "current" inode timestamp, but delayed
4038         sleep 1
4039         touch --date="$DATESTR" $DIR/$tdir/$tfile # setattr timestamp in past
4040         LS_BEFORE="`ls -l $DIR/$tdir/$tfile`" # old timestamp from client cache
4041         cancel_lru_locks $OSC
4042         LS_AFTER="`ls -l $DIR/$tdir/$tfile`"  # timestamp from OST object
4043         date; date +%s
4044         [ "$LS_BEFORE" != "$LS_AFTER" ] && \
4045                 echo "BEFORE: $LS_BEFORE" && \
4046                 echo "AFTER : $LS_AFTER" && \
4047                 echo "WANT  : $DATESTR" && \
4048                 error "$DIR/$tdir/$tfile timestamps changed" || true
4049
4050         export LANG=$LANG_SAVE LC_LANG=$LC_LANG_SAVE
4051 }
4052
4053 test_36f() {
4054         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4055
4056         #define OBD_FAIL_OST_BRW_PAUSE_BULK 0x214
4057         subr_36fh "0x80000214"
4058 }
4059 run_test 36f "utime on file racing with OST BRW write =========="
4060
4061 test_36g() {
4062         remote_ost_nodsh && skip "remote OST with nodsh"
4063         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4064         [ $MDS1_VERSION -lt $(version_code 2.12.51) ] &&
4065                 skip "Need MDS version at least 2.12.51"
4066
4067         local fmd_max_age
4068         local fmd
4069         local facet="ost1"
4070         local tgt="obdfilter"
4071
4072         [[ $OSC == "mdc" ]] && tgt="mdt" && facet="mds1"
4073
4074         test_mkdir $DIR/$tdir
4075         fmd_max_age=$(do_facet $facet \
4076                 "lctl get_param -n $tgt.*.tgt_fmd_seconds 2> /dev/null | \
4077                 head -n 1")
4078
4079         echo "FMD max age: ${fmd_max_age}s"
4080         touch $DIR/$tdir/$tfile
4081         fmd=$(do_facet $facet "lctl get_param -n $tgt.*.exports.*.fmd_count" |
4082                 gawk '{cnt=cnt+$1}  END{print cnt}')
4083         echo "FMD before: $fmd"
4084         [[ $fmd == 0 ]] &&
4085                 error "FMD wasn't create by touch"
4086         sleep $((fmd_max_age + 12))
4087         fmd=$(do_facet $facet "lctl get_param -n $tgt.*.exports.*.fmd_count" |
4088                 gawk '{cnt=cnt+$1}  END{print cnt}')
4089         echo "FMD after: $fmd"
4090         [[ $fmd == 0 ]] ||
4091                 error "FMD wasn't expired by ping"
4092 }
4093 run_test 36g "FMD cache expiry ====================="
4094
4095 test_36h() {
4096         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4097
4098         #define OBD_FAIL_OST_BRW_PAUSE_BULK2 0x227
4099         subr_36fh "0x80000227"
4100 }
4101 run_test 36h "utime on file racing with OST BRW write =========="
4102
4103 test_36i() {
4104         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
4105
4106         test_mkdir $DIR/$tdir
4107         $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir
4108
4109         local mtime=$(stat -c%Y $DIR/$tdir/striped_dir)
4110         local new_mtime=$((mtime + 200))
4111
4112         #change Modify time of striped dir
4113         touch -m -d @$new_mtime $DIR/$tdir/striped_dir ||
4114                         error "change mtime failed"
4115
4116         local got=$(stat -c%Y $DIR/$tdir/striped_dir)
4117
4118         [ "$new_mtime" = "$got" ] || error "expect $new_mtime got $got"
4119 }
4120 run_test 36i "change mtime on striped directory"
4121
4122 # test_37 - duplicate with tests 32q 32r
4123
4124 test_38() {
4125         local file=$DIR/$tfile
4126         touch $file
4127         openfile -f O_DIRECTORY $file
4128         local RC=$?
4129         local ENOTDIR=20
4130         [ $RC -eq 0 ] && error "opened file $file with O_DIRECTORY" || true
4131         [ $RC -eq $ENOTDIR ] || error "error $RC should be ENOTDIR ($ENOTDIR)"
4132 }
4133 run_test 38 "open a regular file with O_DIRECTORY should return -ENOTDIR ==="
4134
4135 test_39a() { # was test_39
4136         touch $DIR/$tfile
4137         touch $DIR/${tfile}2
4138 #       ls -l  $DIR/$tfile $DIR/${tfile}2
4139 #       ls -lu  $DIR/$tfile $DIR/${tfile}2
4140 #       ls -lc  $DIR/$tfile $DIR/${tfile}2
4141         sleep 2
4142         $OPENFILE -f O_CREAT:O_TRUNC:O_WRONLY $DIR/${tfile}2
4143         if [ ! $DIR/${tfile}2 -nt $DIR/$tfile ]; then
4144                 echo "mtime"
4145                 ls -l --full-time $DIR/$tfile $DIR/${tfile}2
4146                 echo "atime"
4147                 ls -lu --full-time $DIR/$tfile $DIR/${tfile}2
4148                 echo "ctime"
4149                 ls -lc --full-time $DIR/$tfile $DIR/${tfile}2
4150                 error "O_TRUNC didn't change timestamps"
4151         fi
4152 }
4153 run_test 39a "mtime changed on create"
4154
4155 test_39b() {
4156         test_mkdir -c1 $DIR/$tdir
4157         cp -p /etc/passwd $DIR/$tdir/fopen
4158         cp -p /etc/passwd $DIR/$tdir/flink
4159         cp -p /etc/passwd $DIR/$tdir/funlink
4160         cp -p /etc/passwd $DIR/$tdir/frename
4161         ln $DIR/$tdir/funlink $DIR/$tdir/funlink2
4162
4163         sleep 1
4164         echo "aaaaaa" >> $DIR/$tdir/fopen
4165         echo "aaaaaa" >> $DIR/$tdir/flink
4166         echo "aaaaaa" >> $DIR/$tdir/funlink
4167         echo "aaaaaa" >> $DIR/$tdir/frename
4168
4169         local open_new=`stat -c %Y $DIR/$tdir/fopen`
4170         local link_new=`stat -c %Y $DIR/$tdir/flink`
4171         local unlink_new=`stat -c %Y $DIR/$tdir/funlink`
4172         local rename_new=`stat -c %Y $DIR/$tdir/frename`
4173
4174         cat $DIR/$tdir/fopen > /dev/null
4175         ln $DIR/$tdir/flink $DIR/$tdir/flink2
4176         rm -f $DIR/$tdir/funlink2
4177         mv -f $DIR/$tdir/frename $DIR/$tdir/frename2
4178
4179         for (( i=0; i < 2; i++ )) ; do
4180                 local open_new2=`stat -c %Y $DIR/$tdir/fopen`
4181                 local link_new2=`stat -c %Y $DIR/$tdir/flink`
4182                 local unlink_new2=`stat -c %Y $DIR/$tdir/funlink`
4183                 local rename_new2=`stat -c %Y $DIR/$tdir/frename2`
4184
4185                 [ $open_new2 -eq $open_new ] || error "open file reverses mtime"
4186                 [ $link_new2 -eq $link_new ] || error "link file reverses mtime"
4187                 [ $unlink_new2 -eq $unlink_new ] || error "unlink file reverses mtime"
4188                 [ $rename_new2 -eq $rename_new ] || error "rename file reverses mtime"
4189
4190                 cancel_lru_locks $OSC
4191                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4192         done
4193 }
4194 run_test 39b "mtime change on open, link, unlink, rename  ======"
4195
4196 # this should be set to past
4197 TEST_39_MTIME=`date -d "1 year ago" +%s`
4198
4199 # bug 11063
4200 test_39c() {
4201         touch $DIR1/$tfile
4202         sleep 2
4203         local mtime0=`stat -c %Y $DIR1/$tfile`
4204
4205         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4206         local mtime1=`stat -c %Y $DIR1/$tfile`
4207         [ "$mtime1" = $TEST_39_MTIME ] || \
4208                 error "mtime is not set to past: $mtime1, should be $TEST_39_MTIME"
4209
4210         local d1=`date +%s`
4211         echo hello >> $DIR1/$tfile
4212         local d2=`date +%s`
4213         local mtime2=`stat -c %Y $DIR1/$tfile`
4214         [ "$mtime2" -ge "$d1" ] && [ "$mtime2" -le "$d2" ] || \
4215                 error "mtime is not updated on write: $d1 <= $mtime2 <= $d2"
4216
4217         mv $DIR1/$tfile $DIR1/$tfile-1
4218
4219         for (( i=0; i < 2; i++ )) ; do
4220                 local mtime3=`stat -c %Y $DIR1/$tfile-1`
4221                 [ "$mtime2" = "$mtime3" ] || \
4222                         error "mtime ($mtime2) changed (to $mtime3) on rename"
4223
4224                 cancel_lru_locks $OSC
4225                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4226         done
4227 }
4228 run_test 39c "mtime change on rename ==========================="
4229
4230 # bug 21114
4231 test_39d() {
4232         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4233
4234         touch $DIR1/$tfile
4235         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4236
4237         for (( i=0; i < 2; i++ )) ; do
4238                 local mtime=`stat -c %Y $DIR1/$tfile`
4239                 [ $mtime = $TEST_39_MTIME ] || \
4240                         error "mtime($mtime) is not set to $TEST_39_MTIME"
4241
4242                 cancel_lru_locks $OSC
4243                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4244         done
4245 }
4246 run_test 39d "create, utime, stat =============================="
4247
4248 # bug 21114
4249 test_39e() {
4250         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4251
4252         touch $DIR1/$tfile
4253         local mtime1=`stat -c %Y $DIR1/$tfile`
4254
4255         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4256
4257         for (( i=0; i < 2; i++ )) ; do
4258                 local mtime2=`stat -c %Y $DIR1/$tfile`
4259                 [ $mtime2 = $TEST_39_MTIME ] || \
4260                         error "mtime($mtime2) is not set to $TEST_39_MTIME"
4261
4262                 cancel_lru_locks $OSC
4263                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4264         done
4265 }
4266 run_test 39e "create, stat, utime, stat ========================"
4267
4268 # bug 21114
4269 test_39f() {
4270         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4271
4272         touch $DIR1/$tfile
4273         mtime1=`stat -c %Y $DIR1/$tfile`
4274
4275         sleep 2
4276         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4277
4278         for (( i=0; i < 2; i++ )) ; do
4279                 local mtime2=`stat -c %Y $DIR1/$tfile`
4280                 [ $mtime2 = $TEST_39_MTIME ] || \
4281                         error "mtime($mtime2) is not set to $TEST_39_MTIME"
4282
4283                 cancel_lru_locks $OSC
4284                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4285         done
4286 }
4287 run_test 39f "create, stat, sleep, utime, stat ================="
4288
4289 # bug 11063
4290 test_39g() {
4291         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4292
4293         echo hello >> $DIR1/$tfile
4294         local mtime1=`stat -c %Y $DIR1/$tfile`
4295
4296         sleep 2
4297         chmod o+r $DIR1/$tfile
4298
4299         for (( i=0; i < 2; i++ )) ; do
4300                 local mtime2=`stat -c %Y $DIR1/$tfile`
4301                 [ "$mtime1" = "$mtime2" ] || \
4302                         error "lost mtime: $mtime2, should be $mtime1"
4303
4304                 cancel_lru_locks $OSC
4305                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4306         done
4307 }
4308 run_test 39g "write, chmod, stat ==============================="
4309
4310 # bug 11063
4311 test_39h() {
4312         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4313
4314         touch $DIR1/$tfile
4315         sleep 1
4316
4317         local d1=`date`
4318         echo hello >> $DIR1/$tfile
4319         local mtime1=`stat -c %Y $DIR1/$tfile`
4320
4321         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4322         local d2=`date`
4323         if [ "$d1" != "$d2" ]; then
4324                 echo "write and touch not within one second"
4325         else
4326                 for (( i=0; i < 2; i++ )) ; do
4327                         local mtime2=`stat -c %Y $DIR1/$tfile`
4328                         [ "$mtime2" = $TEST_39_MTIME ] || \
4329                                 error "lost mtime: $mtime2, should be $TEST_39_MTIME"
4330
4331                         cancel_lru_locks $OSC
4332                         if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4333                 done
4334         fi
4335 }
4336 run_test 39h "write, utime within one second, stat ============="
4337
4338 test_39i() {
4339         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4340
4341         touch $DIR1/$tfile
4342         sleep 1
4343
4344         echo hello >> $DIR1/$tfile
4345         local mtime1=`stat -c %Y $DIR1/$tfile`
4346
4347         mv $DIR1/$tfile $DIR1/$tfile-1
4348
4349         for (( i=0; i < 2; i++ )) ; do
4350                 local mtime2=`stat -c %Y $DIR1/$tfile-1`
4351
4352                 [ "$mtime1" = "$mtime2" ] || \
4353                         error "lost mtime: $mtime2, should be $mtime1"
4354
4355                 cancel_lru_locks $OSC
4356                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4357         done
4358 }
4359 run_test 39i "write, rename, stat =============================="
4360
4361 test_39j() {
4362         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4363
4364         start_full_debug_logging
4365         touch $DIR1/$tfile
4366         sleep 1
4367
4368         #define OBD_FAIL_OSC_DELAY_SETTIME       0x412
4369         lctl set_param fail_loc=0x80000412
4370         multiop_bg_pause $DIR1/$tfile oO_RDWR:w2097152_c ||
4371                 error "multiop failed"
4372         local multipid=$!
4373         local mtime1=`stat -c %Y $DIR1/$tfile`
4374
4375         mv $DIR1/$tfile $DIR1/$tfile-1
4376
4377         kill -USR1 $multipid
4378         wait $multipid || error "multiop close failed"
4379
4380         for (( i=0; i < 2; i++ )) ; do
4381                 local mtime2=`stat -c %Y $DIR1/$tfile-1`
4382                 [ "$mtime1" = "$mtime2" ] ||
4383                         error "mtime is lost on close: $mtime2, " \
4384                               "should be $mtime1"
4385
4386                 cancel_lru_locks
4387                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4388         done
4389         lctl set_param fail_loc=0
4390         stop_full_debug_logging
4391 }
4392 run_test 39j "write, rename, close, stat ======================="
4393
4394 test_39k() {
4395         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4396
4397         touch $DIR1/$tfile
4398         sleep 1
4399
4400         multiop_bg_pause $DIR1/$tfile oO_RDWR:w2097152_c || error "multiop failed"
4401         local multipid=$!
4402         local mtime1=`stat -c %Y $DIR1/$tfile`
4403
4404         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4405
4406         kill -USR1 $multipid
4407         wait $multipid || error "multiop close failed"
4408
4409         for (( i=0; i < 2; i++ )) ; do
4410                 local mtime2=`stat -c %Y $DIR1/$tfile`
4411
4412                 [ "$mtime2" = $TEST_39_MTIME ] || \
4413                         error "mtime is lost on close: $mtime2, should be $TEST_39_MTIME"
4414
4415                 cancel_lru_locks
4416                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4417         done
4418 }
4419 run_test 39k "write, utime, close, stat ========================"
4420
4421 # this should be set to future
4422 TEST_39_ATIME=`date -d "1 year" +%s`
4423
4424 test_39l() {
4425         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4426         remote_mds_nodsh && skip "remote MDS with nodsh"
4427
4428         local atime_diff=$(do_facet $SINGLEMDS \
4429                                 lctl get_param -n mdd.*MDT0000*.atime_diff)
4430         rm -rf $DIR/$tdir
4431         mkdir -p $DIR/$tdir
4432
4433         # test setting directory atime to future
4434         touch -a -d @$TEST_39_ATIME $DIR/$tdir
4435         local atime=$(stat -c %X $DIR/$tdir)
4436         [ "$atime" = $TEST_39_ATIME ] ||
4437                 error "atime is not set to future: $atime, $TEST_39_ATIME"
4438
4439         # test setting directory atime from future to now
4440         local now=$(date +%s)
4441         touch -a -d @$now $DIR/$tdir
4442
4443         atime=$(stat -c %X $DIR/$tdir)
4444         [ "$atime" -eq "$now"  ] ||
4445                 error "atime is not updated from future: $atime, $now"
4446
4447         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=2
4448         sleep 3
4449
4450         # test setting directory atime when now > dir atime + atime_diff
4451         local d1=$(date +%s)
4452         ls $DIR/$tdir
4453         local d2=$(date +%s)
4454         cancel_lru_locks mdc
4455         atime=$(stat -c %X $DIR/$tdir)
4456         [ "$atime" -ge "$d1" -a "$atime" -le "$d2" ] ||
4457                 error "atime is not updated  : $atime, should be $d2"
4458
4459         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=60
4460         sleep 3
4461
4462         # test not setting directory atime when now < dir atime + atime_diff
4463         ls $DIR/$tdir
4464         cancel_lru_locks mdc
4465         atime=$(stat -c %X $DIR/$tdir)
4466         [ "$atime" -ge "$d1" -a "$atime" -le "$d2" ] ||
4467                 error "atime is updated to $atime, should remain $d1<atime<$d2"
4468
4469         do_facet $SINGLEMDS \
4470                 lctl set_param -n mdd.*MDT0000*.atime_diff=$atime_diff
4471 }
4472 run_test 39l "directory atime update ==========================="
4473
4474 test_39m() {
4475         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4476
4477         touch $DIR1/$tfile
4478         sleep 2
4479         local far_past_mtime=$(date -d "May 29 1953" +%s)
4480         local far_past_atime=$(date -d "Dec 17 1903" +%s)
4481
4482         touch -m -d @$far_past_mtime $DIR1/$tfile
4483         touch -a -d @$far_past_atime $DIR1/$tfile
4484
4485         for (( i=0; i < 2; i++ )) ; do
4486                 local timestamps=$(stat -c "%X %Y" $DIR1/$tfile)
4487                 [ "$timestamps" = "$far_past_atime $far_past_mtime" ] || \
4488                         error "atime or mtime set incorrectly"
4489
4490                 cancel_lru_locks $OSC
4491                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4492         done
4493 }
4494 run_test 39m "test atime and mtime before 1970"
4495
4496 test_39n() { # LU-3832
4497         remote_mds_nodsh && skip "remote MDS with nodsh"
4498
4499         local atime_diff=$(do_facet $SINGLEMDS \
4500                 lctl get_param -n mdd.*MDT0000*.atime_diff)
4501         local atime0
4502         local atime1
4503         local atime2
4504
4505         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=1
4506
4507         rm -rf $DIR/$tfile
4508         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 status=noxfer
4509         atime0=$(stat -c %X $DIR/$tfile)
4510
4511         sleep 5
4512         $MULTIOP $DIR/$tfile oO_RDONLY:O_NOATIME:r4096c
4513         atime1=$(stat -c %X $DIR/$tfile)
4514
4515         sleep 5
4516         cancel_lru_locks mdc
4517         cancel_lru_locks osc
4518         $MULTIOP $DIR/$tfile oO_RDONLY:O_NOATIME:r4096c
4519         atime2=$(stat -c %X $DIR/$tfile)
4520
4521         do_facet $SINGLEMDS \
4522                 lctl set_param -n mdd.*MDT0000*.atime_diff=$atime_diff
4523
4524         [ "$atime0" -eq "$atime1" ] || error "atime0 $atime0 != atime1 $atime1"
4525         [ "$atime1" -eq "$atime2" ] || error "atime0 $atime0 != atime1 $atime1"
4526 }
4527 run_test 39n "check that O_NOATIME is honored"
4528
4529 test_39o() {
4530         TESTDIR=$DIR/$tdir/$tfile
4531         [ -e $TESTDIR ] && rm -rf $TESTDIR
4532         mkdir -p $TESTDIR
4533         cd $TESTDIR
4534         links1=2
4535         ls
4536         mkdir a b
4537         ls
4538         links2=$(stat -c %h .)
4539         [ $(($links1 + 2)) != $links2 ] &&
4540                 error "wrong links count $(($links1 + 2)) != $links2"
4541         rmdir b
4542         links3=$(stat -c %h .)
4543         [ $(($links1 + 1)) != $links3 ] &&
4544                 error "wrong links count $links1 != $links3"
4545         return 0
4546 }
4547 run_test 39o "directory cached attributes updated after create"
4548
4549 test_39p() {
4550         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
4551
4552         local MDTIDX=1
4553         TESTDIR=$DIR/$tdir/$tdir
4554         [ -e $TESTDIR ] && rm -rf $TESTDIR
4555         test_mkdir -p $TESTDIR
4556         cd $TESTDIR
4557         links1=2
4558         ls
4559         test_mkdir -i $MDTIDX $TESTDIR/remote_dir1
4560         test_mkdir -i $MDTIDX $TESTDIR/remote_dir2
4561         ls
4562         links2=$(stat -c %h .)
4563         [ $(($links1 + 2)) != $links2 ] &&
4564                 error "wrong links count $(($links1 + 2)) != $links2"
4565         rmdir remote_dir2
4566         links3=$(stat -c %h .)
4567         [ $(($links1 + 1)) != $links3 ] &&
4568                 error "wrong links count $links1 != $links3"
4569         return 0
4570 }
4571 run_test 39p "remote directory cached attributes updated after create ========"
4572
4573 test_39r() {
4574         [ $OST1_VERSION -ge $(version_code 2.13.52) ] ||
4575                 skip "no atime update on old OST"
4576         if [ "$ost1_FSTYPE" != ldiskfs ]; then
4577                 skip_env "ldiskfs only test"
4578         fi
4579
4580         local saved_adiff
4581         saved_adiff=$(do_facet ost1 \
4582                 lctl get_param -n obdfilter.*OST0000.atime_diff)
4583         stack_trap "do_facet ost1 \
4584                 lctl set_param obdfilter.*.atime_diff=$saved_adiff"
4585
4586         do_facet ost1 "lctl set_param obdfilter.*.atime_diff=5"
4587
4588         $LFS setstripe -i 0 $DIR/$tfile
4589         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 ||
4590                 error "can't write initial file"
4591         cancel_lru_locks osc
4592
4593         # exceed atime_diff and access file
4594         sleep 6
4595         dd if=$DIR/$tfile of=/dev/null || error "can't udpate atime"
4596
4597         local atime_cli=$(stat -c %X $DIR/$tfile)
4598         echo "client atime: $atime_cli"
4599         # allow atime update to be written to device
4600         do_facet ost1 "$LCTL set_param -n osd*.*OST*.force_sync 1"
4601         sleep 5
4602
4603         local ostdev=$(ostdevname 1)
4604         local fid=($(lfs getstripe -y $DIR/$tfile |
4605                         awk '/l_fid:/ { print $2 }' | tr ':' ' '))
4606         local objpath="O/0/d$((${fid[1]} % 32))/$((${fid[1]}))"
4607         local cmd="debugfs -c -R \\\"stat $objpath\\\" $ostdev"
4608
4609         echo "OST atime: $(do_facet ost1 "$cmd" |& grep atime)"
4610         local atime_ost=$(do_facet ost1 "$cmd" |&
4611                           awk -F'[: ]' '/atime:/ { print $4 }')
4612         (( atime_cli == atime_ost )) ||
4613                 error "atime on client $atime_cli != ost $atime_ost"
4614 }
4615 run_test 39r "lazy atime update on OST"
4616
4617 test_39q() { # LU-8041
4618         local testdir=$DIR/$tdir
4619         mkdir -p $testdir
4620         multiop_bg_pause $testdir D_c || error "multiop failed"
4621         local multipid=$!
4622         cancel_lru_locks mdc
4623         kill -USR1 $multipid
4624         local atime=$(stat -c %X $testdir)
4625         [ "$atime" -ne 0 ] || error "atime is zero"
4626 }
4627 run_test 39q "close won't zero out atime"
4628
4629 test_40() {
4630         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1
4631         $RUNAS $OPENFILE -f O_WRONLY:O_TRUNC $DIR/$tfile &&
4632                 error "openfile O_WRONLY:O_TRUNC $tfile failed"
4633         $CHECKSTAT -t file -s 4096 $DIR/$tfile ||
4634                 error "$tfile is not 4096 bytes in size"
4635 }
4636 run_test 40 "failed open(O_TRUNC) doesn't truncate ============="
4637
4638 test_41() {
4639         # bug 1553
4640         small_write $DIR/f41 18
4641 }
4642 run_test 41 "test small file write + fstat ====================="
4643
4644 count_ost_writes() {
4645         lctl get_param -n ${OSC}.*.stats |
4646                 awk -vwrites=0 '/ost_write/ { writes += $2 } \
4647                         END { printf("%0.0f", writes) }'
4648 }
4649
4650 # decent default
4651 WRITEBACK_SAVE=500
4652 DIRTY_RATIO_SAVE=40
4653 MAX_DIRTY_RATIO=50
4654 BG_DIRTY_RATIO_SAVE=10
4655 MAX_BG_DIRTY_RATIO=25
4656
4657 start_writeback() {
4658         trap 0
4659         # in 2.6, restore /proc/sys/vm/dirty_writeback_centisecs,
4660         # dirty_ratio, dirty_background_ratio
4661         if [ -f /proc/sys/vm/dirty_writeback_centisecs ]; then
4662                 sysctl -w vm.dirty_writeback_centisecs=$WRITEBACK_SAVE
4663                 sysctl -w vm.dirty_background_ratio=$BG_DIRTY_RATIO_SAVE
4664                 sysctl -w vm.dirty_ratio=$DIRTY_RATIO_SAVE
4665         else
4666                 # if file not here, we are a 2.4 kernel
4667                 kill -CONT `pidof kupdated`
4668         fi
4669 }
4670
4671 stop_writeback() {
4672         # setup the trap first, so someone cannot exit the test at the
4673         # exact wrong time and mess up a machine
4674         trap start_writeback EXIT
4675         # in 2.6, save and 0 /proc/sys/vm/dirty_writeback_centisecs
4676         if [ -f /proc/sys/vm/dirty_writeback_centisecs ]; then
4677                 WRITEBACK_SAVE=`sysctl -n vm.dirty_writeback_centisecs`
4678                 sysctl -w vm.dirty_writeback_centisecs=0
4679                 sysctl -w vm.dirty_writeback_centisecs=0
4680                 # save and increase /proc/sys/vm/dirty_ratio
4681                 DIRTY_RATIO_SAVE=`sysctl -n vm.dirty_ratio`
4682                 sysctl -w vm.dirty_ratio=$MAX_DIRTY_RATIO
4683                 # save and increase /proc/sys/vm/dirty_background_ratio
4684                 BG_DIRTY_RATIO_SAVE=`sysctl -n vm.dirty_background_ratio`
4685                 sysctl -w vm.dirty_background_ratio=$MAX_BG_DIRTY_RATIO
4686         else
4687                 # if file not here, we are a 2.4 kernel
4688                 kill -STOP `pidof kupdated`
4689         fi
4690 }
4691
4692 # ensure that all stripes have some grant before we test client-side cache
4693 setup_test42() {
4694         for i in `seq -f $DIR/f42-%g 1 $OSTCOUNT`; do
4695                 dd if=/dev/zero of=$i bs=4k count=1
4696                 rm $i
4697         done
4698 }
4699
4700 # Tests 42* verify that our behaviour is correct WRT caching, file closure,
4701 # file truncation, and file removal.
4702 test_42a() {
4703         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4704
4705         setup_test42
4706         cancel_lru_locks $OSC
4707         stop_writeback
4708         sync; sleep 1; sync # just to be safe
4709         BEFOREWRITES=`count_ost_writes`
4710         lctl get_param -n osc.*[oO][sS][cC][_-]*.cur_grant_bytes | grep "[0-9]"
4711         dd if=/dev/zero of=$DIR/f42a bs=1024 count=100
4712         AFTERWRITES=`count_ost_writes`
4713         [ $BEFOREWRITES -eq $AFTERWRITES ] || \
4714                 error "$BEFOREWRITES < $AFTERWRITES"
4715         start_writeback
4716 }
4717 run_test 42a "ensure that we don't flush on close"
4718
4719 test_42b() {
4720         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4721
4722         setup_test42
4723         cancel_lru_locks $OSC
4724         stop_writeback
4725         sync
4726         dd if=/dev/zero of=$DIR/f42b bs=1024 count=100
4727         BEFOREWRITES=$(count_ost_writes)
4728         $MUNLINK $DIR/f42b || error "$MUNLINK $DIR/f42b: $?"
4729         AFTERWRITES=$(count_ost_writes)
4730         if [[ $BEFOREWRITES -lt $AFTERWRITES ]]; then
4731                 error "$BEFOREWRITES < $AFTERWRITES on unlink"
4732         fi
4733         BEFOREWRITES=$(count_ost_writes)
4734         sync || error "sync: $?"
4735         AFTERWRITES=$(count_ost_writes)
4736         if [[ $BEFOREWRITES -lt $AFTERWRITES ]]; then
4737                 error "$BEFOREWRITES < $AFTERWRITES on sync"
4738         fi
4739         dmesg | grep 'error from obd_brw_async' && error 'error writing back'
4740         start_writeback
4741         return 0
4742 }
4743 run_test 42b "test destroy of file with cached dirty data ======"
4744
4745 # if these tests just want to test the effect of truncation,
4746 # they have to be very careful.  consider:
4747 # - the first open gets a {0,EOF}PR lock
4748 # - the first write conflicts and gets a {0, count-1}PW
4749 # - the rest of the writes are under {count,EOF}PW
4750 # - the open for truncate tries to match a {0,EOF}PR
4751 #   for the filesize and cancels the PWs.
4752 # any number of fixes (don't get {0,EOF} on open, match
4753 # composite locks, do smarter file size management) fix
4754 # this, but for now we want these tests to verify that
4755 # the cancellation with truncate intent works, so we
4756 # start the file with a full-file pw lock to match against
4757 # until the truncate.
4758 trunc_test() {
4759         test=$1
4760         file=$DIR/$test
4761         offset=$2
4762         cancel_lru_locks $OSC
4763         stop_writeback
4764         # prime the file with 0,EOF PW to match
4765         touch $file
4766         $TRUNCATE $file 0
4767         sync; sync
4768         # now the real test..
4769         dd if=/dev/zero of=$file bs=1024 count=100
4770         BEFOREWRITES=`count_ost_writes`
4771         $TRUNCATE $file $offset
4772         cancel_lru_locks $OSC
4773         AFTERWRITES=`count_ost_writes`
4774         start_writeback
4775 }
4776
4777 test_42c() {
4778         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4779
4780         trunc_test 42c 1024
4781         [ $BEFOREWRITES -eq $AFTERWRITES ] &&
4782                 error "beforewrites $BEFOREWRITES == afterwrites $AFTERWRITES on truncate"
4783         rm $file
4784 }
4785 run_test 42c "test partial truncate of file with cached dirty data"
4786
4787 test_42d() {
4788         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4789
4790         trunc_test 42d 0
4791         [ $BEFOREWRITES -eq $AFTERWRITES ] ||
4792                 error "beforewrites $BEFOREWRITES != afterwrites $AFTERWRITES on truncate"
4793         rm $file
4794 }
4795 run_test 42d "test complete truncate of file with cached dirty data"
4796
4797 test_42e() { # bug22074
4798         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4799
4800         local TDIR=$DIR/${tdir}e
4801         local pages=16 # hardcoded 16 pages, don't change it.
4802         local files=$((OSTCOUNT * 500)) # hopefully 500 files on each OST
4803         local proc_osc0="osc.${FSNAME}-OST0000-osc-[^MDT]*"
4804         local max_dirty_mb
4805         local warmup_files
4806
4807         test_mkdir $DIR/${tdir}e
4808         $LFS setstripe -c 1 $TDIR
4809         createmany -o $TDIR/f $files
4810
4811         max_dirty_mb=$($LCTL get_param -n $proc_osc0/max_dirty_mb)
4812
4813         # we assume that with $OSTCOUNT files, at least one of them will
4814         # be allocated on OST0.
4815         warmup_files=$((OSTCOUNT * max_dirty_mb))
4816         createmany -o $TDIR/w $warmup_files
4817
4818         # write a large amount of data into one file and sync, to get good
4819         # avail_grant number from OST.
4820         for ((i=0; i<$warmup_files; i++)); do
4821                 idx=$($LFS getstripe -i $TDIR/w$i)
4822                 [ $idx -ne 0 ] && continue
4823                 dd if=/dev/zero of=$TDIR/w$i bs="$max_dirty_mb"M count=1
4824                 break
4825         done
4826         [[ $i -gt $warmup_files ]] && error "OST0 is still cold"
4827         sync
4828         $LCTL get_param $proc_osc0/cur_dirty_bytes
4829         $LCTL get_param $proc_osc0/cur_grant_bytes
4830
4831         # create as much dirty pages as we can while not to trigger the actual
4832         # RPCs directly. but depends on the env, VFS may trigger flush during this
4833         # period, hopefully we are good.
4834         for ((i=0; i<$warmup_files; i++)); do
4835                 idx=$($LFS getstripe -i $TDIR/w$i)
4836                 [ $idx -ne 0 ] && continue
4837                 dd if=/dev/zero of=$TDIR/w$i bs=1M count=1 2>/dev/null
4838         done
4839         $LCTL get_param $proc_osc0/cur_dirty_bytes
4840         $LCTL get_param $proc_osc0/cur_grant_bytes
4841
4842         # perform the real test
4843         $LCTL set_param $proc_osc0/rpc_stats 0
4844         for ((;i<$files; i++)); do
4845                 [ $($LFS getstripe -i $TDIR/f$i) -eq 0 ] || continue
4846                 dd if=/dev/zero of=$TDIR/f$i bs=$PAGE_SIZE count=$pages 2>/dev/null
4847         done
4848         sync
4849         $LCTL get_param $proc_osc0/rpc_stats
4850
4851         local percent=0
4852         local have_ppr=false
4853         $LCTL get_param $proc_osc0/rpc_stats |
4854                 while read PPR RRPC RPCT RCUM BAR WRPC WPCT WCUM; do
4855                         # skip lines until we are at the RPC histogram data
4856                         [ "$PPR" == "pages" ] && have_ppr=true && continue
4857                         $have_ppr || continue
4858
4859                         # we only want the percent stat for < 16 pages
4860                         [[ $(echo $PPR | tr -d ':') -ge $pages ]] && break
4861
4862                         percent=$((percent + WPCT))
4863                         if [[ $percent -gt 15 ]]; then
4864                                 error "less than 16-pages write RPCs" \
4865                                       "$percent% > 15%"
4866                                 break
4867                         fi
4868                 done
4869         rm -rf $TDIR
4870 }
4871 run_test 42e "verify sub-RPC writes are not done synchronously"
4872
4873 test_43A() { # was test_43
4874         test_mkdir $DIR/$tdir
4875         cp -p /bin/ls $DIR/$tdir/$tfile
4876         $MULTIOP $DIR/$tdir/$tfile Ow_c &
4877         pid=$!
4878         # give multiop a chance to open
4879         sleep 1
4880
4881         $DIR/$tdir/$tfile && error "execute $DIR/$tdir/$tfile succeeded" || true
4882         kill -USR1 $pid
4883 }
4884 run_test 43A "execution of file opened for write should return -ETXTBSY"
4885
4886 test_43a() {
4887         test_mkdir $DIR/$tdir
4888         cp -p $(which sleep) $DIR/$tdir/sleep || error "can't copy"
4889         $DIR/$tdir/sleep 60 &
4890         SLEEP_PID=$!
4891         # Make sure exec of $tdir/sleep wins race with truncate
4892         sleep 1
4893         $MULTIOP $DIR/$tdir/sleep Oc && error "expected error, got success"
4894         kill $SLEEP_PID
4895 }
4896 run_test 43a "open(RDWR) of file being executed should return -ETXTBSY"
4897
4898 test_43b() {
4899         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4900
4901         test_mkdir $DIR/$tdir
4902         cp -p $(which sleep) $DIR/$tdir/sleep || error "can't copy"
4903         $DIR/$tdir/sleep 60 &
4904         SLEEP_PID=$!
4905         # Make sure exec of $tdir/sleep wins race with truncate
4906         sleep 1
4907         $TRUNCATE $DIR/$tdir/sleep 0 && error "expected error, got success"
4908         kill $SLEEP_PID
4909 }
4910 run_test 43b "truncate of file being executed should return -ETXTBSY"
4911
4912 test_43c() {
4913         local testdir="$DIR/$tdir"
4914         test_mkdir $testdir
4915         cp $SHELL $testdir/
4916         ( cd $(dirname $SHELL) && md5sum $(basename $SHELL) ) |
4917                 ( cd $testdir && md5sum -c )
4918 }
4919 run_test 43c "md5sum of copy into lustre"
4920
4921 test_44A() { # was test_44
4922         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
4923
4924         dd if=/dev/zero of=$DIR/f1 bs=4k count=1 seek=1023
4925         dd if=$DIR/f1 bs=4k count=1 > /dev/null
4926 }
4927 run_test 44A "zero length read from a sparse stripe"
4928
4929 test_44a() {
4930         local nstripe=$($LCTL lov_getconfig $DIR | grep default_stripe_count: |
4931                 awk '{ print $2 }')
4932         [ -z "$nstripe" ] && skip "can't get stripe info"
4933         [[ $nstripe -gt $OSTCOUNT ]] &&
4934                 skip "Wrong default_stripe_count: $nstripe OSTCOUNT: $OSTCOUNT"
4935
4936         local stride=$($LCTL lov_getconfig $DIR | grep default_stripe_size: |
4937                 awk '{ print $2 }')
4938         if [[ $nstripe -eq 0 || $nstripe -eq -1 ]]; then
4939                 nstripe=$($LCTL lov_getconfig $DIR | grep obd_count: |
4940                         awk '{ print $2 }')
4941         fi
4942
4943         OFFSETS="0 $((stride/2)) $((stride-1))"
4944         for offset in $OFFSETS; do
4945                 for i in $(seq 0 $((nstripe-1))); do
4946                         local GLOBALOFFSETS=""
4947                         # size in Bytes
4948                         local size=$((((i + 2 * $nstripe )*$stride + $offset)))
4949                         local myfn=$DIR/d44a-$size
4950                         echo "--------writing $myfn at $size"
4951                         ll_sparseness_write $myfn $size ||
4952                                 error "ll_sparseness_write"
4953                         GLOBALOFFSETS="$GLOBALOFFSETS $size"
4954                         ll_sparseness_verify $myfn $GLOBALOFFSETS ||
4955                                 error "ll_sparseness_verify $GLOBALOFFSETS"
4956
4957                         for j in $(seq 0 $((nstripe-1))); do
4958                                 # size in Bytes
4959                                 size=$((((j + $nstripe )*$stride + $offset)))
4960                                 ll_sparseness_write $myfn $size ||
4961                                         error "ll_sparseness_write"
4962                                 GLOBALOFFSETS="$GLOBALOFFSETS $size"
4963                         done
4964                         ll_sparseness_verify $myfn $GLOBALOFFSETS ||
4965                                 error "ll_sparseness_verify $GLOBALOFFSETS"
4966                         rm -f $myfn
4967                 done
4968         done
4969 }
4970 run_test 44a "test sparse pwrite ==============================="
4971
4972 dirty_osc_total() {
4973         tot=0
4974         for d in `lctl get_param -n ${OSC}.*.cur_dirty_bytes`; do
4975                 tot=$(($tot + $d))
4976         done
4977         echo $tot
4978 }
4979 do_dirty_record() {
4980         before=`dirty_osc_total`
4981         echo executing "\"$*\""
4982         eval $*
4983         after=`dirty_osc_total`
4984         echo before $before, after $after
4985 }
4986 test_45() {
4987         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4988
4989         f="$DIR/f45"
4990         # Obtain grants from OST if it supports it
4991         echo blah > ${f}_grant
4992         stop_writeback
4993         sync
4994         do_dirty_record "echo blah > $f"
4995         [[ $before -eq $after ]] && error "write wasn't cached"
4996         do_dirty_record "> $f"
4997         [[ $before -gt $after ]] || error "truncate didn't lower dirty count"
4998         do_dirty_record "echo blah > $f"
4999         [[ $before -eq $after ]] && error "write wasn't cached"
5000         do_dirty_record "sync"
5001         [[ $before -gt $after ]] || error "writeback didn't lower dirty count"
5002         do_dirty_record "echo blah > $f"
5003         [[ $before -eq $after ]] && error "write wasn't cached"
5004         do_dirty_record "cancel_lru_locks osc"
5005         [[ $before -gt $after ]] ||
5006                 error "lock cancellation didn't lower dirty count"
5007         start_writeback
5008 }
5009 run_test 45 "osc io page accounting ============================"
5010
5011 # in a 2 stripe file (lov.sh), page 1023 maps to page 511 in its object.  this
5012 # test tickles a bug where re-dirtying a page was failing to be mapped to the
5013 # objects offset and an assert hit when an rpc was built with 1023's mapped
5014 # offset 511 and 511's raw 511 offset. it also found general redirtying bugs.
5015 test_46() {
5016         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5017
5018         f="$DIR/f46"
5019         stop_writeback
5020         sync
5021         dd if=/dev/zero of=$f bs=$PAGE_SIZE seek=511 count=1
5022         sync
5023         dd conv=notrunc if=/dev/zero of=$f bs=$PAGE_SIZE seek=1023 count=1
5024         dd conv=notrunc if=/dev/zero of=$f bs=$PAGE_SIZE seek=511 count=1
5025         sync
5026         start_writeback
5027 }
5028 run_test 46 "dirtying a previously written page ================"
5029
5030 # test_47 is removed "Device nodes check" is moved to test_28
5031
5032 test_48a() { # bug 2399
5033         [ "$mds1_FSTYPE" = "zfs" ] &&
5034         [ $MDS1_VERSION -lt $(version_code 2.3.63) ] &&
5035                 skip "MDS prior to 2.3.63 handle ZFS dir .. incorrectly"
5036
5037         test_mkdir $DIR/$tdir
5038         cd $DIR/$tdir
5039         mv $DIR/$tdir $DIR/$tdir.new || error "move directory failed"
5040         test_mkdir $DIR/$tdir
5041         touch foo || error "'touch foo' failed after recreating cwd"
5042         test_mkdir bar
5043         touch .foo || error "'touch .foo' failed after recreating cwd"
5044         test_mkdir .bar
5045         ls . > /dev/null || error "'ls .' failed after recreating cwd"
5046         ls .. > /dev/null || error "'ls ..' failed after removing cwd"
5047         cd . || error "'cd .' failed after recreating cwd"
5048         mkdir . && error "'mkdir .' worked after recreating cwd"
5049         rmdir . && error "'rmdir .' worked after recreating cwd"
5050         ln -s . baz || error "'ln -s .' failed after recreating cwd"
5051         cd .. || error "'cd ..' failed after recreating cwd"
5052 }
5053 run_test 48a "Access renamed working dir (should return errors)="
5054
5055 test_48b() { # bug 2399
5056         rm -rf $DIR/$tdir
5057         test_mkdir $DIR/$tdir
5058         cd $DIR/$tdir
5059         rmdir $DIR/$tdir || error "remove cwd $DIR/$tdir failed"
5060         touch foo && error "'touch foo' worked after removing cwd"
5061         mkdir foo && error "'mkdir foo' worked after removing cwd"
5062         touch .foo && error "'touch .foo' worked after removing cwd"
5063         mkdir .foo && error "'mkdir .foo' worked after removing cwd"
5064         ls . > /dev/null && error "'ls .' worked after removing cwd"
5065         ls .. > /dev/null || error "'ls ..' failed after removing cwd"
5066         mkdir . && error "'mkdir .' worked after removing cwd"
5067         rmdir . && error "'rmdir .' worked after removing cwd"
5068         ln -s . foo && error "'ln -s .' worked after removing cwd"
5069         cd .. || echo "'cd ..' failed after removing cwd `pwd`"  #bug 3517
5070 }
5071 run_test 48b "Access removed working dir (should return errors)="
5072
5073 test_48c() { # bug 2350
5074         #lctl set_param debug=-1
5075         #set -vx
5076         rm -rf $DIR/$tdir
5077         test_mkdir -p $DIR/$tdir/dir
5078         cd $DIR/$tdir/dir
5079         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
5080         $TRACE touch foo && error "touch foo worked after removing cwd"
5081         $TRACE mkdir foo && error "'mkdir foo' worked after removing cwd"
5082         touch .foo && error "touch .foo worked after removing cwd"
5083         mkdir .foo && error "mkdir .foo worked after removing cwd"
5084         $TRACE ls . && error "'ls .' worked after removing cwd"
5085         $TRACE ls .. || error "'ls ..' failed after removing cwd"
5086         $TRACE mkdir . && error "'mkdir .' worked after removing cwd"
5087         $TRACE rmdir . && error "'rmdir .' worked after removing cwd"
5088         $TRACE ln -s . foo && error "'ln -s .' worked after removing cwd"
5089         $TRACE cd .. || echo "'cd ..' failed after removing cwd `pwd`" #bug 3415
5090 }
5091 run_test 48c "Access removed working subdir (should return errors)"
5092
5093 test_48d() { # bug 2350
5094         #lctl set_param debug=-1
5095         #set -vx
5096         rm -rf $DIR/$tdir
5097         test_mkdir -p $DIR/$tdir/dir
5098         cd $DIR/$tdir/dir
5099         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
5100         $TRACE rmdir $DIR/$tdir || error "remove parent $DIR/$tdir failed"
5101         $TRACE touch foo && error "'touch foo' worked after removing parent"
5102         $TRACE mkdir foo && error "mkdir foo worked after removing parent"
5103         touch .foo && error "'touch .foo' worked after removing parent"
5104         mkdir .foo && error "mkdir .foo worked after removing parent"
5105         $TRACE ls . && error "'ls .' worked after removing parent"
5106         $TRACE ls .. && error "'ls ..' worked after removing parent"
5107         $TRACE mkdir . && error "'mkdir .' worked after removing parent"
5108         $TRACE rmdir . && error "'rmdir .' worked after removing parent"
5109         $TRACE ln -s . foo && error "'ln -s .' worked after removing parent"
5110         true
5111 }
5112 run_test 48d "Access removed parent subdir (should return errors)"
5113
5114 test_48e() { # bug 4134
5115         #lctl set_param debug=-1
5116         #set -vx
5117         rm -rf $DIR/$tdir
5118         test_mkdir -p $DIR/$tdir/dir
5119         cd $DIR/$tdir/dir
5120         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
5121         $TRACE rmdir $DIR/$tdir || error "remove parent $DIR/$tdir failed"
5122         $TRACE touch $DIR/$tdir || error "'touch $DIR/$tdir' failed"
5123         $TRACE chmod +x $DIR/$tdir || error "'chmod +x $DIR/$tdir' failed"
5124         # On a buggy kernel addition of "touch foo" after cd .. will
5125         # produce kernel oops in lookup_hash_it
5126         touch ../foo && error "'cd ..' worked after recreate parent"
5127         cd $DIR
5128         $TRACE rm $DIR/$tdir || error "rm '$DIR/$tdir' failed"
5129 }
5130 run_test 48e "Access to recreated parent subdir (should return errors)"
5131
5132 test_49() { # LU-1030
5133         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5134         remote_ost_nodsh && skip "remote OST with nodsh"
5135
5136         # get ost1 size - $FSNAME-OST0000
5137         ost1_size=$(do_facet ost1 $LFS df | grep ${ost1_svc} |
5138                 awk '{ print $4 }')
5139         # write 800M at maximum
5140         [[ $ost1_size -lt 2 ]] && ost1_size=2
5141         [[ $ost1_size -gt 819200 ]] && ost1_size=819200
5142
5143         $LFS setstripe -c 1 -i 0 $DIR/$tfile
5144         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((ost1_size >> 2)) &
5145         local dd_pid=$!
5146
5147         # change max_pages_per_rpc while writing the file
5148         local osc1_mppc=osc.$(get_osc_import_name client ost1).max_pages_per_rpc
5149         local orig_mppc=$($LCTL get_param -n $osc1_mppc)
5150         # loop until dd process exits
5151         while ps ax -opid | grep -wq $dd_pid; do
5152                 $LCTL set_param $osc1_mppc=$((RANDOM % 256 + 1))
5153                 sleep $((RANDOM % 5 + 1))
5154         done
5155         # restore original max_pages_per_rpc
5156         $LCTL set_param $osc1_mppc=$orig_mppc
5157         rm $DIR/$tfile || error "rm $DIR/$tfile failed"
5158 }
5159 run_test 49 "Change max_pages_per_rpc won't break osc extent"
5160
5161 test_50() {
5162         # bug 1485
5163         test_mkdir $DIR/$tdir
5164         cd $DIR/$tdir
5165         ls /proc/$$/cwd || error "ls /proc/$$/cwd failed"
5166 }
5167 run_test 50 "special situations: /proc symlinks  ==============="
5168
5169 test_51a() {    # was test_51
5170         # bug 1516 - create an empty entry right after ".." then split dir
5171         test_mkdir -c1 $DIR/$tdir
5172         touch $DIR/$tdir/foo
5173         $MCREATE $DIR/$tdir/bar
5174         rm $DIR/$tdir/foo
5175         createmany -m $DIR/$tdir/longfile 201
5176         FNUM=202
5177         while [[ $(ls -sd $DIR/$tdir | awk '{ print $1 }') -eq 4 ]]; do
5178                 $MCREATE $DIR/$tdir/longfile$FNUM
5179                 FNUM=$(($FNUM + 1))
5180                 echo -n "+"
5181         done
5182         echo
5183         ls -l $DIR/$tdir > /dev/null || error "ls -l $DIR/$tdir failed"
5184 }
5185 run_test 51a "special situations: split htree with empty entry =="
5186
5187 cleanup_print_lfs_df () {
5188         trap 0
5189         $LFS df
5190         $LFS df -i
5191 }
5192
5193 test_51b() {
5194         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5195
5196         local dir=$DIR/$tdir
5197         local nrdirs=$((65536 + 100))
5198
5199         # cleanup the directory
5200         rm -fr $dir
5201
5202         test_mkdir -c1 $dir
5203
5204         $LFS df
5205         $LFS df -i
5206         local mdtidx=$(printf "%04x" $($LFS getstripe -m $dir))
5207         local numfree=$(lctl get_param -n mdc.$FSNAME-MDT$mdtidx*.filesfree)
5208         [[ $numfree -lt $nrdirs ]] &&
5209                 skip "not enough free inodes ($numfree) on MDT$mdtidx"
5210
5211         # need to check free space for the directories as well
5212         local blkfree=$(lctl get_param -n mdc.$FSNAME-MDT$mdtidx*.kbytesavail)
5213         numfree=$(( blkfree / $(fs_inode_ksize) ))
5214         [[ $numfree -lt $nrdirs ]] && skip "not enough blocks ($numfree)"
5215
5216         trap cleanup_print_lfs_df EXIT
5217
5218         # create files
5219         createmany -d $dir/d $nrdirs || {
5220                 unlinkmany $dir/d $nrdirs
5221                 error "failed to create $nrdirs subdirs in MDT$mdtidx:$dir"
5222         }
5223
5224         # really created :
5225         nrdirs=$(ls -U $dir | wc -l)
5226
5227         # unlink all but 100 subdirectories, then check it still works
5228         local left=100
5229         local delete=$((nrdirs - left))
5230
5231         $LFS df
5232         $LFS df -i
5233
5234         # for ldiskfs the nlink count should be 1, but this is OSD specific
5235         # and so this is listed for informational purposes only
5236         echo "nlink before: $(stat -c %h $dir), created before: $nrdirs"
5237         unlinkmany -d $dir/d $delete ||
5238                 error "unlink of first $delete subdirs failed"
5239
5240         echo "nlink between: $(stat -c %h $dir)"
5241         local found=$(ls -U $dir | wc -l)
5242         [ $found -ne $left ] &&
5243                 error "can't find subdirs: found only $found, expected $left"
5244
5245         unlinkmany -d $dir/d $delete $left ||
5246                 error "unlink of second $left subdirs failed"
5247         # regardless of whether the backing filesystem tracks nlink accurately
5248         # or not, the nlink count shouldn't be more than "." and ".." here
5249         local after=$(stat -c %h $dir)
5250         [[ $after -gt 2 ]] && error "nlink after: $after > 2" ||
5251                 echo "nlink after: $after"
5252
5253         cleanup_print_lfs_df
5254 }
5255 run_test 51b "exceed 64k subdirectory nlink limit on create, verify unlink"
5256
5257 test_51d() {
5258         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5259         [[ $OSTCOUNT -lt 3 ]] && skip_env "needs >= 3 OSTs"
5260
5261         test_mkdir $DIR/$tdir
5262         createmany -o $DIR/$tdir/t- 1000
5263         $LFS getstripe $DIR/$tdir > $TMP/$tfile
5264         for N in $(seq 0 $((OSTCOUNT - 1))); do
5265                 OBJS[$N]=$(awk -vobjs=0 '($1 == '$N') { objs += 1 } \
5266                         END { printf("%0.0f", objs) }' $TMP/$tfile)
5267                 OBJS0[$N]=$(grep -A 1 idx $TMP/$tfile | awk -vobjs=0 \
5268                         '($1 == '$N') { objs += 1 } \
5269                         END { printf("%0.0f", objs) }')
5270                 log "OST$N has ${OBJS[$N]} objects, ${OBJS0[$N]} are index 0"
5271         done
5272         unlinkmany $DIR/$tdir/t- 1000
5273
5274         NLAST=0
5275         for N in $(seq 1 $((OSTCOUNT - 1))); do
5276                 [[ ${OBJS[$N]} -lt $((${OBJS[$NLAST]} - 20)) ]] &&
5277                         error "OST $N has less objects vs OST $NLAST" \
5278                               " (${OBJS[$N]} < ${OBJS[$NLAST]}"
5279                 [[ ${OBJS[$N]} -gt $((${OBJS[$NLAST]} + 20)) ]] &&
5280                         error "OST $N has less objects vs OST $NLAST" \
5281                               " (${OBJS[$N]} < ${OBJS[$NLAST]}"
5282
5283                 [[ ${OBJS0[$N]} -lt $((${OBJS0[$NLAST]} - 20)) ]] &&
5284                         error "OST $N has less #0 objects vs OST $NLAST" \
5285                               " (${OBJS0[$N]} < ${OBJS0[$NLAST]}"
5286                 [[ ${OBJS0[$N]} -gt $((${OBJS0[$NLAST]} + 20)) ]] &&
5287                         error "OST $N has less #0 objects vs OST $NLAST" \
5288                               " (${OBJS0[$N]} < ${OBJS0[$NLAST]}"
5289                 NLAST=$N
5290         done
5291         rm -f $TMP/$tfile
5292 }
5293 run_test 51d "check object distribution"
5294
5295 test_51e() {
5296         if [ "$mds1_FSTYPE" != ldiskfs ]; then
5297                 skip_env "ldiskfs only test"
5298         fi
5299
5300         test_mkdir -c1 $DIR/$tdir
5301         test_mkdir -c1 $DIR/$tdir/d0
5302
5303         touch $DIR/$tdir/d0/foo
5304         createmany -l $DIR/$tdir/d0/foo $DIR/$tdir/d0/f- 65001 &&
5305                 error "file exceed 65000 nlink limit!"
5306         unlinkmany $DIR/$tdir/d0/f- 65001
5307         return 0
5308 }
5309 run_test 51e "check file nlink limit"
5310
5311 test_51f() {
5312         test_mkdir $DIR/$tdir
5313
5314         local max=100000
5315         local ulimit_old=$(ulimit -n)
5316         local spare=20 # number of spare fd's for scripts/libraries, etc.
5317         local mdt=$($LFS getstripe -m $DIR/$tdir)
5318         local numfree=$($LFS df -i $DIR/$tdir | awk '/MDT:'$mdt'/ { print $4 }')
5319
5320         echo "MDT$mdt numfree=$numfree, max=$max"
5321         [[ $numfree -gt $max ]] && numfree=$max || numfree=$((numfree * 7 / 8))
5322         if [ $((numfree + spare)) -gt $ulimit_old ]; then
5323                 while ! ulimit -n $((numfree + spare)); do
5324                         numfree=$((numfree * 3 / 4))
5325                 done
5326                 echo "changed ulimit from $ulimit_old to $((numfree + spare))"
5327         else
5328                 echo "left ulimit at $ulimit_old"
5329         fi
5330
5331         createmany -o -k -t 120 $DIR/$tdir/f $numfree || {
5332                 unlinkmany $DIR/$tdir/f $numfree
5333                 error "create+open $numfree files in $DIR/$tdir failed"
5334         }
5335         ulimit -n $ulimit_old
5336
5337         # if createmany exits at 120s there will be fewer than $numfree files
5338         unlinkmany $DIR/$tdir/f $numfree || true
5339 }
5340 run_test 51f "check many open files limit"
5341
5342 test_52a() {
5343         [ -f $DIR/$tdir/foo ] && chattr -a $DIR/$tdir/foo
5344         test_mkdir $DIR/$tdir
5345         touch $DIR/$tdir/foo
5346         chattr +a $DIR/$tdir/foo || error "chattr +a failed"
5347         echo bar >> $DIR/$tdir/foo || error "append bar failed"
5348         cp /etc/hosts $DIR/$tdir/foo && error "cp worked"
5349         rm -f $DIR/$tdir/foo 2>/dev/null && error "rm worked"
5350         link $DIR/$tdir/foo $DIR/$tdir/foo_link 2>/dev/null &&
5351                                         error "link worked"
5352         echo foo >> $DIR/$tdir/foo || error "append foo failed"
5353         mrename $DIR/$tdir/foo $DIR/$tdir/foo_ren && error "rename worked"
5354         lsattr $DIR/$tdir/foo | egrep -q "^-+a[-e]+ $DIR/$tdir/foo" ||
5355                                                      error "lsattr"
5356         chattr -a $DIR/$tdir/foo || error "chattr -a failed"
5357         cp -r $DIR/$tdir $TMP/
5358         rm -fr $DIR/$tdir $TMP/$tdir || error "cleanup rm failed"
5359 }
5360 run_test 52a "append-only flag test (should return errors)"
5361
5362 test_52b() {
5363         [ -f $DIR/$tdir/foo ] && chattr -i $DIR/$tdir/foo
5364         test_mkdir $DIR/$tdir
5365         touch $DIR/$tdir/foo
5366         chattr +i $DIR/$tdir/foo || error "chattr +i failed"
5367         cat test > $DIR/$tdir/foo && error "cat test worked"
5368         cp /etc/hosts $DIR/$tdir/foo && error "cp worked"
5369         rm -f $DIR/$tdir/foo 2>/dev/null && error "rm worked"
5370         link $DIR/$tdir/foo $DIR/$tdir/foo_link 2>/dev/null &&
5371                                         error "link worked"
5372         echo foo >> $DIR/$tdir/foo && error "echo worked"
5373         mrename $DIR/$tdir/foo $DIR/$tdir/foo_ren && error "rename worked"
5374         [ -f $DIR/$tdir/foo ] || error "$tdir/foo is not a file"
5375         [ -f $DIR/$tdir/foo_ren ] && error "$tdir/foo_ren is not a file"
5376         lsattr $DIR/$tdir/foo | egrep -q "^-+i[-e]+ $DIR/$tdir/foo" ||
5377                                                         error "lsattr"
5378         chattr -i $DIR/$tdir/foo || error "chattr failed"
5379
5380         rm -fr $DIR/$tdir || error "unable to remove $DIR/$tdir"
5381 }
5382 run_test 52b "immutable flag test (should return errors) ======="
5383
5384 test_53() {
5385         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5386         remote_mds_nodsh && skip "remote MDS with nodsh"
5387         remote_ost_nodsh && skip "remote OST with nodsh"
5388
5389         local param
5390         local param_seq
5391         local ostname
5392         local mds_last
5393         local mds_last_seq
5394         local ost_last
5395         local ost_last_seq
5396         local ost_last_id
5397         local ostnum
5398         local node
5399         local found=false
5400         local support_last_seq=true
5401
5402         [[ $MDS1_VERSION -ge $(version_code 2.3.60) ]] ||
5403                 support_last_seq=false
5404
5405         # only test MDT0000
5406         local mdtosc=$(get_mdtosc_proc_path $SINGLEMDS)
5407         local value
5408         for value in $(do_facet $SINGLEMDS \
5409                        $LCTL get_param osp.$mdtosc.prealloc_last_id) ; do
5410                 param=$(echo ${value[0]} | cut -d "=" -f1)
5411                 ostname=$(echo $param | cut -d "." -f2 | cut -d - -f 1-2)
5412
5413                 if $support_last_seq; then
5414                         param_seq=$(echo $param |
5415                                 sed -e s/prealloc_last_id/prealloc_last_seq/g)
5416                         mds_last_seq=$(do_facet $SINGLEMDS \
5417                                        $LCTL get_param -n $param_seq)
5418                 fi
5419                 mds_last=$(do_facet $SINGLEMDS $LCTL get_param -n $param)
5420
5421                 ostnum=$(index_from_ostuuid ${ostname}_UUID)
5422                 node=$(facet_active_host ost$((ostnum+1)))
5423                 param="obdfilter.$ostname.last_id"
5424                 for ost_last in $(do_node $node $LCTL get_param -n $param) ; do
5425                         echo "$ostname.last_id=$ost_last; MDS.last_id=$mds_last"
5426                         ost_last_id=$ost_last
5427
5428                         if $support_last_seq; then
5429                                 ost_last_id=$(echo $ost_last |
5430                                               awk -F':' '{print $2}' |
5431                                               sed -e "s/^0x//g")
5432                                 ost_last_seq=$(echo $ost_last |
5433                                                awk -F':' '{print $1}')
5434                                 [[ $ost_last_seq = $mds_last_seq ]] || continue
5435                         fi
5436
5437                         if [[ $ost_last_id != $mds_last ]]; then
5438                                 error "$ost_last_id != $mds_last"
5439                         else
5440                                 found=true
5441                                 break
5442                         fi
5443                 done
5444         done
5445         $found || error "can not match last_seq/last_id for $mdtosc"
5446         return 0
5447 }
5448 run_test 53 "verify that MDS and OSTs agree on pre-creation ===="
5449
5450 test_54a() {
5451         perl -MSocket -e ';' || skip "no Socket perl module installed"
5452
5453         $SOCKETSERVER $DIR/socket ||
5454                 error "$SOCKETSERVER $DIR/socket failed: $?"
5455         $SOCKETCLIENT $DIR/socket ||
5456                 error "$SOCKETCLIENT $DIR/socket failed: $?"
5457         $MUNLINK $DIR/socket || error "$MUNLINK $DIR/socket failed: $?"
5458 }
5459 run_test 54a "unix domain socket test =========================="
5460
5461 test_54b() {
5462         f="$DIR/f54b"
5463         mknod $f c 1 3
5464         chmod 0666 $f
5465         dd if=/dev/zero of=$f bs=$PAGE_SIZE count=1
5466 }
5467 run_test 54b "char device works in lustre ======================"
5468
5469 find_loop_dev() {
5470         [ -b /dev/loop/0 ] && LOOPBASE=/dev/loop/
5471         [ -b /dev/loop0 ] && LOOPBASE=/dev/loop
5472         [ -z "$LOOPBASE" ] && echo "/dev/loop/0 and /dev/loop0 gone?" && return
5473
5474         for i in $(seq 3 7); do
5475                 losetup $LOOPBASE$i > /dev/null 2>&1 && continue
5476                 LOOPDEV=$LOOPBASE$i
5477                 LOOPNUM=$i
5478                 break
5479         done
5480 }
5481
5482 cleanup_54c() {
5483         local rc=0
5484         loopdev="$DIR/loop54c"
5485
5486         trap 0
5487         $UMOUNT $DIR/$tdir || rc=$?
5488         losetup -d $loopdev || true
5489         losetup -d $LOOPDEV || true
5490         rm -rf $loopdev $DIR/$tfile $DIR/$tdir
5491         return $rc
5492 }
5493
5494 test_54c() {
5495         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5496
5497         loopdev="$DIR/loop54c"
5498
5499         find_loop_dev
5500         [ -z "$LOOPNUM" ] && skip_env "couldn't find empty loop device"
5501         trap cleanup_54c EXIT
5502         mknod $loopdev b 7 $LOOPNUM
5503         echo "make a loop file system with $DIR/$tfile on $loopdev ($LOOPNUM)."
5504         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE seek=1024 count=1 > /dev/null
5505         losetup $loopdev $DIR/$tfile ||
5506                 error "can't set up $loopdev for $DIR/$tfile"
5507         mkfs.ext2 $loopdev || error "mke2fs on $loopdev"
5508         test_mkdir $DIR/$tdir
5509         mount -t ext2 $loopdev $DIR/$tdir ||
5510                 error "error mounting $loopdev on $DIR/$tdir"
5511         dd if=/dev/zero of=$DIR/$tdir/tmp bs=$PAGE_SIZE count=30 ||
5512                 error "dd write"
5513         df $DIR/$tdir
5514         dd if=$DIR/$tdir/tmp of=/dev/zero bs=$PAGE_SIZE count=30 ||
5515                 error "dd read"
5516         cleanup_54c
5517 }
5518 run_test 54c "block device works in lustre ====================="
5519
5520 test_54d() {
5521         f="$DIR/f54d"
5522         string="aaaaaa"
5523         mknod $f p
5524         [ "$string" = $(echo $string > $f | cat $f) ] || error "$f != $string"
5525 }
5526 run_test 54d "fifo device works in lustre ======================"
5527
5528 test_54e() {
5529         f="$DIR/f54e"
5530         string="aaaaaa"
5531         cp -aL /dev/console $f
5532         echo $string > $f || error "echo $string to $f failed"
5533 }
5534 run_test 54e "console/tty device works in lustre ======================"
5535
5536 test_56a() {
5537         local numfiles=3
5538         local dir=$DIR/$tdir
5539
5540         rm -rf $dir
5541         test_mkdir -p $dir/dir
5542         for i in $(seq $numfiles); do
5543                 touch $dir/file$i
5544                 touch $dir/dir/file$i
5545         done
5546
5547         local numcomp=$($LFS getstripe --component-count $dir)
5548
5549         [[ $numcomp == 0 ]] && numcomp=1
5550
5551         # test lfs getstripe with --recursive
5552         local filenum=$($LFS getstripe -r $dir | egrep -c "obdidx|l_ost_idx")
5553
5554         [[ $filenum -eq $((numfiles * 2)) ]] ||
5555                 error "$LFS getstripe -r: found $filenum != $((numfiles * 2))"
5556         filenum=$($LFS getstripe $dir | egrep -c "obdidx|l_ost_idx")
5557         [[ $filenum -eq $numfiles ]] ||
5558                 error "$LFS getstripe $dir: found $filenum, not $numfiles"
5559         echo "$LFS getstripe showed obdidx or l_ost_idx"
5560
5561         # test lfs getstripe with file instead of dir
5562         filenum=$($LFS getstripe $dir/file1 | egrep -c "obdidx|l_ost_idx")
5563         [[ $filenum -eq 1 ]] ||
5564                 error "$LFS getstripe $dir/file1: found $filenum, not 1"
5565         echo "$LFS getstripe file1 passed"
5566
5567         #test lfs getstripe with --verbose
5568         filenum=$($LFS getstripe --verbose $dir | grep -c lmm_magic)
5569         [[ $filenum -eq $((numfiles * numcomp)) ]] ||
5570                 error "$LFS getstripe --verbose $dir: "\
5571                       "got $filenum want $((numfiles * numcomp)) lmm_magic"
5572         [[ $($LFS getstripe $dir | grep -c lmm_magic) -eq 0 ]] ||
5573                 error "$LFS getstripe $dir: showed lmm_magic"
5574
5575         #test lfs getstripe with -v prints lmm_fid
5576         filenum=$($LFS getstripe -v $dir | grep -c lmm_fid)
5577         [[ $filenum -eq $((numfiles * numcomp)) ]] ||
5578                 error "$LFS getstripe -v $dir: "\
5579                       "got $filenum want $((numfiles * numcomp)) lmm_fid"
5580         [[ $($LFS getstripe $dir | grep -c lmm_fid) -eq 0 ]] ||
5581                 error "$LFS getstripe $dir: showed lmm_fid by default"
5582         echo "$LFS getstripe --verbose passed"
5583
5584         #check for FID information
5585         local fid1=$($LFS getstripe --fid $dir/file1)
5586         local fid2=$($LFS getstripe --verbose $dir/file1 |
5587                      awk '/lmm_fid: / { print $2; exit; }')
5588         local fid3=$($LFS path2fid $dir/file1)
5589
5590         [ "$fid1" != "$fid2" ] &&
5591                 error "getstripe --fid '$fid1' != getstripe --verbose '$fid2'"
5592         [ "$fid1" != "$fid3" ] &&
5593                 error "getstripe --fid '$fid1' != lfs path2fid '$fid3'"
5594         echo "$LFS getstripe --fid passed"
5595
5596         #test lfs getstripe with --obd
5597         $LFS getstripe --obd wrong_uuid $dir 2>&1 | grep -q "unknown obduuid" ||
5598                 error "$LFS getstripe --obd wrong_uuid: should return error"
5599
5600         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
5601
5602         local ostidx=1
5603         local obduuid=$(ostuuid_from_index $ostidx)
5604         local found=$($LFS getstripe -r --obd $obduuid $dir |
5605                 grep 'lmm_stripe_offset:' | grep -c " $ostidx\$")
5606
5607         filenum=$($LFS getstripe -ir $dir | grep -c "^$ostidx\$")
5608         [[ $($LFS getstripe -id $dir) -ne $ostidx ]] ||
5609                 ((filenum--))
5610         [[ $($LFS getstripe -id $dir/dir) -ne $ostidx ]] ||
5611                 ((filenum--))
5612
5613         [[ $found -eq $filenum ]] ||
5614                 error "$LFS getstripe --obd: found $found expect $filenum"
5615         [[ $($LFS getstripe -r -v --obd $obduuid $dir |
5616                 sed '/^[         ]*'${ostidx}'[  ]/d' |
5617                 sed -n '/^[      ]*[0-9][0-9]*[  ]/p' | wc -l) -eq 0 ]] ||
5618                 error "$LFS getstripe --obd: should not show file on other obd"
5619         echo "$LFS getstripe --obd passed"
5620 }
5621 run_test 56a "check $LFS getstripe"
5622
5623 test_56b() {
5624         local dir=$DIR/$tdir
5625         local numdirs=3
5626
5627         test_mkdir $dir
5628         for i in $(seq $numdirs); do
5629                 test_mkdir $dir/dir$i
5630         done
5631
5632         # test lfs getdirstripe default mode is non-recursion, which is
5633         # different from lfs getstripe
5634         local dircnt=$($LFS getdirstripe $dir | grep -c lmv_stripe_count)
5635
5636         [[ $dircnt -eq 1 ]] ||
5637                 error "$LFS getdirstripe: found $dircnt, not 1"
5638         dircnt=$($LFS getdirstripe --recursive $dir |
5639                 grep -c lmv_stripe_count)
5640         [[ $dircnt -eq $((numdirs + 1)) ]] ||
5641                 error "$LFS getdirstripe -r: $dircnt, != $((numdirs + 1))"
5642 }
5643 run_test 56b "check $LFS getdirstripe"
5644
5645 test_56c() {
5646         remote_ost_nodsh && skip "remote OST with nodsh"
5647
5648         local ost_idx=0
5649         local ost_name=$(ostname_from_index $ost_idx)
5650         local old_status=$(ost_dev_status $ost_idx)
5651         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
5652
5653         [[ -z "$old_status" ]] ||
5654                 skip_env "OST $ost_name is in $old_status status"
5655
5656         do_facet ost1 $LCTL set_param -n obdfilter.$ost_name.degraded=1
5657         [[ $OST1_VERSION -lt $(version_code 2.12.55) ]] || do_facet ost1 \
5658                 $LCTL set_param -n obdfilter.$ost_name.no_precreate=1
5659         if [[ $OST1_VERSION -ge $(version_code 2.12.57) ]]; then
5660                 save_lustre_params ost1 osd-*.$ost_name.nonrotational > $p
5661                 do_facet ost1 $LCTL set_param -n osd-*.$ost_name.nonrotational=1
5662         fi
5663
5664         [[ $($LFS df -v $MOUNT |& grep -c "inactive device") -eq 0 ]] ||
5665                 error "$LFS df -v showing inactive devices"
5666         sleep_maxage
5667
5668         local new_status=$(ost_dev_status $ost_idx $MOUNT -v)
5669
5670         [[ "$new_status" =~ "D" ]] ||
5671                 error "$ost_name status is '$new_status', missing 'D'"
5672         if [[ $OST1_VERSION -ge $(version_code 2.12.55) ]]; then
5673                 [[ "$new_status" =~ "N" ]] ||
5674                         error "$ost_name status is '$new_status', missing 'N'"
5675         fi
5676         if [[ $OST1_VERSION -ge $(version_code 2.12.57) ]]; then
5677                 [[ "$new_status" =~ "f" ]] ||
5678                         error "$ost_name status is '$new_status', missing 'f'"
5679         fi
5680
5681         do_facet ost1 $LCTL set_param -n obdfilter.$ost_name.degraded=0
5682         [[ $OST1_VERSION -lt $(version_code 2.12.55) ]] || do_facet ost1 \
5683                 $LCTL set_param -n obdfilter.$ost_name.no_precreate=0
5684         [[ -z "$p" ]] && restore_lustre_params < $p || true
5685         sleep_maxage
5686
5687         new_status=$(ost_dev_status $ost_idx)
5688         [[ ! "$new_status" =~ "D" && ! "$new_status" =~ "N" ]] ||
5689                 error "$ost_name status is '$new_status', has 'D' and/or 'N'"
5690         # can't check 'f' as devices may actually be on flash
5691 }
5692 run_test 56c "check 'lfs df' showing device status"
5693
5694 test_56d() {
5695         local mdts=$($LFS df -v $MOUNT | grep -c MDT)
5696         local osts=$($LFS df -v $MOUNT | grep -c OST)
5697
5698         $LFS df $MOUNT
5699
5700         (( mdts == MDSCOUNT )) ||
5701                 error "lfs df -v showed $mdts MDTs, not $MDSCOUNT"
5702         (( osts == OSTCOUNT )) ||
5703                 error "lfs df -v showed $osts OSTs, not $OSTCOUNT"
5704 }
5705 run_test 56d "'lfs df -v' prints only configured devices"
5706
5707 NUMFILES=3
5708 NUMDIRS=3
5709 setup_56() {
5710         local local_tdir="$1"
5711         local local_numfiles="$2"
5712         local local_numdirs="$3"
5713         local dir_params="$4"
5714         local dir_stripe_params="$5"
5715
5716         if [ ! -d "$local_tdir" ] ; then
5717                 test_mkdir -p $dir_stripe_params $local_tdir
5718                 [ "$dir_params" ] && $LFS setstripe $dir_params $local_tdir
5719                 for i in $(seq $local_numfiles) ; do
5720                         touch $local_tdir/file$i
5721                 done
5722                 for i in $(seq $local_numdirs) ; do
5723                         test_mkdir $dir_stripe_params $local_tdir/dir$i
5724                         for j in $(seq $local_numfiles) ; do
5725                                 touch $local_tdir/dir$i/file$j
5726                         done
5727                 done
5728         fi
5729 }
5730
5731 setup_56_special() {
5732         local local_tdir=$1
5733         local local_numfiles=$2
5734         local local_numdirs=$3
5735
5736         setup_56 $local_tdir $local_numfiles $local_numdirs
5737
5738         if [ ! -e "$local_tdir/loop${local_numfiles}b" ] ; then
5739                 for i in $(seq $local_numfiles) ; do
5740                         mknod $local_tdir/loop${i}b b 7 $i
5741                         mknod $local_tdir/null${i}c c 1 3
5742                         ln -s $local_tdir/file1 $local_tdir/link${i}
5743                 done
5744                 for i in $(seq $local_numdirs) ; do
5745                         mknod $local_tdir/dir$i/loop${i}b b 7 $i
5746                         mknod $local_tdir/dir$i/null${i}c c 1 3
5747                         ln -s $local_tdir/dir$i/file1 $local_tdir/dir$i/link${i}
5748                 done
5749         fi
5750 }
5751
5752 test_56g() {
5753         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
5754         local expected=$(($NUMDIRS + 2))
5755
5756         setup_56 $dir $NUMFILES $NUMDIRS
5757
5758         # test lfs find with -name
5759         for i in $(seq $NUMFILES) ; do
5760                 local nums=$($LFS find -name "*$i" $dir | wc -l)
5761
5762                 [ $nums -eq $expected ] ||
5763                         error "lfs find -name '*$i' $dir wrong: "\
5764                               "found $nums, expected $expected"
5765         done
5766 }
5767 run_test 56g "check lfs find -name"
5768
5769 test_56h() {
5770         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
5771         local expected=$(((NUMDIRS + 1) * (NUMFILES - 1) + NUMFILES))
5772
5773         setup_56 $dir $NUMFILES $NUMDIRS
5774
5775         # test lfs find with ! -name
5776         for i in $(seq $NUMFILES) ; do
5777                 local nums=$($LFS find ! -name "*$i" $dir | wc -l)
5778
5779                 [ $nums -eq $expected ] ||
5780                         error "lfs find ! -name '*$i' $dir wrong: "\
5781                               "found $nums, expected $expected"
5782         done
5783 }
5784 run_test 56h "check lfs find ! -name"
5785
5786 test_56i() {
5787         local dir=$DIR/$tdir
5788
5789         test_mkdir $dir
5790
5791         local cmd="$LFS find -ost $(ostuuid_from_index 0 $dir) $dir"
5792         local out=$($cmd)
5793
5794         [ -z "$out" ] || error "'$cmd' returned directory '$out'"
5795 }
5796 run_test 56i "check 'lfs find -ost UUID' skips directories"
5797
5798 test_56j() {
5799         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
5800
5801         setup_56_special $dir $NUMFILES $NUMDIRS
5802
5803         local expected=$((NUMDIRS + 1))
5804         local cmd="$LFS find -type d $dir"
5805         local nums=$($cmd | wc -l)
5806
5807         [ $nums -eq $expected ] ||
5808                 error "'$cmd' wrong: found $nums, expected $expected"
5809 }
5810 run_test 56j "check lfs find -type d"
5811
5812 test_56k() {
5813         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
5814
5815         setup_56_special $dir $NUMFILES $NUMDIRS
5816
5817         local expected=$(((NUMDIRS + 1) * NUMFILES))
5818         local cmd="$LFS find -type f $dir"
5819         local nums=$($cmd | wc -l)
5820
5821         [ $nums -eq $expected ] ||
5822                 error "'$cmd' wrong: found $nums, expected $expected"
5823 }
5824 run_test 56k "check lfs find -type f"
5825
5826 test_56l() {
5827         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
5828
5829         setup_56_special $dir $NUMFILES $NUMDIRS
5830
5831         local expected=$((NUMDIRS + NUMFILES))
5832         local cmd="$LFS find -type b $dir"
5833         local nums=$($cmd | wc -l)
5834
5835         [ $nums -eq $expected ] ||
5836                 error "'$cmd' wrong: found $nums, expected $expected"
5837 }
5838 run_test 56l "check lfs find -type b"
5839
5840 test_56m() {
5841         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
5842
5843         setup_56_special $dir $NUMFILES $NUMDIRS
5844
5845         local expected=$((NUMDIRS + NUMFILES))
5846         local cmd="$LFS find -type c $dir"
5847         local nums=$($cmd | wc -l)
5848         [ $nums -eq $expected ] ||
5849                 error "'$cmd' wrong: found $nums, expected $expected"
5850 }
5851 run_test 56m "check lfs find -type c"
5852
5853 test_56n() {
5854         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
5855         setup_56_special $dir $NUMFILES $NUMDIRS
5856
5857         local expected=$((NUMDIRS + NUMFILES))
5858         local cmd="$LFS find -type l $dir"
5859         local nums=$($cmd | wc -l)
5860
5861         [ $nums -eq $expected ] ||
5862                 error "'$cmd' wrong: found $nums, expected $expected"
5863 }
5864 run_test 56n "check lfs find -type l"
5865
5866 test_56o() {
5867         local dir=$DIR/$tdir
5868
5869         setup_56 $dir $NUMFILES $NUMDIRS
5870         utime $dir/file1 > /dev/null || error "utime (1)"
5871         utime $dir/file2 > /dev/null || error "utime (2)"
5872         utime $dir/dir1 > /dev/null || error "utime (3)"
5873         utime $dir/dir2 > /dev/null || error "utime (4)"
5874         utime $dir/dir1/file1 > /dev/null || error "utime (5)"
5875         dd if=/dev/zero count=1 >> $dir/dir1/file1 && sync
5876
5877         local expected=4
5878         local nums=$($LFS find -mtime +0 $dir | wc -l)
5879
5880         [ $nums -eq $expected ] ||
5881                 error "lfs find -mtime +0 $dir: found $nums expect $expected"
5882
5883         expected=12
5884         cmd="$LFS find -mtime 0 $dir"
5885         nums=$($cmd | wc -l)
5886         [ $nums -eq $expected ] ||
5887                 error "'$cmd' wrong: found $nums, expected $expected"
5888 }
5889 run_test 56o "check lfs find -mtime for old files"
5890
5891 test_56ob() {
5892         local dir=$DIR/$tdir
5893         local expected=1
5894         local count=0
5895
5896         # just to make sure there is something that won't be found
5897         test_mkdir $dir
5898         touch $dir/$tfile.now
5899
5900         for age in year week day hour min; do
5901                 count=$((count + 1))
5902
5903                 touch $dir/$tfile-a.$age $dir/$tfile-m.$age
5904                 touch --date="$count $age ago" -a $dir/$tfile-a.$age
5905                 touch --date="$count $age ago" -m $dir/$tfile-m.$age
5906
5907                 local cmd="$LFS find $dir -mtime $count${age:0:1}"
5908                 local nums=$($cmd | wc -l)
5909                 [ $nums -eq $expected ] ||
5910                         error "'$cmd' wrong: found $nums, expected $expected"
5911
5912                 cmd="$LFS find $dir -atime $count${age:0:1}"
5913                 nums=$($cmd | wc -l)
5914                 [ $nums -eq $expected ] ||
5915                         error "'$cmd' wrong: found $nums, expected $expected"
5916         done
5917
5918         sleep 2
5919         cmd="$LFS find $dir -ctime +1s -type f"
5920         nums=$($cmd | wc -l)
5921         (( $nums == $count * 2 + 1)) ||
5922                 error "'$cmd' wrong: found $nums, expected $((expected*2+1))"
5923 }
5924 run_test 56ob "check lfs find -atime -mtime -ctime with units"
5925
5926 test_newerXY_base() {
5927         local x=$1
5928         local y=$2
5929         local dir=$DIR/$tdir
5930         local ref
5931         local negref
5932
5933         if [ $y == "t" ]; then
5934                 if [ $x == "b" ]; then
5935                         ref="\"$(do_facet mds1 date +"%Y-%m-%d\ %H:%M:%S")\""
5936                 else
5937                         ref="\"$(date +"%Y-%m-%d %H:%M:%S")\""
5938                 fi
5939         else
5940                 ref=$DIR/$tfile.newer.$x$y
5941                 touch $ref || error "touch $ref failed"
5942         fi
5943         sleep 2
5944         setup_56 $dir $NUMFILES $NUMDIRS "-i0 -c1" "-i0 -c1"
5945         sleep 2
5946         if [ $y == "t" ]; then
5947                 if [ $x == "b" ]; then
5948                         negref="\"$(do_facet mds1 date +"%Y-%m-%d\ %H:%M:%S")\""
5949                 else
5950                         negref="\"$(date +"%Y-%m-%d %H:%M:%S")\""
5951                 fi
5952         else
5953                 negref=$DIR/$tfile.negnewer.$x$y
5954                 touch $negref || error "touch $negref failed"
5955         fi
5956
5957         local cmd="$LFS find $dir -newer$x$y $ref"
5958         local nums=$(eval $cmd | wc -l)
5959         local expected=$(((NUMFILES + 2) * NUMDIRS + 1))
5960
5961         [ $nums -eq $expected ] ||
5962                 error "'$cmd' wrong: found $nums, expected $expected"
5963
5964         cmd="$LFS find $dir ! -newer$x$y $negref"
5965         nums=$(eval $cmd | wc -l)
5966         [ $nums -eq $expected ] ||
5967                 error "'$cmd' wrong: found $nums, expected $expected"
5968
5969         cmd="$LFS find $dir -newer$x$y $ref ! -newer$x$y $negref"
5970         nums=$(eval $cmd | wc -l)
5971         [ $nums -eq $expected ] ||
5972                 error "'$cmd' wrong: found $nums, expected $expected"
5973
5974         rm -rf $DIR/*
5975 }
5976
5977 test_56oc() {
5978         test_newerXY_base "b" "t"
5979         test_newerXY_base "a" "a"
5980         test_newerXY_base "a" "m"
5981         test_newerXY_base "a" "c"
5982         test_newerXY_base "m" "a"
5983         test_newerXY_base "m" "m"
5984         test_newerXY_base "m" "c"
5985         test_newerXY_base "c" "a"
5986         test_newerXY_base "c" "m"
5987         test_newerXY_base "c" "c"
5988         test_newerXY_base "b" "b"
5989         test_newerXY_base "a" "t"
5990         test_newerXY_base "m" "t"
5991         test_newerXY_base "c" "t"
5992         test_newerXY_base "b" "t"
5993 }
5994 run_test 56oc "check lfs find -newerXY work"
5995
5996 btime_supported() {
5997         local dir=$DIR/$tdir
5998         local rc
5999
6000         mkdir -p $dir
6001         touch $dir/$tfile
6002         $LFS find $dir -btime -1d -type f
6003         rc=$?
6004         rm -rf $dir
6005         return $rc
6006 }
6007
6008 test_56od() {
6009         [ $MDS1_VERSION -lt $(version_code 2.13.53) ] &&
6010                 ! btime_supported && skip "btime unsupported on MDS"
6011
6012         [ $CLIENT_VERSION -lt $(version_code 2.13.53) ] &&
6013                 ! btime_supported && skip "btime unsupported on clients"
6014
6015         local dir=$DIR/$tdir
6016         local ref=$DIR/$tfile.ref
6017         local negref=$DIR/$tfile.negref
6018
6019         mkdir $dir || error "mkdir $dir failed"
6020         touch $dir/$tfile.n1 || error "touch $dir/$tfile.n1 failed"
6021         touch $dir/$tfile.n2 || error "touch $dir/$tfile.n2 failed"
6022         mkdir $dir/$tdir.n1 || error "mkdir $dir/$tdir.n1 failed"
6023         mkdir $dir/$tdir.n2 || error "mkdir $dir/$tdir.n2 failed"
6024         touch $ref || error "touch $ref failed"
6025         # sleep 3 seconds at least
6026         sleep 3
6027
6028         local before=$(do_facet mds1 date +%s)
6029         local skew=$(($(date +%s) - before + 1))
6030
6031         if (( skew < 0 && skew > -5 )); then
6032                 sleep $((0 - skew + 1))
6033                 skew=0
6034         fi
6035
6036         # Set the dir stripe params to limit files all on MDT0,
6037         # otherwise we need to calc the max clock skew between
6038         # the client and MDTs.
6039         setup_56 $dir/d.btime $NUMFILES $NUMDIRS "-i0 -c1" "-i0 -c1"
6040         sleep 2
6041         touch $negref || error "touch $negref failed"
6042
6043         local cmd="$LFS find $dir -newerbb $ref ! -newerbb $negref -type f"
6044         local nums=$($cmd | wc -l)
6045         local expected=$(((NUMFILES + 1) * NUMDIRS))
6046
6047         [ $nums -eq $expected ] ||
6048                 error "'$cmd' wrong: found $nums, expected $expected"
6049
6050         cmd="$LFS find $dir -newerbb $ref ! -newerbb $negref -type d"
6051         nums=$($cmd | wc -l)
6052         expected=$((NUMFILES + 1))
6053         [ $nums -eq $expected ] ||
6054                 error "'$cmd' wrong: found $nums, expected $expected"
6055
6056         [ $skew -lt 0 ] && return
6057
6058         local after=$(do_facet mds1 date +%s)
6059         local age=$((after - before + 1 + skew))
6060
6061         cmd="$LFS find $dir -btime -${age}s -type f"
6062         nums=$($cmd | wc -l)
6063         expected=$(((NUMFILES + 1) * NUMDIRS))
6064
6065         echo "Clock skew between client and server: $skew, age:$age"
6066         [ $nums -eq $expected ] ||
6067                 error "'$cmd' wrong: found $nums, expected $expected"
6068
6069         expected=$(($NUMDIRS + 1))
6070         cmd="$LFS find $dir -btime -${age}s -type d"
6071         nums=$($cmd | wc -l)
6072         [ $nums -eq $expected ] ||
6073                 error "'$cmd' wrong: found $nums, expected $expected"
6074         rm -f $ref $negref || error "Failed to remove $ref $negref"
6075 }
6076 run_test 56od "check lfs find -btime with units"
6077
6078 test_56p() {
6079         [ $RUNAS_ID -eq $UID ] &&
6080                 skip_env "RUNAS_ID = UID = $UID -- skipping"
6081
6082         local dir=$DIR/$tdir
6083
6084         setup_56 $dir $NUMFILES $NUMDIRS
6085         chown $RUNAS_ID $dir/file* || error "chown $DIR/${tdir}g/file$i failed"
6086
6087         local expected=$NUMFILES
6088         local cmd="$LFS find -uid $RUNAS_ID $dir"
6089         local nums=$($cmd | wc -l)
6090
6091         [ $nums -eq $expected ] ||
6092                 error "'$cmd' wrong: found $nums, expected $expected"
6093
6094         expected=$(((NUMFILES + 1) * NUMDIRS + 1))
6095         cmd="$LFS find ! -uid $RUNAS_ID $dir"
6096         nums=$($cmd | wc -l)
6097         [ $nums -eq $expected ] ||
6098                 error "'$cmd' wrong: found $nums, expected $expected"
6099 }
6100 run_test 56p "check lfs find -uid and ! -uid"
6101
6102 test_56q() {
6103         [ $RUNAS_ID -eq $UID ] &&
6104                 skip_env "RUNAS_ID = UID = $UID -- skipping"
6105
6106         local dir=$DIR/$tdir
6107
6108         setup_56 $dir $NUMFILES $NUMDIRS
6109         chgrp $RUNAS_GID $dir/file* || error "chown $dir/file$i failed"
6110
6111         local expected=$NUMFILES
6112         local cmd="$LFS find -gid $RUNAS_GID $dir"
6113         local nums=$($cmd | wc -l)
6114
6115         [ $nums -eq $expected ] ||
6116                 error "'$cmd' wrong: found $nums, expected $expected"
6117
6118         expected=$(( ($NUMFILES+1) * $NUMDIRS + 1))
6119         cmd="$LFS find ! -gid $RUNAS_GID $dir"
6120         nums=$($cmd | wc -l)
6121         [ $nums -eq $expected ] ||
6122                 error "'$cmd' wrong: found $nums, expected $expected"
6123 }
6124 run_test 56q "check lfs find -gid and ! -gid"
6125
6126 test_56r() {
6127         local dir=$DIR/$tdir
6128
6129         setup_56 $dir $NUMFILES $NUMDIRS
6130
6131         local expected=12
6132         local cmd="$LFS find -size 0 -type f -lazy $dir"
6133         local nums=$($cmd | wc -l)
6134
6135         [ $nums -eq $expected ] ||
6136                 error "'$cmd' wrong: found $nums, expected $expected"
6137         cmd="$LFS find -size 0 -type f $dir"
6138         nums=$($cmd | wc -l)
6139         [ $nums -eq $expected ] ||
6140                 error "'$cmd' wrong: found $nums, expected $expected"
6141
6142         expected=0
6143         cmd="$LFS find ! -size 0 -type f -lazy $dir"
6144         nums=$($cmd | wc -l)
6145         [ $nums -eq $expected ] ||
6146                 error "'$cmd' wrong: found $nums, expected $expected"
6147         cmd="$LFS find ! -size 0 -type f $dir"
6148         nums=$($cmd | wc -l)
6149         [ $nums -eq $expected ] ||
6150                 error "'$cmd' wrong: found $nums, expected $expected"
6151
6152         echo "test" > $dir/$tfile
6153         echo "test2" > $dir/$tfile.2 && sync
6154         expected=1
6155         cmd="$LFS find -size 5 -type f -lazy $dir"
6156         nums=$($cmd | wc -l)
6157         [ $nums -eq $expected ] ||
6158                 error "'$cmd' wrong: found $nums, expected $expected"
6159         cmd="$LFS find -size 5 -type f $dir"
6160         nums=$($cmd | wc -l)
6161         [ $nums -eq $expected ] ||
6162                 error "'$cmd' wrong: found $nums, expected $expected"
6163
6164         expected=1
6165         cmd="$LFS find -size +5 -type f -lazy $dir"
6166         nums=$($cmd | wc -l)
6167         [ $nums -eq $expected ] ||
6168                 error "'$cmd' wrong: found $nums, expected $expected"
6169         cmd="$LFS find -size +5 -type f $dir"
6170         nums=$($cmd | wc -l)
6171         [ $nums -eq $expected ] ||
6172                 error "'$cmd' wrong: found $nums, expected $expected"
6173
6174         expected=2
6175         cmd="$LFS find -size +0 -type f -lazy $dir"
6176         nums=$($cmd | wc -l)
6177         [ $nums -eq $expected ] ||
6178                 error "'$cmd' wrong: found $nums, expected $expected"
6179         cmd="$LFS find -size +0 -type f $dir"
6180         nums=$($cmd | wc -l)
6181         [ $nums -eq $expected ] ||
6182                 error "'$cmd' wrong: found $nums, expected $expected"
6183
6184         expected=2
6185         cmd="$LFS find ! -size -5 -type f -lazy $dir"
6186         nums=$($cmd | wc -l)
6187         [ $nums -eq $expected ] ||
6188                 error "'$cmd' wrong: found $nums, expected $expected"
6189         cmd="$LFS find ! -size -5 -type f $dir"
6190         nums=$($cmd | wc -l)
6191         [ $nums -eq $expected ] ||
6192                 error "'$cmd' wrong: found $nums, expected $expected"
6193
6194         expected=12
6195         cmd="$LFS find -size -5 -type f -lazy $dir"
6196         nums=$($cmd | wc -l)
6197         [ $nums -eq $expected ] ||
6198                 error "'$cmd' wrong: found $nums, expected $expected"
6199         cmd="$LFS find -size -5 -type f $dir"
6200         nums=$($cmd | wc -l)
6201         [ $nums -eq $expected ] ||
6202                 error "'$cmd' wrong: found $nums, expected $expected"
6203 }
6204 run_test 56r "check lfs find -size works"
6205
6206 test_56ra_sub() {
6207         local expected=$1
6208         local glimpses=$2
6209         local cmd="$3"
6210
6211         cancel_lru_locks $OSC
6212
6213         local rpcs_before=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
6214         local nums=$($cmd | wc -l)
6215
6216         [ $nums -eq $expected ] ||
6217                 error "'$cmd' wrong: found $nums, expected $expected"
6218
6219         local rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
6220
6221         if (( rpcs_before + glimpses != rpcs_after )); then
6222                 echo "Before: $rpcs_before After: $rpcs_after $NUMFILES"
6223                 $LCTL get_param osc.*.stats | grep ldlm_glimpse_enqueue
6224
6225                 if [[ $glimpses == 0 ]]; then
6226                         error "'$cmd' should not send glimpse RPCs to OST"
6227                 else
6228                         error "'$cmd' should send $glimpses glimpse RPCs to OST"
6229                 fi
6230         fi
6231 }
6232
6233 test_56ra() {
6234         [[ $MDS1_VERSION -gt $(version_code 2.12.58) ]] ||
6235                 skip "MDS < 2.12.58 doesn't return LSOM data"
6236         local dir=$DIR/$tdir
6237
6238         [[ $OSC == "mdc" ]] && skip "DoM files" && return
6239
6240         setup_56 $dir $NUMFILES $NUMDIRS "-c 1"
6241         # open and close all files to ensure LSOM is updated
6242         cancel_lru_locks $OSC
6243         find $dir -type f | xargs cat > /dev/null
6244
6245         #   expect_found  glimpse_rpcs  command_to_run
6246         test_56ra_sub 12  0 "$LFS find -size 0 -type f -lazy $dir"
6247         test_56ra_sub 12 12 "$LFS find -size 0 -type f $dir"
6248         test_56ra_sub  0  0 "$LFS find ! -size 0 -type f -lazy $dir"
6249         test_56ra_sub  0 12 "$LFS find ! -size 0 -type f $dir"
6250
6251         echo "test" > $dir/$tfile
6252         echo "test2" > $dir/$tfile.2 && sync
6253         cancel_lru_locks $OSC
6254         cat $dir/$tfile $dir/$tfile.2 > /dev/null
6255
6256         test_56ra_sub  1  0 "$LFS find -size 5 -type f -lazy $dir"
6257         test_56ra_sub  1 14 "$LFS find -size 5 -type f $dir"
6258         test_56ra_sub  1  0 "$LFS find -size +5 -type f -lazy $dir"
6259         test_56ra_sub  1 14 "$LFS find -size +5 -type f $dir"
6260
6261         test_56ra_sub  2  0 "$LFS find -size +0 -type f -lazy $dir"
6262         test_56ra_sub  2 14 "$LFS find -size +0 -type f $dir"
6263         test_56ra_sub  2  0 "$LFS find ! -size -5 -type f -lazy $dir"
6264         test_56ra_sub  2 14 "$LFS find ! -size -5 -type f $dir"
6265         test_56ra_sub 12  0 "$LFS find -size -5 -type f -lazy $dir"
6266         test_56ra_sub 12 14 "$LFS find -size -5 -type f $dir"
6267 }
6268 run_test 56ra "check lfs find -size -lazy works for data on OSTs"
6269
6270 test_56rb() {
6271         local dir=$DIR/$tdir
6272         local tmp=$TMP/$tfile.log
6273         local mdt_idx;
6274
6275         test_mkdir -p $dir || error "failed to mkdir $dir"
6276         $LFS setstripe -c 1 -i 0 $dir/$tfile ||
6277                 error "failed to setstripe $dir/$tfile"
6278         mdt_idx=$($LFS getdirstripe -i $dir)
6279         dd if=/dev/zero of=$dir/$tfile bs=1M count=1
6280
6281         stack_trap "rm -f $tmp" EXIT
6282         $LFS find --size +100K --ost 0 $dir |& tee $tmp
6283         ! grep -q obd_uuid $tmp ||
6284                 error "failed to find --size +100K --ost 0 $dir"
6285         $LFS find --size +100K --mdt $mdt_idx $dir |& tee $tmp
6286         ! grep -q obd_uuid $tmp ||
6287                 error "failed to find --size +100K --mdt $mdt_idx $dir"
6288 }
6289 run_test 56rb "check lfs find --size --ost/--mdt works"
6290
6291 test_56s() { # LU-611 #LU-9369
6292         [[ $OSTCOUNT -lt 2 ]] && skip_env "need at least 2 OSTs"
6293
6294         local dir=$DIR/$tdir
6295         local onestripe=$(((NUMDIRS + 1) * NUMFILES))
6296
6297         setup_56 $dir $NUMFILES $NUMDIRS "-c 1"
6298         for i in $(seq $NUMDIRS); do
6299                 $LFS setstripe -c $((OSTCOUNT + 1)) $dir/dir$i/$tfile
6300         done
6301
6302         local expected=$NUMDIRS
6303         local cmd="$LFS find -c $OSTCOUNT $dir"
6304         local nums=$($cmd | wc -l)
6305
6306         [ $nums -eq $expected ] || {
6307                 $LFS getstripe -R $dir
6308                 error "'$cmd' wrong: found $nums, expected $expected"
6309         }
6310
6311         expected=$((NUMDIRS + onestripe))
6312         cmd="$LFS find -stripe-count +0 -type f $dir"
6313         nums=$($cmd | wc -l)
6314         [ $nums -eq $expected ] || {
6315                 $LFS getstripe -R $dir
6316                 error "'$cmd' wrong: found $nums, expected $expected"
6317         }
6318
6319         expected=$onestripe
6320         cmd="$LFS find -stripe-count 1 -type f $dir"
6321         nums=$($cmd | wc -l)
6322         [ $nums -eq $expected ] || {
6323                 $LFS getstripe -R $dir
6324                 error "'$cmd' wrong: found $nums, expected $expected"
6325         }
6326
6327         cmd="$LFS find -stripe-count -2 -type f $dir"
6328         nums=$($cmd | wc -l)
6329         [ $nums -eq $expected ] || {
6330                 $LFS getstripe -R $dir
6331                 error "'$cmd' wrong: found $nums, expected $expected"
6332         }
6333
6334         expected=0
6335         cmd="$LFS find -stripe-count $((OSTCOUNT + 1)) -type f $dir"
6336         nums=$($cmd | wc -l)
6337         [ $nums -eq $expected ] || {
6338                 $LFS getstripe -R $dir
6339                 error "'$cmd' wrong: found $nums, expected $expected"
6340         }
6341 }
6342 run_test 56s "check lfs find -stripe-count works"
6343
6344 test_56t() { # LU-611 #LU-9369
6345         local dir=$DIR/$tdir
6346
6347         setup_56 $dir 0 $NUMDIRS
6348         for i in $(seq $NUMDIRS); do
6349                 $LFS setstripe -S 8M $dir/dir$i/$tfile
6350         done
6351
6352         local expected=$NUMDIRS
6353         local cmd="$LFS find -S 8M $dir"
6354         local nums=$($cmd | wc -l)
6355
6356         [ $nums -eq $expected ] || {
6357                 $LFS getstripe -R $dir
6358                 error "'$cmd' wrong: found $nums, expected $expected"
6359         }
6360         rm -rf $dir
6361
6362         setup_56 $dir $NUMFILES $NUMDIRS "--stripe-size 512k"
6363
6364         $LFS setstripe -S 256k $dir/$tfile.{0,1,2,3}
6365
6366         expected=$(((NUMDIRS + 1) * NUMFILES))
6367         cmd="$LFS find -stripe-size 512k -type f $dir"
6368         nums=$($cmd | wc -l)
6369         [ $nums -eq $expected ] ||
6370                 error "'$cmd' wrong: found $nums, expected $expected"
6371
6372         cmd="$LFS find -stripe-size +320k -type f $dir"
6373         nums=$($cmd | wc -l)
6374         [ $nums -eq $expected ] ||
6375                 error "'$cmd' wrong: found $nums, expected $expected"
6376
6377         expected=$(((NUMDIRS + 1) * NUMFILES + 4))
6378         cmd="$LFS find -stripe-size +200k -type f $dir"
6379         nums=$($cmd | wc -l)
6380         [ $nums -eq $expected ] ||
6381                 error "'$cmd' wrong: found $nums, expected $expected"
6382
6383         cmd="$LFS find -stripe-size -640k -type f $dir"
6384         nums=$($cmd | wc -l)
6385         [ $nums -eq $expected ] ||
6386                 error "'$cmd' wrong: found $nums, expected $expected"
6387
6388         expected=4
6389         cmd="$LFS find -stripe-size 256k -type f $dir"
6390         nums=$($cmd | wc -l)
6391         [ $nums -eq $expected ] ||
6392                 error "'$cmd' wrong: found $nums, expected $expected"
6393
6394         cmd="$LFS find -stripe-size -320k -type f $dir"
6395         nums=$($cmd | wc -l)
6396         [ $nums -eq $expected ] ||
6397                 error "'$cmd' wrong: found $nums, expected $expected"
6398
6399         expected=0
6400         cmd="$LFS find -stripe-size 1024k -type f $dir"
6401         nums=$($cmd | wc -l)
6402         [ $nums -eq $expected ] ||
6403                 error "'$cmd' wrong: found $nums, expected $expected"
6404 }
6405 run_test 56t "check lfs find -stripe-size works"
6406
6407 test_56u() { # LU-611
6408         local dir=$DIR/$tdir
6409
6410         setup_56 $dir $NUMFILES $NUMDIRS "-i 0 -c 1"
6411
6412         if [[ $OSTCOUNT -gt 1 ]]; then
6413                 $LFS setstripe -i 1 -c 1 $dir/$tfile.{0,1,2,3}
6414                 onestripe=4
6415         else
6416                 onestripe=0
6417         fi
6418
6419         local expected=$(((NUMDIRS + 1) * NUMFILES))
6420         local cmd="$LFS find -stripe-index 0 -type f $dir"
6421         local nums=$($cmd | wc -l)
6422
6423         [ $nums -eq $expected ] ||
6424                 error "'$cmd' wrong: found $nums, expected $expected"
6425
6426         expected=$onestripe
6427         cmd="$LFS find -stripe-index 1 -type f $dir"
6428         nums=$($cmd | wc -l)
6429         [ $nums -eq $expected ] ||
6430                 error "'$cmd' wrong: found $nums, expected $expected"
6431
6432         cmd="$LFS find ! -stripe-index 0 -type f $dir"
6433         nums=$($cmd | wc -l)
6434         [ $nums -eq $expected ] ||
6435                 error "'$cmd' wrong: found $nums, expected $expected"
6436
6437         expected=0
6438         # This should produce an error and not return any files
6439         cmd="$LFS find -stripe-index $OSTCOUNT -type f $dir"
6440         nums=$($cmd 2>/dev/null | wc -l)
6441         [ $nums -eq $expected ] ||
6442                 error "'$cmd' wrong: found $nums, expected $expected"
6443
6444         if [[ $OSTCOUNT -gt 1 ]]; then
6445                 expected=$(((NUMDIRS + 1) * NUMFILES + onestripe))
6446                 cmd="$LFS find -stripe-index 0,1 -type f $dir"
6447                 nums=$($cmd | wc -l)
6448                 [ $nums -eq $expected ] ||
6449                         error "'$cmd' wrong: found $nums, expected $expected"
6450         fi
6451 }
6452 run_test 56u "check lfs find -stripe-index works"
6453
6454 test_56v() {
6455         local mdt_idx=0
6456         local dir=$DIR/$tdir
6457
6458         setup_56 $dir $NUMFILES $NUMDIRS
6459
6460         UUID=$(mdtuuid_from_index $mdt_idx $dir)
6461         [ -z "$UUID" ] && error "mdtuuid_from_index cannot find MDT $mdt_idx"
6462
6463         for file in $($LFS find -m $UUID $dir); do
6464                 file_midx=$($LFS getstripe -m $file)
6465                 [ $file_midx -eq $mdt_idx ] ||
6466                         error "lfs find -m $UUID != getstripe -m $file_midx"
6467         done
6468 }
6469 run_test 56v "check 'lfs find -m match with lfs getstripe -m'"
6470
6471 test_56w() {
6472         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
6473         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6474
6475         local dir=$DIR/$tdir
6476
6477         setup_56 $dir $NUMFILES $NUMDIRS "-c $OSTCOUNT" "-c1"
6478
6479         local stripe_size=$($LFS getstripe -S -d $dir) ||
6480                 error "$LFS getstripe -S -d $dir failed"
6481         stripe_size=${stripe_size%% *}
6482
6483         local file_size=$((stripe_size * OSTCOUNT))
6484         local file_num=$((NUMDIRS * NUMFILES + NUMFILES))
6485         local required_space=$((file_num * file_size))
6486         local free_space=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
6487                            head -n1)
6488         [[ $free_space -le $((required_space / 1024)) ]] &&
6489                 skip_env "need $required_space, have $free_space kbytes"
6490
6491         local dd_bs=65536
6492         local dd_count=$((file_size / dd_bs))
6493
6494         # write data into the files
6495         local i
6496         local j
6497         local file
6498
6499         for i in $(seq $NUMFILES); do
6500                 file=$dir/file$i
6501                 yes | dd bs=$dd_bs count=$dd_count of=$file &>/dev/null ||
6502                         error "write data into $file failed"
6503         done
6504         for i in $(seq $NUMDIRS); do
6505                 for j in $(seq $NUMFILES); do
6506                         file=$dir/dir$i/file$j
6507                         yes|dd bs=$dd_bs count=$dd_count of=$file &>/dev/null ||
6508                                 error "write data into $file failed"
6509                 done
6510         done
6511
6512         # $LFS_MIGRATE will fail if hard link migration is unsupported
6513         if [[ $MDS1_VERSION -gt $(version_code 2.5.55) ]]; then
6514                 createmany -l$dir/dir1/file1 $dir/dir1/link 200 ||
6515                         error "creating links to $dir/dir1/file1 failed"
6516         fi
6517
6518         local expected=-1
6519
6520         [[ $OSTCOUNT -gt 1 ]] && expected=$((OSTCOUNT - 1))
6521
6522         # lfs_migrate file
6523         local cmd="$LFS_MIGRATE -y -c $expected $dir/file1"
6524
6525         echo "$cmd"
6526         eval $cmd || error "$cmd failed"
6527
6528         check_stripe_count $dir/file1 $expected
6529
6530         if [ $MDS1_VERSION -ge $(version_code 2.6.90) ];
6531         then
6532                 # lfs_migrate file onto OST 0 if it is on OST 1, or onto
6533                 # OST 1 if it is on OST 0. This file is small enough to
6534                 # be on only one stripe.
6535                 file=$dir/migr_1_ost
6536                 dd bs=$dd_bs count=1 if=/dev/urandom of=$file >/dev/null 2>&1 ||
6537                         error "write data into $file failed"
6538                 local obdidx=$($LFS getstripe -i $file)
6539                 local oldmd5=$(md5sum $file)
6540                 local newobdidx=0
6541
6542                 [[ $obdidx -eq 0 ]] && newobdidx=1
6543                 cmd="$LFS migrate -i $newobdidx $file"
6544                 echo $cmd
6545                 eval $cmd || error "$cmd failed"
6546
6547                 local realobdix=$($LFS getstripe -i $file)
6548                 local newmd5=$(md5sum $file)
6549
6550                 [[ $newobdidx -ne $realobdix ]] &&
6551                         error "new OST is different (was=$obdidx, "\
6552                               "wanted=$newobdidx, got=$realobdix)"
6553                 [[ "$oldmd5" != "$newmd5" ]] &&
6554                         error "md5sum differ: $oldmd5, $newmd5"
6555         fi
6556
6557         # lfs_migrate dir
6558         cmd="$LFS_MIGRATE -y -c $expected $dir/dir1"
6559         echo "$cmd"
6560         eval $cmd || error "$cmd failed"
6561
6562         for j in $(seq $NUMFILES); do
6563                 check_stripe_count $dir/dir1/file$j $expected
6564         done
6565
6566         # lfs_migrate works with lfs find
6567         cmd="$LFS find -stripe_count $OSTCOUNT -type f $dir |
6568              $LFS_MIGRATE -y -c $expected"
6569         echo "$cmd"
6570         eval $cmd || error "$cmd failed"
6571
6572         for i in $(seq 2 $NUMFILES); do
6573                 check_stripe_count $dir/file$i $expected
6574         done
6575         for i in $(seq 2 $NUMDIRS); do
6576                 for j in $(seq $NUMFILES); do
6577                 check_stripe_count $dir/dir$i/file$j $expected
6578                 done
6579         done
6580 }
6581 run_test 56w "check lfs_migrate -c stripe_count works"
6582
6583 test_56wb() {
6584         local file1=$DIR/$tdir/file1
6585         local create_pool=false
6586         local initial_pool=$($LFS getstripe -p $DIR)
6587         local pool_list=()
6588         local pool=""
6589
6590         echo -n "Creating test dir..."
6591         test_mkdir $DIR/$tdir &> /dev/null || error "cannot create dir"
6592         echo "done."
6593
6594         echo -n "Creating test file..."
6595         touch $file1 || error "cannot create file"
6596         echo "done."
6597
6598         echo -n "Detecting existing pools..."
6599         pool_list=($($LFS pool_list $FSNAME | grep "$FSNAME\." | cut -d. -f2))
6600
6601         if [ ${#pool_list[@]} -gt 0 ]; then
6602                 echo "${pool_list[@]}"
6603                 for thispool in "${pool_list[@]}"; do
6604                         if [[ -z "$initial_pool" ||
6605                               "$initial_pool" != "$thispool" ]]; then
6606                                 pool="$thispool"
6607                                 echo "Using existing pool '$pool'"
6608                                 break
6609                         fi
6610                 done
6611         else
6612                 echo "none detected."
6613         fi
6614         if [ -z "$pool" ]; then
6615                 pool=${POOL:-testpool}
6616                 [ "$initial_pool" = "$pool" ] && pool="testpool2"
6617                 echo -n "Creating pool '$pool'..."
6618                 create_pool=true
6619                 pool_add $pool &> /dev/null ||
6620                         error "pool_add failed"
6621                 echo "done."
6622
6623                 echo -n "Adding target to pool..."
6624                 pool_add_targets $pool 0 0 1 &> /dev/null ||
6625                         error "pool_add_targets failed"
6626                 echo "done."
6627         fi
6628
6629         echo -n "Setting pool using -p option..."
6630         $LFS_MIGRATE -y -q --no-rsync -p $pool $file1 &> /dev/null ||
6631                 error "migrate failed rc = $?"
6632         echo "done."
6633
6634         echo -n "Verifying test file is in pool after migrating..."
6635         [ "$($LFS getstripe -p $file1)" = $pool ] ||
6636                 error "file was not migrated to pool $pool"
6637         echo "done."
6638
6639         echo -n "Removing test file from pool '$pool'..."
6640         # "lfs migrate $file" won't remove the file from the pool
6641         # until some striping information is changed.
6642         $LFS migrate -c 1 $file1 &> /dev/null ||
6643                 error "cannot remove from pool"
6644         [ "$($LFS getstripe -p $file1)" ] &&
6645                 error "pool still set"
6646         echo "done."
6647
6648         echo -n "Setting pool using --pool option..."
6649         $LFS_MIGRATE -y -q --no-rsync --pool $pool $file1 &> /dev/null ||
6650                 error "migrate failed rc = $?"
6651         echo "done."
6652
6653         # Clean up
6654         rm -f $file1
6655         if $create_pool; then
6656                 destroy_test_pools 2> /dev/null ||
6657                         error "destroy test pools failed"
6658         fi
6659 }
6660 run_test 56wb "check lfs_migrate pool support"
6661
6662 test_56wc() {
6663         local file1="$DIR/$tdir/file1"
6664         local parent_ssize
6665         local parent_scount
6666         local cur_ssize
6667         local cur_scount
6668         local orig_ssize
6669
6670         echo -n "Creating test dir..."
6671         test_mkdir $DIR/$tdir &> /dev/null || error "cannot create dir"
6672         $LFS setstripe -S 1M -c 1 "$DIR/$tdir" &> /dev/null ||
6673                 error "cannot set stripe by '-S 1M -c 1'"
6674         echo "done"
6675
6676         echo -n "Setting initial stripe for test file..."
6677         $LFS setstripe -S 512K -c 1 "$file1" &> /dev/null ||
6678                 error "cannot set stripe"
6679         cur_ssize=$($LFS getstripe -S "$file1")
6680         [ $cur_ssize -eq 524288 ] || error "setstripe -S $cur_ssize != 524288"
6681         echo "done."
6682
6683         # File currently set to -S 512K -c 1
6684
6685         # Ensure -c and -S options are rejected when -R is set
6686         echo -n "Verifying incompatible options are detected..."
6687         $LFS_MIGRATE -y -R -c 1 "$file1" &> /dev/null &&
6688                 error "incompatible -c and -R options not detected"
6689         $LFS_MIGRATE -y -R -S 1M "$file1" &> /dev/null &&
6690                 error "incompatible -S and -R options not detected"
6691         echo "done."
6692
6693         # Ensure unrecognized options are passed through to 'lfs migrate'
6694         echo -n "Verifying -S option is passed through to lfs migrate..."
6695         $LFS_MIGRATE -y -S 1M "$file1" &> /dev/null ||
6696                 error "migration failed"
6697         cur_ssize=$($LFS getstripe -S "$file1")
6698         [ $cur_ssize -eq 1048576 ] || error "migrate -S $cur_ssize != 1048576"
6699         echo "done."
6700
6701         # File currently set to -S 1M -c 1
6702
6703         # Ensure long options are supported
6704         echo -n "Verifying long options supported..."
6705         $LFS_MIGRATE -y --non-block "$file1" &> /dev/null ||
6706                 error "long option without argument not supported"
6707         $LFS_MIGRATE -y --stripe-size 512K "$file1" &> /dev/null ||
6708                 error "long option with argument not supported"
6709         cur_ssize=$($LFS getstripe -S "$file1")
6710         [ $cur_ssize -eq 524288 ] ||
6711                 error "migrate --stripe-size $cur_ssize != 524288"
6712         echo "done."
6713
6714         # File currently set to -S 512K -c 1
6715
6716         if [ "$OSTCOUNT" -gt 1 ]; then
6717                 echo -n "Verifying explicit stripe count can be set..."
6718                 $LFS_MIGRATE -y -c 2 "$file1" &> /dev/null ||
6719                         error "migrate failed"
6720                 cur_scount=$($LFS getstripe -c "$file1")
6721                 [ $cur_scount -eq 2 ] || error "migrate -c $cur_scount != 2"
6722                 echo "done."
6723         fi
6724
6725         # File currently set to -S 512K -c 1 or -S 512K -c 2
6726
6727         # Ensure parent striping is used if -R is set, and no stripe
6728         # count or size is specified
6729         echo -n "Setting stripe for parent directory..."
6730         $LFS setstripe -S 2M -c 1 "$DIR/$tdir" &> /dev/null ||
6731                 error "cannot set stripe '-S 2M -c 1'"
6732         echo "done."
6733
6734         echo -n "Verifying restripe option uses parent stripe settings..."
6735         parent_ssize=$($LFS getstripe -S $DIR/$tdir 2>/dev/null)
6736         parent_scount=$($LFS getstripe -c $DIR/$tdir 2>/dev/null)
6737         $LFS_MIGRATE -y -R "$file1" &> /dev/null ||
6738                 error "migrate failed"
6739         cur_ssize=$($LFS getstripe -S "$file1")
6740         [ $cur_ssize -eq $parent_ssize ] ||
6741                 error "migrate -R stripe_size $cur_ssize != $parent_ssize"
6742         cur_scount=$($LFS getstripe -c "$file1")
6743         [ $cur_scount -eq $parent_scount ] ||
6744                 error "migrate -R stripe_count $cur_scount != $parent_scount"
6745         echo "done."
6746
6747         # File currently set to -S 1M -c 1
6748
6749         # Ensure striping is preserved if -R is not set, and no stripe
6750         # count or size is specified
6751         echo -n "Verifying striping size preserved when not specified..."
6752         orig_ssize=$($LFS getstripe -S "$file1" 2>/dev/null)
6753         $LFS setstripe -S 2M -c 1 "$DIR/$tdir" &> /dev/null ||
6754                 error "cannot set stripe on parent directory"
6755         $LFS_MIGRATE -y "$file1" &> /dev/null ||
6756                 error "migrate failed"
6757         cur_ssize=$($LFS getstripe -S "$file1")
6758         [ $cur_ssize -eq $orig_ssize ] ||
6759                 error "migrate by default $cur_ssize != $orig_ssize"
6760         echo "done."
6761
6762         # Ensure file name properly detected when final option has no argument
6763         echo -n "Verifying file name properly detected..."
6764         $LFS_MIGRATE -y "$file1" &> /dev/null ||
6765                 error "file name interpreted as option argument"
6766         echo "done."
6767
6768         # Clean up
6769         rm -f "$file1"
6770 }
6771 run_test 56wc "check unrecognized options for lfs_migrate are passed through"
6772
6773 test_56wd() {
6774         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
6775
6776         local file1=$DIR/$tdir/file1
6777
6778         echo -n "Creating test dir..."
6779         test_mkdir $DIR/$tdir || error "cannot create dir"
6780         echo "done."
6781
6782         echo -n "Creating test file..."
6783         touch $file1
6784         echo "done."
6785
6786         # Ensure 'lfs migrate' will fail by using a non-existent option,
6787         # and make sure rsync is not called to recover
6788         echo -n "Make sure --no-rsync option works..."
6789         $LFS_MIGRATE -y --no-rsync --invalid-opt $file1 2>&1 |
6790                 grep -q 'refusing to fall back to rsync' ||
6791                 error "rsync was called with --no-rsync set"
6792         echo "done."
6793
6794         # Ensure rsync is called without trying 'lfs migrate' first
6795         echo -n "Make sure --rsync option works..."
6796         $LFS_MIGRATE -y --rsync --invalid-opt $file1 2>&1 |
6797                 grep -q 'falling back to rsync' &&
6798                 error "lfs migrate was called with --rsync set"
6799         echo "done."
6800
6801         echo -n "Make sure --rsync and --no-rsync options are exclusive..."
6802         $LFS_MIGRATE -y --rsync --no-rsync $file1 2>&1 |
6803                 grep -q 'at the same time' ||
6804                 error "--rsync and --no-rsync accepted concurrently"
6805         echo "done."
6806
6807         # Clean up
6808         rm -f $file1
6809 }
6810 run_test 56wd "check lfs_migrate --rsync and --no-rsync work"
6811
6812 test_56we() {
6813         local td=$DIR/$tdir
6814         local tf=$td/$tfile
6815
6816         test_mkdir $td || error "cannot create $td"
6817         touch $tf || error "cannot touch $tf"
6818
6819         echo -n "Make sure --non-direct|-D works..."
6820         $LFS_MIGRATE -y --non-direct -v $tf 2>&1 |
6821                 grep -q "lfs migrate --non-direct" ||
6822                 error "--non-direct option cannot work correctly"
6823         $LFS_MIGRATE -y -D -v $tf 2>&1 |
6824                 grep -q "lfs migrate -D" ||
6825                 error "-D option cannot work correctly"
6826         echo "done."
6827 }
6828 run_test 56we "check lfs_migrate --non-direct|-D support"
6829
6830 test_56x() {
6831         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
6832         check_swap_layouts_support
6833
6834         local dir=$DIR/$tdir
6835         local ref1=/etc/passwd
6836         local file1=$dir/file1
6837
6838         test_mkdir $dir || error "creating dir $dir"
6839         $LFS setstripe -c 2 $file1
6840         cp $ref1 $file1
6841         $LFS migrate -c 1 $file1 || error "migrate failed rc = $?"
6842         stripe=$($LFS getstripe -c $file1)
6843         [[ $stripe == 1 ]] || error "stripe of $file1 is $stripe != 1"
6844         cmp $file1 $ref1 || error "content mismatch $file1 differs from $ref1"
6845
6846         # clean up
6847         rm -f $file1
6848 }
6849 run_test 56x "lfs migration support"
6850
6851 test_56xa() {
6852         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
6853         check_swap_layouts_support
6854
6855         local dir=$DIR/$tdir/$testnum
6856
6857         test_mkdir -p $dir
6858
6859         local ref1=/etc/passwd
6860         local file1=$dir/file1
6861
6862         $LFS setstripe -c 2 $file1
6863         cp $ref1 $file1
6864         $LFS migrate --block -c 1 $file1 || error "migrate failed rc = $?"
6865
6866         local stripe=$($LFS getstripe -c $file1)
6867
6868         [[ $stripe == 1 ]] || error "stripe of $file1 is $stripe != 1"
6869         cmp $file1 $ref1 || error "content mismatch $file1 differs from $ref1"
6870
6871         # clean up
6872         rm -f $file1
6873 }
6874 run_test 56xa "lfs migration --block support"
6875
6876 check_migrate_links() {
6877         local dir="$1"
6878         local file1="$dir/file1"
6879         local begin="$2"
6880         local count="$3"
6881         local runas="$4"
6882         local total_count=$(($begin + $count - 1))
6883         local symlink_count=10
6884         local uniq_count=10
6885
6886         if [ ! -f "$file1" ]; then
6887                 echo -n "creating initial file..."
6888                 $LFS setstripe -c 1 -S "512k" "$file1" ||
6889                         error "cannot setstripe initial file"
6890                 echo "done"
6891
6892                 echo -n "creating symlinks..."
6893                 for s in $(seq 1 $symlink_count); do
6894                         ln -s "$file1" "$dir/slink$s" ||
6895                                 error "cannot create symlinks"
6896                 done
6897                 echo "done"
6898
6899                 echo -n "creating nonlinked files..."
6900                 createmany -o "$dir/uniq" 1 10 &> /dev/null ||
6901                         error "cannot create nonlinked files"
6902                 echo "done"
6903         fi
6904
6905         # create hard links
6906         if [ ! -f "$dir/file$total_count" ]; then
6907                 echo -n "creating hard links $begin:$total_count..."
6908                 createmany -l"$file1" "$dir/file" "$begin" "$count" &>  \
6909                         /dev/null || error "cannot create hard links"
6910                 echo "done"
6911         fi
6912
6913         echo -n "checking number of hard links listed in xattrs..."
6914         local fid=$($LFS getstripe -F "$file1")
6915         local paths=($($LFS fid2path "$MOUNT" "$fid" 2> /dev/null))
6916
6917         echo "${#paths[*]}"
6918         if [ ${#paths[*]} -lt $total_count -a "$begin" -eq 2  ]; then
6919                         skip "hard link list has unexpected size, skipping test"
6920         fi
6921         if [ ${#paths[*]} -ge $total_count -a "$begin" -ne 2  ]; then
6922                         error "link names should exceed xattrs size"
6923         fi
6924
6925         echo -n "migrating files..."
6926         local migrate_out=$($runas $LFS_MIGRATE -y -S '1m' $dir)
6927         local rc=$?
6928         [ $rc -eq 0 ] || error "migrate failed rc = $rc"
6929         echo "done"
6930
6931         # make sure all links have been properly migrated
6932         echo -n "verifying files..."
6933         fid=$($LFS getstripe -F "$file1") ||
6934                 error "cannot get fid for file $file1"
6935         for i in $(seq 2 $total_count); do
6936                 local fid2=$($LFS getstripe -F $dir/file$i)
6937
6938                 [ "$fid2" == "$fid" ] ||
6939                         error "migrated hard link has mismatched FID"
6940         done
6941
6942         # make sure hard links were properly detected, and migration was
6943         # performed only once for the entire link set; nonlinked files should
6944         # also be migrated
6945         local actual=$(grep -c 'done' <<< "$migrate_out")
6946         local expected=$(($uniq_count + 1))
6947
6948         [ "$actual" -eq  "$expected" ] ||
6949                 error "hard links individually migrated ($actual != $expected)"
6950
6951         # make sure the correct number of hard links are present
6952         local hardlinks=$(stat -c '%h' "$file1")
6953
6954         [ $hardlinks -eq $total_count ] ||
6955                 error "num hard links $hardlinks != $total_count"
6956         echo "done"
6957
6958         return 0
6959 }
6960
6961 test_56xb() {
6962         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
6963                 skip "Need MDS version at least 2.10.55"
6964
6965         local dir="$DIR/$tdir"
6966
6967         test_mkdir "$dir" || error "cannot create dir $dir"
6968
6969         echo "testing lfs migrate mode when all links fit within xattrs"
6970         LFS_MIGRATE_RSYNC_MODE=false check_migrate_links "$dir" 2 99
6971
6972         echo "testing rsync mode when all links fit within xattrs"
6973         LFS_MIGRATE_RSYNC_MODE=true check_migrate_links "$dir" 2 99
6974
6975         echo "testing lfs migrate mode when all links do not fit within xattrs"
6976         LFS_MIGRATE_RSYNC_MODE=false check_migrate_links "$dir" 101 100
6977
6978         echo "testing rsync mode when all links do not fit within xattrs"
6979         LFS_MIGRATE_RSYNC_MODE=true check_migrate_links "$dir" 101 100
6980
6981         chown -R $RUNAS_ID $dir
6982         echo "testing non-root lfs migrate mode when not all links are in xattr"
6983         LFS_MIGRATE_RSYNC_MODE=false check_migrate_links "$dir" 101 100 "$RUNAS"
6984
6985         # clean up
6986         rm -rf $dir
6987 }
6988 run_test 56xb "lfs migration hard link support"
6989
6990 test_56xc() {
6991         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
6992
6993         local dir="$DIR/$tdir"
6994
6995         test_mkdir "$dir" || error "cannot create dir $dir"
6996
6997         # Test 1: ensure file < 1 GB is always migrated with 1 stripe
6998         echo -n "Setting initial stripe for 20MB test file..."
6999         $LFS setstripe -c 2 -i 0 "$dir/20mb" ||
7000                 error "cannot setstripe 20MB file"
7001         echo "done"
7002         echo -n "Sizing 20MB test file..."
7003         truncate "$dir/20mb" 20971520 || error "cannot create 20MB test file"
7004         echo "done"
7005         echo -n "Verifying small file autostripe count is 1..."
7006         $LFS_MIGRATE -y -A -C 1 "$dir/20mb" ||
7007                 error "cannot migrate 20MB file"
7008         local stripe_count=$($LFS getstripe -c "$dir/20mb") ||
7009                 error "cannot get stripe for $dir/20mb"
7010         [ $stripe_count -eq 1 ] ||
7011                 error "unexpected stripe count $stripe_count for 20MB file"
7012         rm -f "$dir/20mb"
7013         echo "done"
7014
7015         # Test 2: File is small enough to fit within the available space on
7016         # sqrt(size_in_gb) + 1 OSTs but is larger than 1GB.  The file must
7017         # have at least an additional 1KB for each desired stripe for test 3
7018         echo -n "Setting stripe for 1GB test file..."
7019         $LFS setstripe -c 1 -i 0 "$dir/1gb" || error "cannot setstripe 1GB file"
7020         echo "done"
7021         echo -n "Sizing 1GB test file..."
7022         # File size is 1GB + 3KB
7023         truncate "$dir/1gb" 1073744896 || error "cannot create 1GB test file"
7024         echo "done"
7025
7026         # need at least 512MB per OST for 1GB file to fit in 2 stripes
7027         local avail=$($LCTL get_param -n llite.$FSNAME*.kbytesavail)
7028         if (( avail > 524288 * OSTCOUNT )); then
7029                 echo -n "Migrating 1GB file..."
7030                 $LFS_MIGRATE -y -A -C 1 "$dir/1gb" ||
7031                         error "cannot migrate 1GB file"
7032                 echo "done"
7033                 echo -n "Verifying autostripe count is sqrt(n) + 1..."
7034                 stripe_count=$($LFS getstripe -c "$dir/1gb") ||
7035                         error "cannot getstripe for 1GB file"
7036                 [ $stripe_count -eq 2 ] ||
7037                         error "unexpected stripe count $stripe_count != 2"
7038                 echo "done"
7039         fi
7040
7041         # Test 3: File is too large to fit within the available space on
7042         # sqrt(n) + 1 OSTs.  Simulate limited available space with -X
7043         if [ $OSTCOUNT -ge 3 ]; then
7044                 # The required available space is calculated as
7045                 # file size (1GB + 3KB) / OST count (3).
7046                 local kb_per_ost=349526
7047
7048                 echo -n "Migrating 1GB file with limit..."
7049                 $LFS_MIGRATE -y -A -C 1 -X $kb_per_ost "$dir/1gb" ||
7050                         error "cannot migrate 1GB file with limit"
7051                 echo "done"
7052
7053                 stripe_count=$($LFS getstripe -c "$dir/1gb")
7054                 echo -n "Verifying 1GB autostripe count with limited space..."
7055                 [ "$stripe_count" -a $stripe_count -ge 3 ] ||
7056                         error "unexpected stripe count $stripe_count (min 3)"
7057                 echo "done"
7058         fi
7059
7060         # clean up
7061         rm -rf $dir
7062 }
7063 run_test 56xc "lfs migration autostripe"
7064
7065 test_56xd() {
7066         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7067
7068         local dir=$DIR/$tdir
7069         local f_mgrt=$dir/$tfile.mgrt
7070         local f_yaml=$dir/$tfile.yaml
7071         local f_copy=$dir/$tfile.copy
7072         local layout_yaml="-E 1M -S 512K -c 1 -E -1 -S 1M -c 2 -i 0"
7073         local layout_copy="-c 2 -S 2M -i 1"
7074         local yamlfile=$dir/yamlfile
7075         local layout_before;
7076         local layout_after;
7077
7078         test_mkdir "$dir" || error "cannot create dir $dir"
7079         $LFS setstripe $layout_yaml $f_yaml ||
7080                 error "cannot setstripe $f_yaml with layout $layout_yaml"
7081         $LFS getstripe --yaml $f_yaml > $yamlfile
7082         $LFS setstripe $layout_copy $f_copy ||
7083                 error "cannot setstripe $f_copy with layout $layout_copy"
7084         touch $f_mgrt
7085         dd if=/dev/zero of=$f_mgrt bs=1M count=4
7086
7087         # 1. test option --yaml
7088         $LFS_MIGRATE -y --yaml $yamlfile $f_mgrt ||
7089                 error "cannot migrate $f_mgrt with --yaml $yamlfile"
7090         layout_before=$(get_layout_param $f_yaml)
7091         layout_after=$(get_layout_param $f_mgrt)
7092         [ "$layout_after" == "$layout_before" ] ||
7093                 error "lfs_migrate --yaml: $layout_after != $layout_before"
7094
7095         # 2. test option --copy
7096         $LFS_MIGRATE -y --copy $f_copy $f_mgrt ||
7097                 error "cannot migrate $f_mgrt with --copy $f_copy"
7098         layout_before=$(get_layout_param $f_copy)
7099         layout_after=$(get_layout_param $f_mgrt)
7100         [ "$layout_after" == "$layout_before" ] ||
7101                 error "lfs_migrate --copy: $layout_after != $layout_before"
7102 }
7103 run_test 56xd "check lfs_migrate --yaml and --copy support"
7104
7105 test_56xe() {
7106         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7107
7108         local dir=$DIR/$tdir
7109         local f_comp=$dir/$tfile
7110         local layout="-E 1M -S 512K -c 1 -E -1 -S 1M -c 2 -i 0"
7111         local layout_before=""
7112         local layout_after=""
7113
7114         test_mkdir "$dir" || error "cannot create dir $dir"
7115         $LFS setstripe $layout $f_comp ||
7116                 error "cannot setstripe $f_comp with layout $layout"
7117         layout_before=$(get_layout_param $f_comp)
7118         dd if=/dev/zero of=$f_comp bs=1M count=4
7119
7120         # 1. migrate a comp layout file by lfs_migrate
7121         $LFS_MIGRATE -y $f_comp || error "cannot migrate $f_comp by lfs_migrate"
7122         layout_after=$(get_layout_param $f_comp)
7123         [ "$layout_before" == "$layout_after" ] ||
7124                 error "lfs_migrate: $layout_before != $layout_after"
7125
7126         # 2. migrate a comp layout file by lfs migrate
7127         $LFS migrate $f_comp || error "cannot migrate $f_comp by lfs migrate"
7128         layout_after=$(get_layout_param $f_comp)
7129         [ "$layout_before" == "$layout_after" ] ||
7130                 error "lfs migrate: $layout_before != $layout_after"
7131 }
7132 run_test 56xe "migrate a composite layout file"
7133
7134 test_56xf() {
7135         [[ $OSTCOUNT -ge 2 ]] || skip_env "needs >= 2 OSTs"
7136
7137         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
7138                 skip "Need server version at least 2.13.53"
7139
7140         local dir=$DIR/$tdir
7141         local f_comp=$dir/$tfile
7142         local layout="-E 1M -c1 -E -1 -c2"
7143         local fid_before=""
7144         local fid_after=""
7145
7146         test_mkdir "$dir" || error "cannot create dir $dir"
7147         $LFS setstripe $layout $f_comp ||
7148                 error "cannot setstripe $f_comp with layout $layout"
7149         fid_before=$($LFS getstripe --fid $f_comp)
7150         dd if=/dev/zero of=$f_comp bs=1M count=4
7151
7152         # 1. migrate a comp layout file to a comp layout
7153         $LFS migrate $f_comp || error "cannot migrate $f_comp by lfs migrate"
7154         fid_after=$($LFS getstripe --fid $f_comp)
7155         [ "$fid_before" == "$fid_after" ] ||
7156                 error "comp-to-comp migrate: $fid_before != $fid_after"
7157
7158         # 2. migrate a comp layout file to a plain layout
7159         $LFS migrate -c2 $f_comp ||
7160                 error "cannot migrate $f_comp by lfs migrate"
7161         fid_after=$($LFS getstripe --fid $f_comp)
7162         [ "$fid_before" == "$fid_after" ] ||
7163                 error "comp-to-plain migrate: $fid_before != $fid_after"
7164
7165         # 3. migrate a plain layout file to a comp layout
7166         $LFS migrate $layout $f_comp ||
7167                 error "cannot migrate $f_comp by lfs migrate"
7168         fid_after=$($LFS getstripe --fid $f_comp)
7169         [ "$fid_before" == "$fid_after" ] ||
7170                 error "plain-to-comp migrate: $fid_before != $fid_after"
7171 }
7172 run_test 56xf "FID is not lost during migration of a composite layout file"
7173
7174 test_56y() {
7175         [ $MDS1_VERSION -lt $(version_code 2.4.53) ] &&
7176                 skip "No HSM $(lustre_build_version $SINGLEMDS) MDS < 2.4.53"
7177
7178         local res=""
7179         local dir=$DIR/$tdir
7180         local f1=$dir/file1
7181         local f2=$dir/file2
7182
7183         test_mkdir -p $dir || error "creating dir $dir"
7184         touch $f1 || error "creating std file $f1"
7185         $MULTIOP $f2 H2c || error "creating released file $f2"
7186
7187         # a directory can be raid0, so ask only for files
7188         res=$($LFS find $dir -L raid0 -type f | wc -l)
7189         [[ $res == 2 ]] || error "search raid0: found $res files != 2"
7190
7191         res=$($LFS find $dir \! -L raid0 -type f | wc -l)
7192         [[ $res == 0 ]] || error "search !raid0: found $res files != 0"
7193
7194         # only files can be released, so no need to force file search
7195         res=$($LFS find $dir -L released)
7196         [[ $res == $f2 ]] || error "search released: found $res != $f2"
7197
7198         res=$($LFS find $dir -type f \! -L released)
7199         [[ $res == $f1 ]] || error "search !released: found $res != $f1"
7200 }
7201 run_test 56y "lfs find -L raid0|released"
7202
7203 test_56z() { # LU-4824
7204         # This checks to make sure 'lfs find' continues after errors
7205         # There are two classes of errors that should be caught:
7206         # - If multiple paths are provided, all should be searched even if one
7207         #   errors out
7208         # - If errors are encountered during the search, it should not terminate
7209         #   early
7210         local dir=$DIR/$tdir
7211         local i
7212
7213         test_mkdir $dir
7214         for i in d{0..9}; do
7215                 test_mkdir $dir/$i
7216                 touch $dir/$i/$tfile
7217         done
7218         $LFS find $DIR/non_existent_dir $dir &&
7219                 error "$LFS find did not return an error"
7220         # Make a directory unsearchable. This should NOT be the last entry in
7221         # directory order.  Arbitrarily pick the 6th entry
7222         chmod 700 $($LFS find $dir -type d | sed '6!d')
7223
7224         $RUNAS $LFS find $DIR/non_existent $dir
7225         local count=$($RUNAS $LFS find $DIR/non_existent $dir | wc -l)
7226
7227         # The user should be able to see 10 directories and 9 files
7228         (( count == 19 )) ||
7229                 error "$LFS find found $count != 19 entries after error"
7230 }
7231 run_test 56z "lfs find should continue after an error"
7232
7233 test_56aa() { # LU-5937
7234         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
7235
7236         local dir=$DIR/$tdir
7237
7238         mkdir $dir
7239         $LFS setdirstripe -c$MDSCOUNT $dir/striped_dir
7240
7241         createmany -o $dir/striped_dir/${tfile}- 1024
7242         local dirs=$($LFS find --size +8k $dir/)
7243
7244         [ -n "$dirs" ] || error "lfs find --size wrong under striped dir"
7245 }
7246 run_test 56aa "lfs find --size under striped dir"
7247
7248 test_56ab() { # LU-10705
7249         test_mkdir $DIR/$tdir
7250         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=8k count=1 seek=2k
7251         dd if=/dev/zero of=$DIR/$tdir/$tfile.2 bs=4k count=1 seek=4k
7252         dd if=/dev/zero of=$DIR/$tdir/$tfile.3 bs=1M count=2 seek=16
7253         # Flush writes to ensure valid blocks.  Need to be more thorough for
7254         # ZFS, since blocks are not allocated/returned to client immediately.
7255         sync_all_data
7256         wait_zfs_commit ost1 2
7257         cancel_lru_locks osc
7258         ls -ls $DIR/$tdir
7259
7260         local files=$($LFS find --size +16M $DIR/$tdir | wc -l)
7261
7262         [[ $files == 3 ]] || error ">16M size files $files isn't 3 as expected"
7263
7264         files=$($LFS find --blocks +1M $DIR/$tdir | wc -l)
7265         [[ $files == 1 ]] || error ">1M blocks files $files isn't 1 as expected"
7266
7267         rm -f $DIR/$tdir/$tfile.[123]
7268 }
7269 run_test 56ab "lfs find --blocks"
7270
7271 test_56ba() {
7272         [ $MDS1_VERSION -lt $(version_code 2.10.50) ] &&
7273                 skip "Need MDS version at least 2.10.50"
7274
7275         # Create composite files with one component
7276         local dir=$DIR/$tdir
7277
7278         setup_56 $dir/1Mfiles 5 1 "-S 1M --component-end 1M"
7279         # Create composite files with three components
7280         setup_56 $dir/2Mfiles 5 2 "-E 2M -S 1M -E 4M -E 6M"
7281         # Create non-composite files
7282         createmany -o $dir/${tfile}- 10
7283
7284         local nfiles=$($LFS find --component-end 1M --type f $dir | wc -l)
7285
7286         [[ $nfiles == 10 ]] ||
7287                 error "lfs find -E 1M found $nfiles != 10 files"
7288
7289         nfiles=$($LFS find ! -E 1M --type f $dir | wc -l)
7290         [[ $nfiles == 25 ]] ||
7291                 error "lfs find ! -E 1M found $nfiles != 25 files"
7292
7293         # All files have a component that starts at 0
7294         nfiles=$($LFS find --component-start 0 --type f $dir | wc -l)
7295         [[ $nfiles == 35 ]] ||
7296                 error "lfs find --component-start 0 - $nfiles != 35 files"
7297
7298         nfiles=$($LFS find --component-start 2M --type f $dir | wc -l)
7299         [[ $nfiles == 15 ]] ||
7300                 error "lfs find --component-start 2M - $nfiles != 15 files"
7301
7302         # All files created here have a componenet that does not starts at 2M
7303         nfiles=$($LFS find ! --component-start 2M --type f $dir | wc -l)
7304         [[ $nfiles == 35 ]] ||
7305                 error "lfs find ! --component-start 2M - $nfiles != 35 files"
7306
7307         # Find files with a specified number of components
7308         local nfiles=$($LFS find --component-count 3 --type f $dir | wc -l)
7309         [[ $nfiles == 15 ]] ||
7310                 error "lfs find --component-count 3 - $nfiles != 15 files"
7311
7312         # Remember non-composite files have a component count of zero
7313         local nfiles=$($LFS find --component-count 0 --type f $dir | wc -l)
7314         [[ $nfiles == 10 ]] ||
7315                 error "lfs find --component-count 0 - $nfiles != 10 files"
7316
7317         nfiles=$($LFS find ! --component-count 3 --type f $dir | wc -l)
7318         [[ $nfiles == 20 ]] ||
7319                 error "lfs find ! --component-count 3 - $nfiles != 20 files"
7320
7321         # All files have a flag called "init"
7322         local nfiles=$($LFS find --component-flags init --type f $dir | wc -l)
7323         [[ $nfiles == 35 ]] ||
7324                 error "lfs find --component-flags init - $nfiles != 35 files"
7325
7326         # Multi-component files will have a component not initialized
7327         local nfiles=$($LFS find ! --component-flags init --type f $dir | wc -l)
7328         [[ $nfiles == 15 ]] ||
7329                 error "lfs find !--component-flags init - $nfiles != 15 files"
7330
7331         rm -rf $dir
7332
7333 }
7334 run_test 56ba "test lfs find --component-end, -start, -count, and -flags"
7335
7336 test_56ca() {
7337         [[ $MDS1_VERSION -ge $(version_code 2.10.57) ]] ||
7338                 skip "Need MDS version at least 2.10.57"
7339
7340         local td=$DIR/$tdir
7341         local tf=$td/$tfile
7342         local dir
7343         local nfiles
7344         local cmd
7345         local i
7346         local j
7347
7348         # create mirrored directories and mirrored files
7349         mkdir $td || error "mkdir $td failed"
7350         $LFS mirror create -N3 $td || error "create mirrored dir $td failed"
7351         createmany -o $tf- 10 || error "create $tf- failed"
7352
7353         for i in $(seq 2); do
7354                 dir=$td/dir$i
7355                 mkdir $dir || error "mkdir $dir failed"
7356                 $LFS mirror create -N$((3 + i)) $dir ||
7357                         error "create mirrored dir $dir failed"
7358                 createmany -o $dir/$tfile- 10 ||
7359                         error "create $dir/$tfile- failed"
7360         done
7361
7362         # change the states of some mirrored files
7363         echo foo > $tf-6
7364         for i in $(seq 2); do
7365                 dir=$td/dir$i
7366                 for j in $(seq 4 9); do
7367                         echo foo > $dir/$tfile-$j
7368                 done
7369         done
7370
7371         # find mirrored files with specific mirror count
7372         cmd="$LFS find --mirror-count 3 --type f $td"
7373         nfiles=$($cmd | wc -l)
7374         [[ $nfiles = 10 ]] || error "$cmd: $nfiles != 10 files"
7375
7376         cmd="$LFS find ! --mirror-count 3 --type f $td"
7377         nfiles=$($cmd | wc -l)
7378         [[ $nfiles = 20 ]] || error "$cmd: $nfiles != 20 files"
7379
7380         cmd="$LFS find --mirror-count +2 --type f $td"
7381         nfiles=$($cmd | wc -l)
7382         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
7383
7384         cmd="$LFS find --mirror-count -6 --type f $td"
7385         nfiles=$($cmd | wc -l)
7386         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
7387
7388         # find mirrored files with specific file state
7389         cmd="$LFS find --maxdepth 1 --mirror-state=^ro --type f $td"
7390         [[ $($cmd) = $tf-6 ]] || error "$cmd: didn't return $tf-6"
7391
7392         cmd="$LFS find --mirror-state=ro --type f $td"
7393         nfiles=$($cmd | wc -l)
7394         [[ $nfiles = 17 ]] || error "$cmd: $nfiles != 17 files"
7395
7396         cmd="$LFS find ! --mirror-state=ro --type f $td"
7397         nfiles=$($cmd | wc -l)
7398         [[ $nfiles = 13 ]] || error "$cmd: $nfiles != 13 files"
7399
7400         cmd="$LFS find --mirror-state=wp --type f $td"
7401         nfiles=$($cmd | wc -l)
7402         [[ $nfiles = 13 ]] || error "$cmd: $nfiles != 13 files"
7403
7404         cmd="$LFS find ! --mirror-state=sp --type f $td"
7405         nfiles=$($cmd | wc -l)
7406         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
7407 }
7408 run_test 56ca "check lfs find --mirror-count|-N and --mirror-state"
7409
7410 test_57a() {
7411         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7412         # note test will not do anything if MDS is not local
7413         if [ "$mds1_FSTYPE" != ldiskfs ]; then
7414                 skip_env "ldiskfs only test"
7415         fi
7416         remote_mds_nodsh && skip "remote MDS with nodsh"
7417
7418         local MNTDEV="osd*.*MDT*.mntdev"
7419         DEV=$(do_facet $SINGLEMDS lctl get_param -n $MNTDEV)
7420         [ -z "$DEV" ] && error "can't access $MNTDEV"
7421         for DEV in $(do_facet $SINGLEMDS lctl get_param -n $MNTDEV); do
7422                 do_facet $SINGLEMDS $DUMPE2FS -h $DEV > $TMP/t57a.dump ||
7423                         error "can't access $DEV"
7424                 DEVISIZE=$(awk '/Inode size:/ { print $3 }' $TMP/t57a.dump)
7425                 [[ $DEVISIZE -gt 128 ]] || error "inode size $DEVISIZE"
7426                 rm $TMP/t57a.dump
7427         done
7428 }
7429 run_test 57a "verify MDS filesystem created with large inodes =="
7430
7431 test_57b() {
7432         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7433         if [ "$mds1_FSTYPE" != ldiskfs ]; then
7434                 skip_env "ldiskfs only test"
7435         fi
7436         remote_mds_nodsh && skip "remote MDS with nodsh"
7437
7438         local dir=$DIR/$tdir
7439         local filecount=100
7440         local file1=$dir/f1
7441         local fileN=$dir/f$filecount
7442
7443         rm -rf $dir || error "removing $dir"
7444         test_mkdir -c1 $dir
7445         local mdtidx=$($LFS getstripe -m $dir)
7446         local mdtname=MDT$(printf %04x $mdtidx)
7447         local facet=mds$((mdtidx + 1))
7448
7449         echo "mcreating $filecount files"
7450         createmany -m $dir/f 1 $filecount || error "creating files in $dir"
7451
7452         # verify that files do not have EAs yet
7453         $LFS getstripe $file1 2>&1 | grep -q "no stripe" ||
7454                 error "$file1 has an EA"
7455         $LFS getstripe $fileN 2>&1 | grep -q "no stripe" ||
7456                 error "$fileN has an EA"
7457
7458         sync
7459         sleep 1
7460         df $dir  #make sure we get new statfs data
7461         local mdsfree=$(do_facet $facet \
7462                         lctl get_param -n osd*.*$mdtname.kbytesfree)
7463         local mdcfree=$(lctl get_param -n mdc.*$mdtname-mdc-*.kbytesfree)
7464         local file
7465
7466         echo "opening files to create objects/EAs"
7467         for file in $(seq -f $dir/f%g 1 $filecount); do
7468                 $OPENFILE -f O_RDWR $file > /dev/null 2>&1 ||
7469                         error "opening $file"
7470         done
7471
7472         # verify that files have EAs now
7473         $LFS getstripe $file1 | grep -q "obdidx" || error "$file1 missing EA"
7474         $LFS getstripe $fileN | grep -q "obdidx" || error "$fileN missing EA"
7475
7476         sleep 1  #make sure we get new statfs data
7477         df $dir
7478         local mdsfree2=$(do_facet $facet \
7479                          lctl get_param -n osd*.*$mdtname.kbytesfree)
7480         local mdcfree2=$(lctl get_param -n mdc.*$mdtname-mdc-*.kbytesfree)
7481
7482         if [[ $mdcfree2 -lt $((mdcfree - 16)) ]]; then
7483                 if [ "$mdsfree" != "$mdsfree2" ]; then
7484                         error "MDC before $mdcfree != after $mdcfree2"
7485                 else
7486                         echo "MDC before $mdcfree != after $mdcfree2"
7487                         echo "unable to confirm if MDS has large inodes"
7488                 fi
7489         fi
7490         rm -rf $dir
7491 }
7492 run_test 57b "default LOV EAs are stored inside large inodes ==="
7493
7494 test_58() {
7495         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7496         [ -z "$(which wiretest 2>/dev/null)" ] &&
7497                         skip_env "could not find wiretest"
7498
7499         wiretest
7500 }
7501 run_test 58 "verify cross-platform wire constants =============="
7502
7503 test_59() {
7504         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7505
7506         echo "touch 130 files"
7507         createmany -o $DIR/f59- 130
7508         echo "rm 130 files"
7509         unlinkmany $DIR/f59- 130
7510         sync
7511         # wait for commitment of removal
7512         wait_delete_completed
7513 }
7514 run_test 59 "verify cancellation of llog records async ========="
7515
7516 TEST60_HEAD="test_60 run $RANDOM"
7517 test_60a() {
7518         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7519         remote_mgs_nodsh && skip "remote MGS with nodsh"
7520         do_facet mgs "! which run-llog.sh &> /dev/null" &&
7521                 do_facet mgs "! ls run-llog.sh &> /dev/null" &&
7522                         skip_env "missing subtest run-llog.sh"
7523
7524         log "$TEST60_HEAD - from kernel mode"
7525         do_facet mgs "$LCTL dk > /dev/null"
7526         do_facet mgs "bash run-llog.sh" || error "run-llog.sh failed"
7527         do_facet mgs $LCTL dk > $TMP/$tfile
7528
7529         # LU-6388: test llog_reader
7530         local llog_reader=$(do_facet mgs "which llog_reader 2> /dev/null")
7531         llog_reader=${llog_reader:-$LUSTRE/utils/llog_reader}
7532         [ -z $(do_facet mgs ls -d $llog_reader 2> /dev/null) ] &&
7533                         skip_env "missing llog_reader"
7534         local fstype=$(facet_fstype mgs)
7535         [ $fstype != ldiskfs -a $fstype != zfs ] &&
7536                 skip_env "Only for ldiskfs or zfs type mgs"
7537
7538         local mntpt=$(facet_mntpt mgs)
7539         local mgsdev=$(mgsdevname 1)
7540         local fid_list
7541         local fid
7542         local rec_list
7543         local rec
7544         local rec_type
7545         local obj_file
7546         local path
7547         local seq
7548         local oid
7549         local pass=true
7550
7551         #get fid and record list
7552         fid_list=($(awk '/9_sub.*record/ { print $NF }' $TMP/$tfile |
7553                 tail -n 4))
7554         rec_list=($(awk '/9_sub.*record/ { print $((NF-3)) }' $TMP/$tfile |
7555                 tail -n 4))
7556         #remount mgs as ldiskfs or zfs type
7557         stop mgs || error "stop mgs failed"
7558         mount_fstype mgs || error "remount mgs failed"
7559         for ((i = 0; i < ${#fid_list[@]}; i++)); do
7560                 fid=${fid_list[i]}
7561                 rec=${rec_list[i]}
7562                 seq=$(echo $fid | awk -F ':' '{ print $1 }' | sed -e "s/^0x//g")
7563                 oid=$(echo $fid | awk -F ':' '{ print $2 }' | sed -e "s/^0x//g")
7564                 oid=$((16#$oid))
7565
7566                 case $fstype in
7567                         ldiskfs )
7568                                 obj_file=$mntpt/O/$seq/d$((oid%32))/$oid ;;
7569                         zfs )
7570                                 obj_file=$mntpt/oi.$(($((16#$seq))&127))/$fid ;;
7571                 esac
7572                 echo "obj_file is $obj_file"
7573                 do_facet mgs $llog_reader $obj_file
7574
7575                 rec_type=$(do_facet mgs $llog_reader $obj_file | grep "type=" |
7576                         awk '{ print $3 }' | sed -e "s/^type=//g")
7577                 if [ $rec_type != $rec ]; then
7578                         echo "FAILED test_60a wrong record type $rec_type," \
7579                               "should be $rec"
7580                         pass=false
7581                         break
7582                 fi
7583
7584                 #check obj path if record type is LLOG_LOGID_MAGIC
7585                 if [ "$rec" == "1064553b" ]; then
7586                         path=$(do_facet mgs $llog_reader $obj_file |
7587                                 grep "path=" | awk '{ print $NF }' |
7588                                 sed -e "s/^path=//g")
7589                         if [ $obj_file != $mntpt/$path ]; then
7590                                 echo "FAILED test_60a wrong obj path" \
7591                                       "$montpt/$path, should be $obj_file"
7592                                 pass=false
7593                                 break
7594                         fi
7595                 fi
7596         done
7597         rm -f $TMP/$tfile
7598         #restart mgs before "error", otherwise it will block the next test
7599         stop mgs || error "stop mgs failed"
7600         start mgs $(mgsdevname) $MGS_MOUNT_OPTS || error "start mgs failed"
7601         $pass || error "test failed, see FAILED test_60a messages for specifics"
7602 }
7603 run_test 60a "llog_test run from kernel module and test llog_reader"
7604
7605 test_60b() { # bug 6411
7606         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7607
7608         dmesg > $DIR/$tfile
7609         LLOG_COUNT=$(do_facet mgs dmesg |
7610                      awk "/$TEST60_HEAD/ { marker = 1; from_marker = 0; }
7611                           /llog_[a-z]*.c:[0-9]/ {
7612                                 if (marker)
7613                                         from_marker++
7614                                 from_begin++
7615                           }
7616                           END {
7617                                 if (marker)
7618                                         print from_marker
7619                                 else
7620                                         print from_begin
7621                           }")
7622
7623         [[ $LLOG_COUNT -gt 120 ]] &&
7624                 error "CDEBUG_LIMIT not limiting messages ($LLOG_COUNT)" || true
7625 }
7626 run_test 60b "limit repeated messages from CERROR/CWARN"
7627
7628 test_60c() {
7629         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7630
7631         echo "create 5000 files"
7632         createmany -o $DIR/f60c- 5000
7633 #define OBD_FAIL_MDS_LLOG_CREATE_FAILED  0x137
7634         lctl set_param fail_loc=0x80000137
7635         unlinkmany $DIR/f60c- 5000
7636         lctl set_param fail_loc=0
7637 }
7638 run_test 60c "unlink file when mds full"
7639
7640 test_60d() {
7641         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7642
7643         SAVEPRINTK=$(lctl get_param -n printk)
7644         # verify "lctl mark" is even working"
7645         MESSAGE="test message ID $RANDOM $$"
7646         $LCTL mark "$MESSAGE" || error "$LCTL mark failed"
7647         dmesg | grep -q "$MESSAGE" || error "didn't find debug marker in log"
7648
7649         lctl set_param printk=0 || error "set lnet.printk failed"
7650         lctl get_param -n printk | grep emerg || error "lnet.printk dropped emerg"
7651         MESSAGE="new test message ID $RANDOM $$"
7652         # Assume here that libcfs_debug_mark_buffer() uses D_WARNING
7653         $LCTL mark "$MESSAGE" || error "$LCTL mark failed"
7654         dmesg | grep -q "$MESSAGE" && error "D_WARNING wasn't masked" || true
7655
7656         lctl set_param -n printk="$SAVEPRINTK"
7657 }
7658 run_test 60d "test printk console message masking"
7659
7660 test_60e() {
7661         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7662         remote_mds_nodsh && skip "remote MDS with nodsh"
7663
7664         touch $DIR/$tfile
7665 #define OBD_FAIL_MDS_LLOG_CREATE_FAILED2  0x15b
7666         do_facet mds1 lctl set_param fail_loc=0x15b
7667         rm $DIR/$tfile
7668 }
7669 run_test 60e "no space while new llog is being created"
7670
7671 test_60g() {
7672         local pid
7673         local i
7674
7675         test_mkdir -c $MDSCOUNT $DIR/$tdir
7676
7677         (
7678                 local index=0
7679                 while true; do
7680                         $LFS setdirstripe -i $(($index % $MDSCOUNT)) \
7681                                 -c $MDSCOUNT $DIR/$tdir/subdir$index \
7682                                 2>/dev/null
7683                         mkdir $DIR/$tdir/subdir$index 2>/dev/null
7684                         rmdir $DIR/$tdir/subdir$index 2>/dev/null
7685                         index=$((index + 1))
7686                 done
7687         ) &
7688
7689         pid=$!
7690
7691         for i in {0..100}; do
7692                 # define OBD_FAIL_OSD_TXN_START    0x19a
7693                 local index=$((i % MDSCOUNT + 1))
7694
7695                 do_facet mds$index $LCTL set_param fail_loc=0x8000019a \
7696                         > /dev/null
7697                 usleep 100
7698         done
7699
7700         kill -9 $pid
7701
7702         for i in $(seq $MDSCOUNT); do
7703                 do_facet mds$i $LCTL set_param fail_loc=0 > /dev/null
7704         done
7705
7706         mkdir $DIR/$tdir/new || error "mkdir failed"
7707         rmdir $DIR/$tdir/new || error "rmdir failed"
7708
7709         do_facet mds1 $LCTL lfsck_start -M $(facet_svc mds1) -A -C \
7710                 -t namespace
7711         for i in $(seq $MDSCOUNT); do
7712                 wait_update_facet mds$i "$LCTL get_param -n \
7713                         mdd.$(facet_svc mds$i).lfsck_namespace |
7714                         awk '/^status/ { print \\\$2 }'" "completed"
7715         done
7716
7717         ls -R $DIR/$tdir || error "ls failed"
7718         rm -rf $DIR/$tdir || error "rmdir failed"
7719 }
7720 run_test 60g "transaction abort won't cause MDT hung"
7721
7722 test_60h() {
7723         [ $MDS1_VERSION -le $(version_code 2.12.52) ] &&
7724                 skip "Need MDS version at least 2.12.52"
7725         [ $MDSCOUNT -lt 2 ] && skip "Need at least 2 MDTs"
7726
7727         local f
7728
7729         #define OBD_FAIL_MDS_STRIPE_CREATE       0x188
7730         #define OBD_FAIL_MDS_STRIPE_FID          0x189
7731         for fail_loc in 0x80000188 0x80000189; do
7732                 do_facet mds1 "$LCTL set_param fail_loc=$fail_loc"
7733                 $LFS mkdir -c $MDSCOUNT -i 0 $DIR/$tdir-$fail_loc ||
7734                         error "mkdir $dir-$fail_loc failed"
7735                 for i in {0..10}; do
7736                         # create may fail on missing stripe
7737                         echo $i > $DIR/$tdir-$fail_loc/$i
7738                 done
7739                 $LFS getdirstripe $DIR/$tdir-$fail_loc ||
7740                         error "getdirstripe $tdir-$fail_loc failed"
7741                 $LFS migrate -m 1 $DIR/$tdir-$fail_loc ||
7742                         error "migrate $tdir-$fail_loc failed"
7743                 $LFS getdirstripe $DIR/$tdir-$fail_loc ||
7744                         error "getdirstripe $tdir-$fail_loc failed"
7745                 pushd $DIR/$tdir-$fail_loc
7746                 for f in *; do
7747                         echo $f | cmp $f - || error "$f data mismatch"
7748                 done
7749                 popd
7750                 rm -rf $DIR/$tdir-$fail_loc
7751         done
7752 }
7753 run_test 60h "striped directory with missing stripes can be accessed"
7754
7755 test_61a() {
7756         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7757
7758         f="$DIR/f61"
7759         dd if=/dev/zero of=$f bs=$PAGE_SIZE count=1 || error "dd $f failed"
7760         cancel_lru_locks osc
7761         $MULTIOP $f OSMWUc || error "$MULTIOP $f failed"
7762         sync
7763 }
7764 run_test 61a "mmap() writes don't make sync hang ================"
7765
7766 test_61b() {
7767         mmap_mknod_test $DIR/$tfile || error "mmap_mknod_test failed"
7768 }
7769 run_test 61b "mmap() of unstriped file is successful"
7770
7771 # bug 2330 - insufficient obd_match error checking causes LBUG
7772 test_62() {
7773         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7774
7775         f="$DIR/f62"
7776         echo foo > $f
7777         cancel_lru_locks osc
7778         lctl set_param fail_loc=0x405
7779         cat $f && error "cat succeeded, expect -EIO"
7780         lctl set_param fail_loc=0
7781 }
7782 # This test is now irrelevant (as of bug 10718 inclusion), we no longer
7783 # match every page all of the time.
7784 #run_test 62 "verify obd_match failure doesn't LBUG (should -EIO)"
7785
7786 # bug 2319 - oig_wait() interrupted causes crash because of invalid waitq.
7787 # Though this test is irrelevant anymore, it helped to reveal some
7788 # other grant bugs (LU-4482), let's keep it.
7789 test_63a() {   # was test_63
7790         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7791
7792         MAX_DIRTY_MB=$(lctl get_param -n osc.*.max_dirty_mb | head -n 1)
7793
7794         for i in `seq 10` ; do
7795                 dd if=/dev/zero of=$DIR/f63 bs=8k &
7796                 sleep 5
7797                 kill $!
7798                 sleep 1
7799         done
7800
7801         rm -f $DIR/f63 || true
7802 }
7803 run_test 63a "Verify oig_wait interruption does not crash ======="
7804
7805 # bug 2248 - async write errors didn't return to application on sync
7806 # bug 3677 - async write errors left page locked
7807 test_63b() {
7808         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7809
7810         debugsave
7811         lctl set_param debug=-1
7812
7813         # ensure we have a grant to do async writes
7814         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1
7815         rm $DIR/$tfile
7816
7817         sync    # sync lest earlier test intercept the fail_loc
7818
7819         #define OBD_FAIL_OSC_BRW_PREP_REQ        0x406
7820         lctl set_param fail_loc=0x80000406
7821         $MULTIOP $DIR/$tfile Owy && \
7822                 error "sync didn't return ENOMEM"
7823         sync; sleep 2; sync     # do a real sync this time to flush page
7824         lctl get_param -n llite.*.dump_page_cache | grep locked && \
7825                 error "locked page left in cache after async error" || true
7826         debugrestore
7827 }
7828 run_test 63b "async write errors should be returned to fsync ==="
7829
7830 test_64a () {
7831         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7832
7833         lfs df $DIR
7834         lctl get_param osc.*[oO][sS][cC][_-]*.cur* | grep "=[1-9]"
7835 }
7836 run_test 64a "verify filter grant calculations (in kernel) ====="
7837
7838 test_64b () {
7839         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7840
7841         sh oos.sh $MOUNT || error "oos.sh failed: $?"
7842 }
7843 run_test 64b "check out-of-space detection on client"
7844
7845 test_64c() {
7846         $LCTL set_param osc.*OST0000-osc-[^mM]*.cur_grant_bytes=0
7847 }
7848 run_test 64c "verify grant shrink"
7849
7850 import_param() {
7851         local tgt=$1
7852         local param=$2
7853
7854         $LCTL get_param osc.$tgt.import | awk "/$param/ { print \$2 }"
7855 }
7856
7857 # this does exactly what osc_request.c:osc_announce_cached() does in
7858 # order to calculate max amount of grants to ask from server
7859 want_grant() {
7860         local tgt=$1
7861
7862         local nrpages=$($LCTL get_param -n osc.$tgt.max_pages_per_rpc)
7863         local rpc_in_flight=$($LCTL get_param -n osc.$tgt.max_rpcs_in_flight)
7864
7865         ((rpc_in_flight++));
7866         nrpages=$((nrpages * rpc_in_flight))
7867
7868         local dirty_max_pages=$($LCTL get_param -n osc.$tgt.max_dirty_mb)
7869
7870         dirty_max_pages=$((dirty_max_pages * 1024 * 1024 / PAGE_SIZE))
7871
7872         [[ $dirty_max_pages -gt $nrpages ]] && nrpages=$dirty_max_pages
7873         local undirty=$((nrpages * PAGE_SIZE))
7874
7875         local max_extent_pages
7876         max_extent_pages=$(import_param $tgt grant_max_extent_size)
7877         max_extent_pages=$((max_extent_pages / PAGE_SIZE))
7878         local nrextents=$(((nrpages + max_extent_pages - 1) / max_extent_pages))
7879         local grant_extent_tax
7880         grant_extent_tax=$(import_param $tgt grant_extent_tax)
7881
7882         undirty=$((undirty + nrextents * grant_extent_tax))
7883
7884         echo $undirty
7885 }
7886
7887 # this is size of unit for grant allocation. It should be equal to
7888 # what tgt_grant.c:tgt_grant_chunk() calculates
7889 grant_chunk() {
7890         local tgt=$1
7891         local max_brw_size
7892         local grant_extent_tax
7893
7894         max_brw_size=$(import_param $tgt max_brw_size)
7895
7896         grant_extent_tax=$(import_param $tgt grant_extent_tax)
7897
7898         echo $(((max_brw_size + grant_extent_tax) * 2))
7899 }
7900
7901 test_64d() {
7902         [ $OST1_VERSION -ge $(version_code 2.10.56) ] ||
7903                 skip "OST < 2.10.55 doesn't limit grants enough"
7904
7905         local tgt=$($LCTL dl | awk '/OST0000-osc-[^mM]/ { print $4 }')
7906
7907         [[ "$($LCTL get_param osc.${tgt}.import)" =~ "grant_param" ]] ||
7908                 skip "no grant_param connect flag"
7909
7910         local olddebug="$($LCTL get_param -n debug 2> /dev/null)"
7911
7912         $LCTL set_param -n -n debug="$OLDDEBUG" || true
7913         stack_trap "$LCTL set_param -n debug='$olddebug'" EXIT
7914
7915
7916         local max_cur_granted=$(($(want_grant $tgt) + $(grant_chunk $tgt)))
7917         stack_trap "rm -f $DIR/$tfile && wait_delete_completed" EXIT
7918
7919         $LFS setstripe $DIR/$tfile -i 0 -c 1
7920         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1000 &
7921         ddpid=$!
7922
7923         while kill -0 $ddpid; do
7924                 local cur_grant=$($LCTL get_param -n osc.$tgt.cur_grant_bytes)
7925
7926                 if [[ $cur_grant -gt $max_cur_granted ]]; then
7927                         kill $ddpid
7928                         error "cur_grant $cur_grant > $max_cur_granted"
7929                 fi
7930
7931                 sleep 1
7932         done
7933 }
7934 run_test 64d "check grant limit exceed"
7935
7936 check_grants() {
7937         local tgt=$1
7938         local expected=$2
7939         local msg=$3
7940         local cur_grants=$($LCTL get_param -n osc.$tgt.cur_grant_bytes)
7941
7942         ((cur_grants == expected)) ||
7943                 error "$msg: grants mismatch: $cur_grants, expected $expected"
7944 }
7945
7946 round_up_p2() {
7947         echo $((($1 + $2 - 1) & ~($2 - 1)))
7948 }
7949
7950 test_64e() {
7951         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7952         [ $OST1_VERSION -ge $(version_code 2.11.56) ] ||
7953                 skip "Need OSS version at least 2.11.56"
7954
7955         # Remount client to reset grant
7956         remount_client $MOUNT || error "failed to remount client"
7957         local osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
7958
7959         local init_grants=$(import_param $osc_tgt initial_grant)
7960
7961         check_grants $osc_tgt $init_grants "init grants"
7962
7963         local extent_tax=$(import_param $osc_tgt grant_extent_tax)
7964         local max_brw_size=$(import_param $osc_tgt max_brw_size)
7965         local gbs=$(import_param $osc_tgt grant_block_size)
7966
7967         # write random number of bytes from max_brw_size / 4 to max_brw_size
7968         local write_bytes=$(shuf -i $((max_brw_size / 4))-$max_brw_size -n 1)
7969         # align for direct io
7970         write_bytes=$(round_up_p2 $write_bytes PAGE_SIZE)
7971         # round to grant consumption unit
7972         local wb_round_up=$(round_up_p2 $write_bytes gbs)
7973
7974         local grants=$((wb_round_up + extent_tax))
7975
7976         $LFS setstripe -c 1 -i 0 $DIR/$tfile  || error "lfs setstripe failed"
7977
7978         # define OBD_FAIL_TGT_NO_GRANT 0x725
7979         # make the server not grant more back
7980         do_facet ost1 $LCTL set_param fail_loc=0x725
7981         dd if=/dev/zero of=$DIR/$tfile bs=$write_bytes count=1 oflag=direct
7982
7983         do_facet ost1 $LCTL set_param fail_loc=0
7984
7985         check_grants $osc_tgt $((init_grants - grants)) "dio w/o grant alloc"
7986
7987         rm -f $DIR/$tfile || error "rm failed"
7988
7989         # Remount client to reset grant
7990         remount_client $MOUNT || error "failed to remount client"
7991         osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
7992
7993         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "lfs setstripe failed"
7994
7995         # define OBD_FAIL_TGT_NO_GRANT 0x725
7996         # make the server not grant more back
7997         do_facet ost1 $LCTL set_param fail_loc=0x725
7998         $MULTIOP $DIR/$tfile "oO_WRONLY:w${write_bytes}yc"
7999         do_facet ost1 $LCTL set_param fail_loc=0
8000
8001         check_grants $osc_tgt $((init_grants - grants)) "buf io w/o grant alloc"
8002 }
8003 run_test 64e "check grant consumption (no grant allocation)"
8004
8005 test_64f() {
8006         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8007
8008         # Remount client to reset grant
8009         remount_client $MOUNT || error "failed to remount client"
8010         local osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
8011
8012         local init_grants=$(import_param $osc_tgt initial_grant)
8013         local extent_tax=$(import_param $osc_tgt grant_extent_tax)
8014         local max_brw_size=$(import_param $osc_tgt max_brw_size)
8015         local gbs=$(import_param $osc_tgt grant_block_size)
8016         local chunk=$(grant_chunk $osc_tgt)
8017
8018         # write random number of bytes from max_brw_size / 4 to max_brw_size
8019         local write_bytes=$(shuf -i $((max_brw_size / 4))-$max_brw_size -n 1)
8020         # align for direct io
8021         write_bytes=$(round_up_p2 $write_bytes PAGE_SIZE)
8022         # round to grant consumption unit
8023         local wb_round_up=$(round_up_p2 $write_bytes gbs)
8024
8025         local grants=$((wb_round_up + extent_tax))
8026
8027         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "lfs setstripe failed"
8028         dd if=/dev/zero of=$DIR/$tfile bs=$write_bytes count=1 oflag=direct ||
8029                 error "error writing to $DIR/$tfile"
8030
8031         check_grants $osc_tgt $((init_grants - grants + chunk)) \
8032                 "direct io with grant allocation"
8033
8034         rm -f $DIR/$tfile || error "rm failed"
8035
8036         # Remount client to reset grant
8037         remount_client $MOUNT || error "failed to remount client"
8038         osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
8039
8040         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "lfs setstripe failed"
8041
8042         local cmd="oO_WRONLY:w${write_bytes}_yc"
8043
8044         $MULTIOP $DIR/$tfile $cmd &
8045         MULTIPID=$!
8046         sleep 1
8047
8048         check_grants $osc_tgt $((init_grants - grants)) \
8049                 "buffered io, not write rpc"
8050
8051         kill -USR1 $MULTIPID
8052         wait
8053
8054         check_grants $osc_tgt $((init_grants - grants + chunk)) \
8055                 "buffered io, one RPC"
8056 }
8057 run_test 64f "check grant consumption (with grant allocation)"
8058
8059 # bug 1414 - set/get directories' stripe info
8060 test_65a() {
8061         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8062
8063         test_mkdir $DIR/$tdir
8064         touch $DIR/$tdir/f1
8065         $LVERIFY $DIR/$tdir $DIR/$tdir/f1 || error "lverify failed"
8066 }
8067 run_test 65a "directory with no stripe info"
8068
8069 test_65b() {
8070         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8071
8072         test_mkdir $DIR/$tdir
8073         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
8074
8075         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
8076                                                 error "setstripe"
8077         touch $DIR/$tdir/f2
8078         $LVERIFY $DIR/$tdir $DIR/$tdir/f2 || error "lverify failed"
8079 }
8080 run_test 65b "directory setstripe -S stripe_size*2 -i 0 -c 1"
8081
8082 test_65c() {
8083         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8084         [ $OSTCOUNT -lt 2 ] && skip_env "need at least 2 OSTs"
8085
8086         test_mkdir $DIR/$tdir
8087         local stripesize=$($LFS getstripe -S $DIR/$tdir)
8088
8089         $LFS setstripe -S $((stripesize * 4)) -i 1 \
8090                 -c $((OSTCOUNT - 1)) $DIR/$tdir || error "setstripe"
8091         touch $DIR/$tdir/f3
8092         $LVERIFY $DIR/$tdir $DIR/$tdir/f3 || error "lverify failed"
8093 }
8094 run_test 65c "directory setstripe -S stripe_size*4 -i 1 -c $((OSTCOUNT-1))"
8095
8096 test_65d() {
8097         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8098
8099         test_mkdir $DIR/$tdir
8100         local STRIPECOUNT=$($LFS getstripe -c $DIR/$tdir)
8101         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
8102
8103         if [[ $STRIPECOUNT -le 0 ]]; then
8104                 sc=1
8105         elif [[ $STRIPECOUNT -gt $LOV_MAX_STRIPE_COUNT ]]; then
8106                 [[ $OSTCOUNT -gt $LOV_MAX_STRIPE_COUNT ]] &&
8107                         sc=$LOV_MAX_STRIPE_COUNT || sc=$(($OSTCOUNT - 1))
8108         else
8109                 sc=$(($STRIPECOUNT - 1))
8110         fi
8111         $LFS setstripe -S $STRIPESIZE -c $sc $DIR/$tdir || error "setstripe"
8112         touch $DIR/$tdir/f4 $DIR/$tdir/f5
8113         $LVERIFY $DIR/$tdir $DIR/$tdir/f4 $DIR/$tdir/f5 ||
8114                 error "lverify failed"
8115 }
8116 run_test 65d "directory setstripe -S stripe_size -c stripe_count"
8117
8118 test_65e() {
8119         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8120
8121         test_mkdir $DIR/$tdir
8122
8123         $LFS setstripe $DIR/$tdir || error "setstripe"
8124         $LFS getstripe -v $DIR/$tdir | grep "Default" ||
8125                                         error "no stripe info failed"
8126         touch $DIR/$tdir/f6
8127         $LVERIFY $DIR/$tdir $DIR/$tdir/f6 || error "lverify failed"
8128 }
8129 run_test 65e "directory setstripe defaults"
8130
8131 test_65f() {
8132         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8133
8134         test_mkdir $DIR/${tdir}f
8135         $RUNAS $LFS setstripe $DIR/${tdir}f &&
8136                 error "setstripe succeeded" || true
8137 }
8138 run_test 65f "dir setstripe permission (should return error) ==="
8139
8140 test_65g() {
8141         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8142
8143         test_mkdir $DIR/$tdir
8144         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
8145
8146         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
8147                 error "setstripe -S failed"
8148         $LFS setstripe -d $DIR/$tdir || error "setstripe -d failed"
8149         $LFS getstripe -v $DIR/$tdir | grep "Default" ||
8150                 error "delete default stripe failed"
8151 }
8152 run_test 65g "directory setstripe -d"
8153
8154 test_65h() {
8155         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8156
8157         test_mkdir $DIR/$tdir
8158         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
8159
8160         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
8161                 error "setstripe -S failed"
8162         test_mkdir $DIR/$tdir/dd1
8163         [ $($LFS getstripe -c $DIR/$tdir) = $($LFS getstripe -c $DIR/$tdir/dd1) ] ||
8164                 error "stripe info inherit failed"
8165 }
8166 run_test 65h "directory stripe info inherit ===================="
8167
8168 test_65i() {
8169         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8170
8171         save_layout_restore_at_exit $MOUNT
8172
8173         # bug6367: set non-default striping on root directory
8174         $LFS setstripe -S 65536 -c -1 $MOUNT || error "error setting stripe"
8175
8176         # bug12836: getstripe on -1 default directory striping
8177         $LFS getstripe $MOUNT || error "getstripe $MOUNT failed"
8178
8179         # bug12836: getstripe -v on -1 default directory striping
8180         $LFS getstripe -v $MOUNT || error "getstripe -v $MOUNT failed"
8181
8182         # bug12836: new find on -1 default directory striping
8183         $LFS find -mtime -1 $MOUNT > /dev/null || error "find $MOUNT failed"
8184 }
8185 run_test 65i "various tests to set root directory striping"
8186
8187 test_65j() { # bug6367
8188         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8189
8190         sync; sleep 1
8191
8192         # if we aren't already remounting for each test, do so for this test
8193         if [ "$I_MOUNTED" = "yes" ]; then
8194                 cleanup || error "failed to unmount"
8195                 setup
8196         fi
8197
8198         save_layout_restore_at_exit $MOUNT
8199
8200         $LFS setstripe -d $MOUNT || error "setstripe failed"
8201 }
8202 run_test 65j "set default striping on root directory (bug 6367)="
8203
8204 cleanup_65k() {
8205         rm -rf $DIR/$tdir
8206         wait_delete_completed
8207         do_facet $SINGLEMDS "lctl set_param -n \
8208                 osp.$ost*MDT0000.max_create_count=$max_count"
8209         do_facet $SINGLEMDS "lctl set_param -n \
8210                 osp.$ost*MDT0000.create_count=$count"
8211         do_facet $SINGLEMDS lctl --device  %$INACTIVE_OSC activate
8212         echo $INACTIVE_OSC "is Activate"
8213
8214         wait_osc_import_state mds ost$(( ostnum + 1 )) FULL
8215 }
8216
8217 test_65k() { # bug11679
8218         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8219         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
8220         remote_mds_nodsh && skip "remote MDS with nodsh"
8221
8222         local disable_precreate=true
8223         [ $MDS1_VERSION -le $(version_code 2.8.54) ] &&
8224                 disable_precreate=false
8225
8226         echo "Check OST status: "
8227         local MDS_OSCS=$(do_facet $SINGLEMDS lctl dl |
8228                 awk '/[oO][sS][cC].*md[ts]/ { print $4 }')
8229
8230         for OSC in $MDS_OSCS; do
8231                 echo $OSC "is active"
8232                 do_facet $SINGLEMDS lctl --device %$OSC activate
8233         done
8234
8235         for INACTIVE_OSC in $MDS_OSCS; do
8236                 local ost=$(osc_to_ost $INACTIVE_OSC)
8237                 local ostnum=$(do_facet $SINGLEMDS lctl get_param -n \
8238                                lov.*md*.target_obd |
8239                                awk -F: /$ost/'{ print $1 }' | head -n 1)
8240
8241                 mkdir -p $DIR/$tdir
8242                 $LFS setstripe -i $ostnum -c 1 $DIR/$tdir
8243                 createmany -o $DIR/$tdir/$tfile.$ostnum. 1000
8244
8245                 echo "Deactivate: " $INACTIVE_OSC
8246                 do_facet $SINGLEMDS lctl --device %$INACTIVE_OSC deactivate
8247
8248                 local count=$(do_facet $SINGLEMDS "lctl get_param -n \
8249                               osp.$ost*MDT0000.create_count")
8250                 local max_count=$(do_facet $SINGLEMDS "lctl get_param -n \
8251                                   osp.$ost*MDT0000.max_create_count")
8252                 $disable_precreate &&
8253                         do_facet $SINGLEMDS "lctl set_param -n \
8254                                 osp.$ost*MDT0000.max_create_count=0"
8255
8256                 for idx in $(seq 0 $((OSTCOUNT - 1))); do
8257                         [ -f $DIR/$tdir/$idx ] && continue
8258                         echo "$LFS setstripe -i $idx -c 1 $DIR/$tdir/$idx"
8259                         $LFS setstripe -i $idx -c 1 $DIR/$tdir/$idx ||
8260                                 { cleanup_65k;
8261                                   error "setstripe $idx should succeed"; }
8262                         rm -f $DIR/$tdir/$idx || error "rm $idx failed"
8263                 done
8264                 unlinkmany $DIR/$tdir/$tfile.$ostnum. 1000
8265                 rmdir $DIR/$tdir
8266
8267                 do_facet $SINGLEMDS "lctl set_param -n \
8268                         osp.$ost*MDT0000.max_create_count=$max_count"
8269                 do_facet $SINGLEMDS "lctl set_param -n \
8270                         osp.$ost*MDT0000.create_count=$count"
8271                 do_facet $SINGLEMDS lctl --device  %$INACTIVE_OSC activate
8272                 echo $INACTIVE_OSC "is Activate"
8273
8274                 wait_osc_import_state mds ost$(( ostnum + 1 )) FULL
8275         done
8276 }
8277 run_test 65k "validate manual striping works properly with deactivated OSCs"
8278
8279 test_65l() { # bug 12836
8280         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8281
8282         test_mkdir -p $DIR/$tdir/test_dir
8283         $LFS setstripe -c -1 $DIR/$tdir/test_dir
8284         $LFS find -mtime -1 $DIR/$tdir >/dev/null
8285 }
8286 run_test 65l "lfs find on -1 stripe dir ========================"
8287
8288 test_65m() {
8289         local layout=$(save_layout $MOUNT)
8290         $RUNAS $LFS setstripe -c 2 $MOUNT && {
8291                 restore_layout $MOUNT $layout
8292                 error "setstripe should fail by non-root users"
8293         }
8294         true
8295 }
8296 run_test 65m "normal user can't set filesystem default stripe"
8297
8298 test_65n() {
8299         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
8300         [[ $MDS1_VERSION -ge $(version_code 2.12.50) ]] ||
8301                 skip "Need MDS version at least 2.12.50"
8302         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
8303
8304         [[ $OSTCOUNT -ge 2 ]] || skip_env "needs >= 2 OSTs"
8305         which getfattr > /dev/null 2>&1 || skip_env "no getfattr command"
8306         which setfattr > /dev/null 2>&1 || skip_env "no setfattr command"
8307
8308         local root_layout=$(save_layout $MOUNT)
8309         stack_trap "restore_layout $MOUNT $root_layout" EXIT
8310
8311         # new subdirectory under root directory should not inherit
8312         # the default layout from root
8313         local dir1=$MOUNT/$tdir-1
8314         mkdir $dir1 || error "mkdir $dir1 failed"
8315         ! getfattr -n trusted.lov $dir1 &> /dev/null ||
8316                 error "$dir1 shouldn't have LOV EA"
8317
8318         # delete the default layout on root directory
8319         $LFS setstripe -d $MOUNT || error "delete root default layout failed"
8320
8321         local dir2=$MOUNT/$tdir-2
8322         mkdir $dir2 || error "mkdir $dir2 failed"
8323         ! getfattr -n trusted.lov $dir2 &> /dev/null ||
8324                 error "$dir2 shouldn't have LOV EA"
8325
8326         # set a new striping pattern on root directory
8327         local def_stripe_size=$($LFS getstripe -S $MOUNT)
8328         local new_def_stripe_size=$((def_stripe_size * 2))
8329         $LFS setstripe -S $new_def_stripe_size $MOUNT ||
8330                 error "set stripe size on $MOUNT failed"
8331
8332         # new file created in $dir2 should inherit the new stripe size from
8333         # the filesystem default
8334         local file2=$dir2/$tfile-2
8335         touch $file2 || error "touch $file2 failed"
8336
8337         local file2_stripe_size=$($LFS getstripe -S $file2)
8338         [[ $file2_stripe_size -eq $new_def_stripe_size ]] ||
8339                 error "$file2 didn't inherit stripe size $new_def_stripe_size"
8340
8341         local dir3=$MOUNT/$tdir-3
8342         mkdir $dir3 || error "mkdir $dir3 failed"
8343         # $dir3 shouldn't have LOV EA, but "lfs getstripe -d $dir3" should show
8344         # the root layout, which is the actual default layout that will be used
8345         # when new files are created in $dir3.
8346         local dir3_layout=$(get_layout_param $dir3)
8347         local root_dir_layout=$(get_layout_param $MOUNT)
8348         [[ "$dir3_layout" = "$root_dir_layout" ]] ||
8349                 error "$dir3 should show the default layout from $MOUNT"
8350
8351         # set OST pool on root directory
8352         local pool=$TESTNAME
8353         pool_add $pool || error "add $pool failed"
8354         pool_add_targets $pool 0 $((OSTCOUNT - 1)) 1 ||
8355                 error "add targets to $pool failed"
8356
8357         $LFS setstripe -p $pool $MOUNT ||
8358                 error "set OST pool on $MOUNT failed"
8359
8360         # new file created in $dir3 should inherit the pool from
8361         # the filesystem default
8362         local file3=$dir3/$tfile-3
8363         touch $file3 || error "touch $file3 failed"
8364
8365         local file3_pool=$($LFS getstripe -p $file3)
8366         [[ "$file3_pool" = "$pool" ]] ||
8367                 error "$file3 didn't inherit OST pool $pool"
8368
8369         local dir4=$MOUNT/$tdir-4
8370         mkdir $dir4 || error "mkdir $dir4 failed"
8371         local dir4_layout=$(get_layout_param $dir4)
8372         root_dir_layout=$(get_layout_param $MOUNT)
8373         echo "$LFS getstripe -d $dir4"
8374         $LFS getstripe -d $dir4
8375         echo "$LFS getstripe -d $MOUNT"
8376         $LFS getstripe -d $MOUNT
8377         [[ "$dir4_layout" = "$root_dir_layout" ]] ||
8378                 error "$dir4 should show the default layout from $MOUNT"
8379
8380         # new file created in $dir4 should inherit the pool from
8381         # the filesystem default
8382         local file4=$dir4/$tfile-4
8383         touch $file4 || error "touch $file4 failed"
8384
8385         local file4_pool=$($LFS getstripe -p $file4)
8386         [[ "$file4_pool" = "$pool" ]] ||
8387                 error "$file4 didn't inherit OST pool $pool"
8388
8389         # new subdirectory under non-root directory should inherit
8390         # the default layout from its parent directory
8391         $LFS setstripe -S $new_def_stripe_size -p $pool $dir4 ||
8392                 error "set directory layout on $dir4 failed"
8393
8394         local dir5=$dir4/$tdir-5
8395         mkdir $dir5 || error "mkdir $dir5 failed"
8396
8397         dir4_layout=$(get_layout_param $dir4)
8398         local dir5_layout=$(get_layout_param $dir5)
8399         [[ "$dir4_layout" = "$dir5_layout" ]] ||
8400                 error "$dir5 should inherit the default layout from $dir4"
8401
8402         # though subdir under ROOT doesn't inherit default layout, but
8403         # its sub dir/file should be created with default layout.
8404         [[ $MDSCOUNT -ge 2 ]] || skip_env "needs >= 2 MDTs"
8405         [[ $MDS1_VERSION -ge $(version_code 2.12.59) ]] ||
8406                 skip "Need MDS version at least 2.12.59"
8407
8408         local default_lmv_count=$($LFS getdirstripe -D -c $MOUNT)
8409         local default_lmv_index=$($LFS getdirstripe -D -i $MOUNT)
8410         local default_lmv_hash=$($LFS getdirstripe -D -H $MOUNT)
8411
8412         if [ $default_lmv_hash == "none" ]; then
8413                 stack_trap "$LFS setdirstripe -D -d $MOUNT" EXIT
8414         else
8415                 stack_trap "$LFS setdirstripe -D -i $default_lmv_index \
8416                         -c $default_lmv_count -H $default_lmv_hash $MOUNT" EXIT
8417         fi
8418
8419         $LFS setdirstripe -D -c 2 $MOUNT ||
8420                 error "setdirstripe -D -c 2 failed"
8421         mkdir $MOUNT/$tdir-6 || error "mkdir $tdir-6 failed"
8422         local lmv_count=$($LFS getdirstripe -c $MOUNT/$tdir-6)
8423         [ $lmv_count -eq 2 ] || error "$tdir-6 stripe count $lmv_count"
8424 }
8425 run_test 65n "don't inherit default layout from root for new subdirectories"
8426
8427 # bug 2543 - update blocks count on client
8428 test_66() {
8429         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8430
8431         COUNT=${COUNT:-8}
8432         dd if=/dev/zero of=$DIR/f66 bs=1k count=$COUNT
8433         sync; sync_all_data; sync; sync_all_data
8434         cancel_lru_locks osc
8435         BLOCKS=`ls -s $DIR/f66 | awk '{ print $1 }'`
8436         [ $BLOCKS -ge $COUNT ] || error "$DIR/f66 blocks $BLOCKS < $COUNT"
8437 }
8438 run_test 66 "update inode blocks count on client ==============="
8439
8440 meminfo() {
8441         awk '($1 == "'$1':") { print $2 }' /proc/meminfo
8442 }
8443
8444 swap_used() {
8445         swapon -s | awk '($1 == "'$1'") { print $4 }'
8446 }
8447
8448 # bug5265, obdfilter oa2dentry return -ENOENT
8449 # #define OBD_FAIL_SRV_ENOENT 0x217
8450 test_69() {
8451         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8452         remote_ost_nodsh && skip "remote OST with nodsh"
8453
8454         f="$DIR/$tfile"
8455         $LFS setstripe -c 1 -i 0 $f
8456
8457         $DIRECTIO write ${f}.2 0 1 || error "directio write error"
8458
8459         do_facet ost1 lctl set_param fail_loc=0x217
8460         $TRUNCATE $f 1 # vmtruncate() will ignore truncate() error.
8461         $DIRECTIO write $f 0 2 && error "write succeeded, expect -ENOENT"
8462
8463         do_facet ost1 lctl set_param fail_loc=0
8464         $DIRECTIO write $f 0 2 || error "write error"
8465
8466         cancel_lru_locks osc
8467         $DIRECTIO read $f 0 1 || error "read error"
8468
8469         do_facet ost1 lctl set_param fail_loc=0x217
8470         $DIRECTIO read $f 1 1 && error "read succeeded, expect -ENOENT"
8471
8472         do_facet ost1 lctl set_param fail_loc=0
8473         rm -f $f
8474 }
8475 run_test 69 "verify oa2dentry return -ENOENT doesn't LBUG ======"
8476
8477 test_71() {
8478         test_mkdir $DIR/$tdir
8479         $LFS setdirstripe -D -c$MDSCOUNT $DIR/$tdir
8480         sh rundbench -C -D $DIR/$tdir 2 || error "dbench failed!"
8481 }
8482 run_test 71 "Running dbench on lustre (don't segment fault) ===="
8483
8484 test_72a() { # bug 5695 - Test that on 2.6 remove_suid works properly
8485         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8486         [ "$RUNAS_ID" = "$UID" ] &&
8487                 skip_env "RUNAS_ID = UID = $UID -- skipping"
8488         # Check that testing environment is properly set up. Skip if not
8489         FAIL_ON_ERROR=false check_runas_id_ret $RUNAS_ID $RUNAS_GID $RUNAS ||
8490                 skip_env "User $RUNAS_ID does not exist - skipping"
8491
8492         touch $DIR/$tfile
8493         chmod 777 $DIR/$tfile
8494         chmod ug+s $DIR/$tfile
8495         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=512 count=1 ||
8496                 error "$RUNAS dd $DIR/$tfile failed"
8497         # See if we are still setuid/sgid
8498         [ -u $DIR/$tfile ] || [ -g $DIR/$tfile ] &&
8499                 error "S/gid is not dropped on write"
8500         # Now test that MDS is updated too
8501         cancel_lru_locks mdc
8502         [ -u $DIR/$tfile ] || [ -g $DIR/$tfile ] &&
8503                 error "S/gid is not dropped on MDS"
8504         rm -f $DIR/$tfile
8505 }
8506 run_test 72a "Test that remove suid works properly (bug5695) ===="
8507
8508 test_72b() { # bug 24226 -- keep mode setting when size is not changing
8509         local perm
8510
8511         [ "$RUNAS_ID" = "$UID" ] &&
8512                 skip_env "RUNAS_ID = UID = $UID -- skipping"
8513         [ "$RUNAS_ID" -eq 0 ] &&
8514                 skip_env "RUNAS_ID = 0 -- skipping"
8515         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8516         # Check that testing environment is properly set up. Skip if not
8517         FAIL_ON_ERROR=false check_runas_id_ret $RUNAS_ID $RUNAS_ID $RUNAS ||
8518                 skip_env "User $RUNAS_ID does not exist - skipping"
8519
8520         touch $DIR/${tfile}-f{g,u}
8521         test_mkdir $DIR/${tfile}-dg
8522         test_mkdir $DIR/${tfile}-du
8523         chmod 770 $DIR/${tfile}-{f,d}{g,u}
8524         chmod g+s $DIR/${tfile}-{f,d}g
8525         chmod u+s $DIR/${tfile}-{f,d}u
8526         for perm in 777 2777 4777; do
8527                 $RUNAS chmod $perm $DIR/${tfile}-fg && error "S/gid file allowed improper chmod to $perm"
8528                 $RUNAS chmod $perm $DIR/${tfile}-fu && error "S/uid file allowed improper chmod to $perm"
8529                 $RUNAS chmod $perm $DIR/${tfile}-dg && error "S/gid dir allowed improper chmod to $perm"
8530                 $RUNAS chmod $perm $DIR/${tfile}-du && error "S/uid dir allowed improper chmod to $perm"
8531         done
8532         true
8533 }
8534 run_test 72b "Test that we keep mode setting if without file data changed (bug 24226)"
8535
8536 # bug 3462 - multiple simultaneous MDC requests
8537 test_73() {
8538         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8539
8540         test_mkdir $DIR/d73-1
8541         test_mkdir $DIR/d73-2
8542         multiop_bg_pause $DIR/d73-1/f73-1 O_c || return 1
8543         pid1=$!
8544
8545         lctl set_param fail_loc=0x80000129
8546         $MULTIOP $DIR/d73-1/f73-2 Oc &
8547         sleep 1
8548         lctl set_param fail_loc=0
8549
8550         $MULTIOP $DIR/d73-2/f73-3 Oc &
8551         pid3=$!
8552
8553         kill -USR1 $pid1
8554         wait $pid1 || return 1
8555
8556         sleep 25
8557
8558         $CHECKSTAT -t file $DIR/d73-1/f73-1 || return 4
8559         $CHECKSTAT -t file $DIR/d73-1/f73-2 || return 5
8560         $CHECKSTAT -t file $DIR/d73-2/f73-3 || return 6
8561
8562         rm -rf $DIR/d73-*
8563 }
8564 run_test 73 "multiple MDC requests (should not deadlock)"
8565
8566 test_74a() { # bug 6149, 6184
8567         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8568
8569         touch $DIR/f74a
8570         #define OBD_FAIL_LDLM_ENQUEUE_OLD_EXPORT 0x30e
8571         #
8572         # very important to OR with OBD_FAIL_ONCE (0x80000000) -- otherwise it
8573         # will spin in a tight reconnection loop
8574         $LCTL set_param fail_loc=0x8000030e
8575         # get any lock that won't be difficult - lookup works.
8576         ls $DIR/f74a
8577         $LCTL set_param fail_loc=0
8578         rm -f $DIR/f74a
8579         true
8580 }
8581 run_test 74a "ldlm_enqueue freed-export error path, ls (shouldn't LBUG)"
8582
8583 test_74b() { # bug 13310
8584         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8585
8586         #define OBD_FAIL_LDLM_ENQUEUE_OLD_EXPORT 0x30e
8587         #
8588         # very important to OR with OBD_FAIL_ONCE (0x80000000) -- otherwise it
8589         # will spin in a tight reconnection loop
8590         $LCTL set_param fail_loc=0x8000030e
8591         # get a "difficult" lock
8592         touch $DIR/f74b
8593         $LCTL set_param fail_loc=0
8594         rm -f $DIR/f74b
8595         true
8596 }
8597 run_test 74b "ldlm_enqueue freed-export error path, touch (shouldn't LBUG)"
8598
8599 test_74c() {
8600         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8601
8602         #define OBD_FAIL_LDLM_NEW_LOCK
8603         $LCTL set_param fail_loc=0x319
8604         touch $DIR/$tfile && error "touch successful"
8605         $LCTL set_param fail_loc=0
8606         true
8607 }
8608 run_test 74c "ldlm_lock_create error path, (shouldn't LBUG)"
8609
8610 num_inodes() {
8611         [ -f /sys/kernel/slab/lustre_inode_cache/shrink ] &&
8612                 echo 1 > /sys/kernel/slab/lustre_inode_cache/shrink
8613         awk '/lustre_inode_cache/ {print $2; exit}' /proc/slabinfo
8614 }
8615
8616 test_76() { # Now for bug 20433, added originally in bug 1443
8617         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8618
8619         cancel_lru_locks osc
8620         local cpus=$(getconf _NPROCESSORS_ONLN 2>/dev/null)
8621         local before=$(num_inodes)
8622         local count=$((512 * cpus))
8623         [ "$SLOW" = "no" ] && count=$((64 * cpus))
8624
8625         echo "before inodes: $before"
8626         for i in $(seq $count); do
8627                 touch $DIR/$tfile
8628                 rm -f $DIR/$tfile
8629         done
8630         cancel_lru_locks osc
8631         local after=$(num_inodes)
8632         echo "after inodes: $after"
8633         while (( after > before + 8 * ${cpus:-1} )); do
8634                 sleep 1
8635                 after=$(num_inodes)
8636                 wait=$((wait + 1))
8637                 (( wait % 5 == 0 )) && echo "wait $wait seconds inodes: $after"
8638                 if (( wait > 30 )); then
8639                         error "inode slab grew from $before to $after"
8640                 fi
8641         done
8642 }
8643 run_test 76 "confirm clients recycle inodes properly ===="
8644
8645
8646 export ORIG_CSUM=""
8647 set_checksums()
8648 {
8649         # Note: in sptlrpc modes which enable its own bulk checksum, the
8650         # original crc32_le bulk checksum will be automatically disabled,
8651         # and the OBD_FAIL_OSC_CHECKSUM_SEND/OBD_FAIL_OSC_CHECKSUM_RECEIVE
8652         # will be checked by sptlrpc code against sptlrpc bulk checksum.
8653         # In this case set_checksums() will not be no-op, because sptlrpc
8654         # bulk checksum will be enabled all through the test.
8655
8656         [ "$ORIG_CSUM" ] || ORIG_CSUM=`lctl get_param -n osc.*.checksums | head -n1`
8657         lctl set_param -n osc.*.checksums $1
8658         return 0
8659 }
8660
8661 export ORIG_CSUM_TYPE="`lctl get_param -n osc.*osc-[^mM]*.checksum_type |
8662                         sed 's/.*\[\(.*\)\].*/\1/g' | head -n1`"
8663 CKSUM_TYPES=${CKSUM_TYPES:-$(lctl get_param -n osc.*osc-[^mM]*.checksum_type |
8664                              tr -d [] | head -n1)}
8665 set_checksum_type()
8666 {
8667         lctl set_param -n osc.*osc-[^mM]*.checksum_type $1
8668         rc=$?
8669         log "set checksum type to $1, rc = $rc"
8670         return $rc
8671 }
8672
8673 get_osc_checksum_type()
8674 {
8675         # arugment 1: OST name, like OST0000
8676         ost=$1
8677         checksum_type=$(lctl get_param -n osc.*${ost}-osc-[^mM]*.checksum_type |
8678                         sed 's/.*\[\(.*\)\].*/\1/g')
8679         rc=$?
8680         [ $rc -ne 0 ] && error "failed to get checksum type of $ost, rc = $rc, output = $checksum_type"
8681         echo $checksum_type
8682 }
8683
8684 F77_TMP=$TMP/f77-temp
8685 F77SZ=8
8686 setup_f77() {
8687         dd if=/dev/urandom of=$F77_TMP bs=1M count=$F77SZ || \
8688                 error "error writing to $F77_TMP"
8689 }
8690
8691 test_77a() { # bug 10889
8692         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8693         $GSS && skip_env "could not run with gss"
8694
8695         [ ! -f $F77_TMP ] && setup_f77
8696         set_checksums 1
8697         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ || error "dd error"
8698         set_checksums 0
8699         rm -f $DIR/$tfile
8700 }
8701 run_test 77a "normal checksum read/write operation"
8702
8703 test_77b() { # bug 10889
8704         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8705         $GSS && skip_env "could not run with gss"
8706
8707         [ ! -f $F77_TMP ] && setup_f77
8708         #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
8709         $LCTL set_param fail_loc=0x80000409
8710         set_checksums 1
8711
8712         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ conv=sync ||
8713                 error "dd error: $?"
8714         $LCTL set_param fail_loc=0
8715
8716         for algo in $CKSUM_TYPES; do
8717                 cancel_lru_locks osc
8718                 set_checksum_type $algo
8719                 #define OBD_FAIL_OSC_CHECKSUM_RECEIVE    0x408
8720                 $LCTL set_param fail_loc=0x80000408
8721                 cmp $F77_TMP $DIR/$tfile || error "file compare failed"
8722                 $LCTL set_param fail_loc=0
8723         done
8724         set_checksums 0
8725         set_checksum_type $ORIG_CSUM_TYPE
8726         rm -f $DIR/$tfile
8727 }
8728 run_test 77b "checksum error on client write, read"
8729
8730 cleanup_77c() {
8731         trap 0
8732         set_checksums 0
8733         $LCTL set_param osc.*osc-[^mM]*.checksum_dump=0
8734         $check_ost &&
8735                 do_facet ost1 $LCTL set_param obdfilter.*-OST*.checksum_dump=0
8736         [ -n "$osc_file_prefix" ] && rm -f ${osc_file_prefix}*
8737         $check_ost && [ -n "$ost_file_prefix" ] &&
8738                 do_facet ost1 rm -f ${ost_file_prefix}\*
8739 }
8740
8741 test_77c() {
8742         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8743         $GSS && skip_env "could not run with gss"
8744         remote_ost_nodsh && skip "remote OST with nodsh"
8745
8746         local bad1
8747         local osc_file_prefix
8748         local osc_file
8749         local check_ost=false
8750         local ost_file_prefix
8751         local ost_file
8752         local orig_cksum
8753         local dump_cksum
8754         local fid
8755
8756         # ensure corruption will occur on first OSS/OST
8757         $LFS setstripe -i 0 $DIR/$tfile
8758
8759         [ ! -f $F77_TMP ] && setup_f77
8760         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ conv=sync ||
8761                 error "dd write error: $?"
8762         fid=$($LFS path2fid $DIR/$tfile)
8763
8764         if [ $OST1_VERSION -ge $(version_code 2.9.57) ]
8765         then
8766                 check_ost=true
8767                 ost_file_prefix=$(do_facet ost1 $LCTL get_param -n debug_path)
8768                 ost_file_prefix=${ost_file_prefix}-checksum_dump-ost-\\${fid}
8769         else
8770                 echo "OSS do not support bulk pages dump upon error"
8771         fi
8772
8773         osc_file_prefix=$($LCTL get_param -n debug_path)
8774         osc_file_prefix=${osc_file_prefix}-checksum_dump-osc-\\${fid}
8775
8776         trap cleanup_77c EXIT
8777
8778         set_checksums 1
8779         # enable bulk pages dump upon error on Client
8780         $LCTL set_param osc.*osc-[^mM]*.checksum_dump=1
8781         # enable bulk pages dump upon error on OSS
8782         $check_ost &&
8783                 do_facet ost1 $LCTL set_param obdfilter.*-OST*.checksum_dump=1
8784
8785         # flush Client cache to allow next read to reach OSS
8786         cancel_lru_locks osc
8787
8788         #define OBD_FAIL_OSC_CHECKSUM_RECEIVE       0x408
8789         $LCTL set_param fail_loc=0x80000408
8790         dd if=$DIR/$tfile of=/dev/null bs=1M || error "dd read error: $?"
8791         $LCTL set_param fail_loc=0
8792
8793         rm -f $DIR/$tfile
8794
8795         # check cksum dump on Client
8796         osc_file=$(ls ${osc_file_prefix}*)
8797         [ -n "$osc_file" ] || error "no checksum dump file on Client"
8798         # OBD_FAIL_OSC_CHECKSUM_RECEIVE corrupts with "bad1" at start of file
8799         bad1=$(dd if=$osc_file bs=1 count=4 2>/dev/null) || error "dd error: $?"
8800         [ $bad1 == "bad1" ] || error "unexpected corrupt pattern"
8801         orig_cksum=$(dd if=$F77_TMP bs=1 skip=4 count=1048572 2>/dev/null |
8802                      cksum)
8803         dump_cksum=$(dd if=$osc_file bs=1 skip=4 2>/dev/null | cksum)
8804         [[ "$orig_cksum" == "$dump_cksum" ]] ||
8805                 error "dump content does not match on Client"
8806
8807         $check_ost || skip "No need to check cksum dump on OSS"
8808
8809         # check cksum dump on OSS
8810         ost_file=$(do_facet ost1 ls ${ost_file_prefix}\*)
8811         [ -n "$ost_file" ] || error "no checksum dump file on OSS"
8812         orig_cksum=$(dd if=$F77_TMP bs=1048576 count=1 2>/dev/null | cksum)
8813         dump_cksum=$(do_facet ost1 dd if=$ost_file 2>/dev/null \| cksum)
8814         [[ "$orig_cksum" == "$dump_cksum" ]] ||
8815                 error "dump content does not match on OSS"
8816
8817         cleanup_77c
8818 }
8819 run_test 77c "checksum error on client read with debug"
8820
8821 test_77d() { # bug 10889
8822         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8823         $GSS && skip_env "could not run with gss"
8824
8825         #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
8826         $LCTL set_param fail_loc=0x80000409
8827         set_checksums 1
8828         $DIRECTIO write $DIR/$tfile 0 $F77SZ $((1024 * 1024)) ||
8829                 error "direct write: rc=$?"
8830         $LCTL set_param fail_loc=0
8831         set_checksums 0
8832
8833         #define OBD_FAIL_OSC_CHECKSUM_RECEIVE    0x408
8834         $LCTL set_param fail_loc=0x80000408
8835         set_checksums 1
8836         cancel_lru_locks osc
8837         $DIRECTIO read $DIR/$tfile 0 $F77SZ $((1024 * 1024)) ||
8838                 error "direct read: rc=$?"
8839         $LCTL set_param fail_loc=0
8840         set_checksums 0
8841 }
8842 run_test 77d "checksum error on OST direct write, read"
8843
8844 test_77f() { # bug 10889
8845         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8846         $GSS && skip_env "could not run with gss"
8847
8848         set_checksums 1
8849         for algo in $CKSUM_TYPES; do
8850                 cancel_lru_locks osc
8851                 set_checksum_type $algo
8852                 #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
8853                 $LCTL set_param fail_loc=0x409
8854                 $DIRECTIO write $DIR/$tfile 0 $F77SZ $((1024 * 1024)) &&
8855                         error "direct write succeeded"
8856                 $LCTL set_param fail_loc=0
8857         done
8858         set_checksum_type $ORIG_CSUM_TYPE
8859         set_checksums 0
8860 }
8861 run_test 77f "repeat checksum error on write (expect error)"
8862
8863 test_77g() { # bug 10889
8864         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8865         $GSS && skip_env "could not run with gss"
8866         remote_ost_nodsh && skip "remote OST with nodsh"
8867
8868         [ ! -f $F77_TMP ] && setup_f77
8869
8870         local file=$DIR/$tfile
8871         stack_trap "rm -f $file" EXIT
8872
8873         $LFS setstripe -c 1 -i 0 $file
8874         #define OBD_FAIL_OST_CHECKSUM_RECEIVE       0x21a
8875         do_facet ost1 lctl set_param fail_loc=0x8000021a
8876         set_checksums 1
8877         dd if=$F77_TMP of=$file bs=1M count=$F77SZ ||
8878                 error "write error: rc=$?"
8879         do_facet ost1 lctl set_param fail_loc=0
8880         set_checksums 0
8881
8882         cancel_lru_locks osc
8883         #define OBD_FAIL_OST_CHECKSUM_SEND          0x21b
8884         do_facet ost1 lctl set_param fail_loc=0x8000021b
8885         set_checksums 1
8886         cmp $F77_TMP $file || error "file compare failed"
8887         do_facet ost1 lctl set_param fail_loc=0
8888         set_checksums 0
8889 }
8890 run_test 77g "checksum error on OST write, read"
8891
8892 test_77k() { # LU-10906
8893         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8894         $GSS && skip_env "could not run with gss"
8895
8896         local cksum_param="osc.$FSNAME*.checksums"
8897         local get_checksum="$LCTL get_param -n $cksum_param | head -n1"
8898         local checksum
8899         local i
8900
8901         [ "$ORIG_CSUM" ] || ORIG_CSUM=$(eval $get_checksum)
8902         stack_trap "wait_update $HOSTNAME '$get_checksum' $ORIG_CSUM || true"
8903         stack_trap "do_facet mgs $LCTL set_param -P $cksum_param=$ORIG_CSUM"
8904
8905         for i in 0 1; do
8906                 do_facet mgs $LCTL set_param -P $cksum_param=$i ||
8907                         error "failed to set checksum=$i on MGS"
8908                 wait_update $HOSTNAME "$get_checksum" $i
8909                 #remount
8910                 echo "remount client, checksum should be $i"
8911                 remount_client $MOUNT || error "failed to remount client"
8912                 checksum=$(eval $get_checksum)
8913                 [ $checksum -eq $i ] || error "checksum($checksum) != $i"
8914         done
8915         # remove persistent param to avoid races with checksum mountopt below
8916         do_facet mgs $LCTL set_param -P -d $cksum_param ||
8917                 error "failed to delete checksum on MGS"
8918
8919         for opt in "checksum" "nochecksum"; do
8920                 #remount with mount option
8921                 echo "remount client with option $opt, checksum should be $i"
8922                 umount_client $MOUNT || error "failed to umount client"
8923                 mount_client $MOUNT "$MOUNT_OPTS,$opt" ||
8924                         error "failed to mount client with option '$opt'"
8925                 checksum=$(eval $get_checksum)
8926                 [ $checksum -eq $i ] || error "checksum($checksum) != $i"
8927                 i=$((i - 1))
8928         done
8929
8930         remount_client $MOUNT || error "failed to remount client"
8931 }
8932 run_test 77k "enable/disable checksum correctly"
8933
8934 test_77l() {
8935         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8936         $GSS && skip_env "could not run with gss"
8937
8938         set_checksums 1
8939         stack_trap "set_checksums $ORIG_CSUM" EXIT
8940         stack_trap "set_checksum_type $ORIG_CSUM_TYPE" EXIT
8941
8942         set_checksum_type invalid && error "unexpected success of invalid checksum type"
8943
8944         $LFS setstripe -c 1 -i 0 $DIR/$tfile
8945         for algo in $CKSUM_TYPES; do
8946                 set_checksum_type $algo || error "fail to set checksum type $algo"
8947                 osc_algo=$(get_osc_checksum_type OST0000)
8948                 [ "$osc_algo" != "$algo" ] && error "checksum type is $osc_algo after setting it to $algo"
8949
8950                 # no locks, no reqs to let the connection idle
8951                 cancel_lru_locks osc
8952                 lru_resize_disable osc
8953                 wait_osc_import_state client ost1 IDLE
8954
8955                 # ensure ost1 is connected
8956                 stat $DIR/$tfile >/dev/null || error "can't stat"
8957                 wait_osc_import_state client ost1 FULL
8958
8959                 osc_algo=$(get_osc_checksum_type OST0000)
8960                 [ "$osc_algo" != "$algo" ] && error "checksum type changed from $algo to $osc_algo after reconnection"
8961         done
8962         return 0
8963 }
8964 run_test 77l "preferred checksum type is remembered after reconnected"
8965
8966 [ "$ORIG_CSUM" ] && set_checksums $ORIG_CSUM || true
8967 rm -f $F77_TMP
8968 unset F77_TMP
8969
8970 cleanup_test_78() {
8971         trap 0
8972         rm -f $DIR/$tfile
8973 }
8974
8975 test_78() { # bug 10901
8976         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8977         remote_ost || skip_env "local OST"
8978
8979         NSEQ=5
8980         F78SIZE=$(($(awk '/MemFree:/ { print $2 }' /proc/meminfo) / 1024))
8981         echo "MemFree: $F78SIZE, Max file size: $MAXFREE"
8982         MEMTOTAL=$(($(awk '/MemTotal:/ { print $2 }' /proc/meminfo) / 1024))
8983         echo "MemTotal: $MEMTOTAL"
8984
8985         # reserve 256MB of memory for the kernel and other running processes,
8986         # and then take 1/2 of the remaining memory for the read/write buffers.
8987         if [ $MEMTOTAL -gt 512 ] ;then
8988                 MEMTOTAL=$(((MEMTOTAL - 256 ) / 2))
8989         else
8990                 # for those poor memory-starved high-end clusters...
8991                 MEMTOTAL=$((MEMTOTAL / 2))
8992         fi
8993         echo "Mem to use for directio: $MEMTOTAL"
8994
8995         [[ $F78SIZE -gt $MEMTOTAL ]] && F78SIZE=$MEMTOTAL
8996         [[ $F78SIZE -gt 512 ]] && F78SIZE=512
8997         [[ $F78SIZE -gt $((MAXFREE / 1024)) ]] && F78SIZE=$((MAXFREE / 1024))
8998         SMALLESTOST=$($LFS df $DIR | grep OST | awk '{ print $4 }' | sort -n |
8999                 head -n1)
9000         echo "Smallest OST: $SMALLESTOST"
9001         [[ $SMALLESTOST -lt 10240 ]] &&
9002                 skip "too small OSTSIZE, useless to run large O_DIRECT test"
9003
9004         trap cleanup_test_78 EXIT
9005
9006         [[ $F78SIZE -gt $((SMALLESTOST * $OSTCOUNT / 1024 - 80)) ]] &&
9007                 F78SIZE=$((SMALLESTOST * $OSTCOUNT / 1024 - 80))
9008
9009         [ "$SLOW" = "no" ] && NSEQ=1 && [ $F78SIZE -gt 32 ] && F78SIZE=32
9010         echo "File size: $F78SIZE"
9011         $LFS setstripe -c $OSTCOUNT $DIR/$tfile || error "setstripe failed"
9012         for i in $(seq 1 $NSEQ); do
9013                 FSIZE=$(($F78SIZE / ($NSEQ - $i + 1)))
9014                 echo directIO rdwr round $i of $NSEQ
9015                 $DIRECTIO rdwr $DIR/$tfile 0 $FSIZE 1048576||error "rdwr failed"
9016         done
9017
9018         cleanup_test_78
9019 }
9020 run_test 78 "handle large O_DIRECT writes correctly ============"
9021
9022 test_79() { # bug 12743
9023         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9024
9025         wait_delete_completed
9026
9027         BKTOTAL=$(calc_osc_kbytes kbytestotal)
9028         BKFREE=$(calc_osc_kbytes kbytesfree)
9029         BKAVAIL=$(calc_osc_kbytes kbytesavail)
9030
9031         STRING=`df -P $MOUNT | tail -n 1 | awk '{print $2","$3","$4}'`
9032         DFTOTAL=`echo $STRING | cut -d, -f1`
9033         DFUSED=`echo $STRING  | cut -d, -f2`
9034         DFAVAIL=`echo $STRING | cut -d, -f3`
9035         DFFREE=$(($DFTOTAL - $DFUSED))
9036
9037         ALLOWANCE=$((64 * $OSTCOUNT))
9038
9039         if [ $DFTOTAL -lt $(($BKTOTAL - $ALLOWANCE)) ] ||
9040            [ $DFTOTAL -gt $(($BKTOTAL + $ALLOWANCE)) ] ; then
9041                 error "df total($DFTOTAL) mismatch OST total($BKTOTAL)"
9042         fi
9043         if [ $DFFREE -lt $(($BKFREE - $ALLOWANCE)) ] ||
9044            [ $DFFREE -gt $(($BKFREE + $ALLOWANCE)) ] ; then
9045                 error "df free($DFFREE) mismatch OST free($BKFREE)"
9046         fi
9047         if [ $DFAVAIL -lt $(($BKAVAIL - $ALLOWANCE)) ] ||
9048            [ $DFAVAIL -gt $(($BKAVAIL + $ALLOWANCE)) ] ; then
9049                 error "df avail($DFAVAIL) mismatch OST avail($BKAVAIL)"
9050         fi
9051 }
9052 run_test 79 "df report consistency check ======================="
9053
9054 test_80() { # bug 10718
9055         remote_ost_nodsh && skip "remote OST with nodsh"
9056         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9057
9058         # relax strong synchronous semantics for slow backends like ZFS
9059         if [ "$ost1_FSTYPE" != "ldiskfs" ]; then
9060                 local soc="obdfilter.*.sync_lock_cancel"
9061                 local save=$(do_facet ost1 $LCTL get_param -n $soc | head -n1)
9062
9063                 # "sync_on_lock_cancel" was broken by v2_11_55_0-26-g7059644e9a
9064                 if [ -z "$save" ]; then
9065                         soc="obdfilter.*.sync_on_lock_cancel"
9066                         save=$(do_facet ost1 $LCTL get_param -n $soc | head -n1)
9067                 fi
9068
9069                 if [ "$save" != "never" ]; then
9070                         local hosts=$(comma_list $(osts_nodes))
9071
9072                         do_nodes $hosts $LCTL set_param $soc=never
9073                         stack_trap "do_nodes $hosts $LCTL set_param $soc=$save"
9074                 fi
9075         fi
9076
9077         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=1M
9078         sync; sleep 1; sync
9079         local before=$(date +%s)
9080         cancel_lru_locks osc
9081         local after=$(date +%s)
9082         local diff=$((after - before))
9083         [ $diff -le 1 ] || error "elapsed for 1M@1T = $diff"
9084
9085         rm -f $DIR/$tfile
9086 }
9087 run_test 80 "Page eviction is equally fast at high offsets too"
9088
9089 test_81a() { # LU-456
9090         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9091         remote_ost_nodsh && skip "remote OST with nodsh"
9092
9093         # define OBD_FAIL_OST_MAPBLK_ENOSPC    0x228
9094         # MUST OR with the OBD_FAIL_ONCE (0x80000000)
9095         do_facet ost1 lctl set_param fail_loc=0x80000228
9096
9097         # write should trigger a retry and success
9098         $LFS setstripe -i 0 -c 1 $DIR/$tfile
9099         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
9100         RC=$?
9101         if [ $RC -ne 0 ] ; then
9102                 error "write should success, but failed for $RC"
9103         fi
9104 }
9105 run_test 81a "OST should retry write when get -ENOSPC ==============="
9106
9107 test_81b() { # LU-456
9108         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9109         remote_ost_nodsh && skip "remote OST with nodsh"
9110
9111         # define OBD_FAIL_OST_MAPBLK_ENOSPC    0x228
9112         # Don't OR with the OBD_FAIL_ONCE (0x80000000)
9113         do_facet ost1 lctl set_param fail_loc=0x228
9114
9115         # write should retry several times and return -ENOSPC finally
9116         $LFS setstripe -i 0 -c 1 $DIR/$tfile
9117         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
9118         RC=$?
9119         ENOSPC=28
9120         if [ $RC -ne $ENOSPC ] ; then
9121                 error "dd should fail for -ENOSPC, but succeed."
9122         fi
9123 }
9124 run_test 81b "OST should return -ENOSPC when retry still fails ======="
9125
9126 test_99() {
9127         [ -z "$(which cvs 2>/dev/null)" ] && skip_env "could not find cvs"
9128
9129         test_mkdir $DIR/$tdir.cvsroot
9130         chown $RUNAS_ID $DIR/$tdir.cvsroot
9131
9132         cd $TMP
9133         $RUNAS cvs -d $DIR/$tdir.cvsroot init || error "cvs init failed"
9134
9135         cd /etc/init.d
9136         # some versions of cvs import exit(1) when asked to import links or
9137         # files they can't read.  ignore those files.
9138         local toignore=$(find . -type l -printf '-I %f\n' -o \
9139                          ! -perm /4 -printf '-I %f\n')
9140         $RUNAS cvs -d $DIR/$tdir.cvsroot import -m "nomesg" $toignore \
9141                 $tdir.reposname vtag rtag
9142
9143         cd $DIR
9144         test_mkdir $DIR/$tdir.reposname
9145         chown $RUNAS_ID $DIR/$tdir.reposname
9146         $RUNAS cvs -d $DIR/$tdir.cvsroot co $tdir.reposname
9147
9148         cd $DIR/$tdir.reposname
9149         $RUNAS touch foo99
9150         $RUNAS cvs add -m 'addmsg' foo99
9151         $RUNAS cvs update
9152         $RUNAS cvs commit -m 'nomsg' foo99
9153         rm -fr $DIR/$tdir.cvsroot
9154 }
9155 run_test 99 "cvs strange file/directory operations"
9156
9157 test_100() {
9158         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9159         [[ "$NETTYPE" =~ tcp ]] ||
9160                 skip_env "TCP secure port test, not useful for NETTYPE=$NETTYPE"
9161         remote_ost_nodsh && skip "remote OST with nodsh"
9162         remote_mds_nodsh && skip "remote MDS with nodsh"
9163         remote_servers ||
9164                 skip "useless for local single node setup"
9165
9166         netstat -tna | ( rc=1; while read PROT SND RCV LOCAL REMOTE STAT; do
9167                 [ "$PROT" != "tcp" ] && continue
9168                 RPORT=$(echo $REMOTE | cut -d: -f2)
9169                 [ "$RPORT" != "$ACCEPTOR_PORT" ] && continue
9170
9171                 rc=0
9172                 LPORT=`echo $LOCAL | cut -d: -f2`
9173                 if [ $LPORT -ge 1024 ]; then
9174                         echo "bad: $PROT $SND $RCV $LOCAL $REMOTE $STAT"
9175                         netstat -tna
9176                         error_exit "local: $LPORT > 1024, remote: $RPORT"
9177                 fi
9178         done
9179         [ "$rc" = 0 ] || error_exit "privileged port not found" )
9180 }
9181 run_test 100 "check local port using privileged port ==========="
9182
9183 function get_named_value()
9184 {
9185     local tag
9186
9187     tag=$1
9188     while read ;do
9189         line=$REPLY
9190         case $line in
9191         $tag*)
9192             echo $line | sed "s/^$tag[ ]*//"
9193             break
9194             ;;
9195         esac
9196     done
9197 }
9198
9199 export CACHE_MAX=$($LCTL get_param -n llite.*.max_cached_mb |
9200                    awk '/^max_cached_mb/ { print $2 }')
9201
9202 cleanup_101a() {
9203         $LCTL set_param -n llite.*.max_cached_mb $CACHE_MAX
9204         trap 0
9205 }
9206
9207 test_101a() {
9208         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9209
9210         local s
9211         local discard
9212         local nreads=10000
9213         local cache_limit=32
9214
9215         $LCTL set_param -n osc.*-osc*.rpc_stats 0
9216         trap cleanup_101a EXIT
9217         $LCTL set_param -n llite.*.read_ahead_stats 0
9218         $LCTL set_param -n llite.*.max_cached_mb $cache_limit
9219
9220         #
9221         # randomly read 10000 of 64K chunks from file 3x 32MB in size
9222         #
9223         echo "nreads: $nreads file size: $((cache_limit * 3))MB"
9224         $READS -f $DIR/$tfile -s$((cache_limit * 3192 * 1024)) -b65536 -C -n$nreads -t 180
9225
9226         discard=0
9227         for s in $($LCTL get_param -n llite.*.read_ahead_stats |
9228                 get_named_value 'read but discarded' | cut -d" " -f1); do
9229                         discard=$(($discard + $s))
9230         done
9231         cleanup_101a
9232
9233         $LCTL get_param osc.*-osc*.rpc_stats
9234         $LCTL get_param llite.*.read_ahead_stats
9235
9236         # Discard is generally zero, but sometimes a few random reads line up
9237         # and trigger larger readahead, which is wasted & leads to discards.
9238         if [[ $(($discard)) -gt $nreads ]]; then
9239                 error "too many ($discard) discarded pages"
9240         fi
9241         rm -f $DIR/$tfile || true
9242 }
9243 run_test 101a "check read-ahead for random reads"
9244
9245 setup_test101bc() {
9246         test_mkdir $DIR/$tdir
9247         local ssize=$1
9248         local FILE_LENGTH=$2
9249         STRIPE_OFFSET=0
9250
9251         local FILE_SIZE_MB=$((FILE_LENGTH / ssize))
9252
9253         local list=$(comma_list $(osts_nodes))
9254         set_osd_param $list '' read_cache_enable 0
9255         set_osd_param $list '' writethrough_cache_enable 0
9256
9257         trap cleanup_test101bc EXIT
9258         # prepare the read-ahead file
9259         $LFS setstripe -S $ssize -i $STRIPE_OFFSET -c $OSTCOUNT $DIR/$tfile
9260
9261         dd if=/dev/zero of=$DIR/$tfile bs=$ssize \
9262                                 count=$FILE_SIZE_MB 2> /dev/null
9263
9264 }
9265
9266 cleanup_test101bc() {
9267         trap 0
9268         rm -rf $DIR/$tdir
9269         rm -f $DIR/$tfile
9270
9271         local list=$(comma_list $(osts_nodes))
9272         set_osd_param $list '' read_cache_enable 1
9273         set_osd_param $list '' writethrough_cache_enable 1
9274 }
9275
9276 calc_total() {
9277         awk 'BEGIN{total=0}; {total+=$1}; END{print total}'
9278 }
9279
9280 ra_check_101() {
9281         local READ_SIZE=$1
9282         local STRIPE_SIZE=$2
9283         local FILE_LENGTH=$3
9284         local RA_INC=1048576
9285         local STRIDE_LENGTH=$((STRIPE_SIZE/READ_SIZE))
9286         local discard_limit=$((((STRIDE_LENGTH - 1)*3/(STRIDE_LENGTH*OSTCOUNT))* \
9287                              (STRIDE_LENGTH*OSTCOUNT - STRIDE_LENGTH)))
9288         DISCARD=$($LCTL get_param -n llite.*.read_ahead_stats |
9289                         get_named_value 'read but discarded' |
9290                         cut -d" " -f1 | calc_total)
9291         if [[ $DISCARD -gt $discard_limit ]]; then
9292                 $LCTL get_param llite.*.read_ahead_stats
9293                 error "Too many ($DISCARD) discarded pages with size (${READ_SIZE})"
9294         else
9295                 echo "Read-ahead success for size ${READ_SIZE}"
9296         fi
9297 }
9298
9299 test_101b() {
9300         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9301         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
9302
9303         local STRIPE_SIZE=1048576
9304         local STRIDE_SIZE=$((STRIPE_SIZE*OSTCOUNT))
9305
9306         if [ $SLOW == "yes" ]; then
9307                 local FILE_LENGTH=$((STRIDE_SIZE * 64))
9308         else
9309                 local FILE_LENGTH=$((STRIDE_SIZE * 8))
9310         fi
9311
9312         local ITERATION=$((FILE_LENGTH / STRIDE_SIZE))
9313
9314         # prepare the read-ahead file
9315         setup_test101bc $STRIPE_SIZE $FILE_LENGTH
9316         cancel_lru_locks osc
9317         for BIDX in 2 4 8 16 32 64 128 256
9318         do
9319                 local BSIZE=$((BIDX*4096))
9320                 local READ_COUNT=$((STRIPE_SIZE/BSIZE))
9321                 local STRIDE_LENGTH=$((STRIDE_SIZE/BSIZE))
9322                 local OFFSET=$((STRIPE_SIZE/BSIZE*(OSTCOUNT - 1)))
9323                 $LCTL set_param -n llite.*.read_ahead_stats 0
9324                 $READS -f $DIR/$tfile  -l $STRIDE_LENGTH -o $OFFSET \
9325                               -s $FILE_LENGTH -b $STRIPE_SIZE -a $READ_COUNT -n $ITERATION
9326                 cancel_lru_locks osc
9327                 ra_check_101 $BSIZE $STRIPE_SIZE $FILE_LENGTH
9328         done
9329         cleanup_test101bc
9330         true
9331 }
9332 run_test 101b "check stride-io mode read-ahead ================="
9333
9334 test_101c() {
9335         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9336
9337         local STRIPE_SIZE=1048576
9338         local FILE_LENGTH=$((STRIPE_SIZE*100))
9339         local nreads=10000
9340         local rsize=65536
9341         local osc_rpc_stats
9342
9343         setup_test101bc $STRIPE_SIZE $FILE_LENGTH
9344
9345         cancel_lru_locks osc
9346         $LCTL set_param osc.*.rpc_stats 0
9347         $READS -f $DIR/$tfile -s$FILE_LENGTH -b$rsize -n$nreads -t 180
9348         $LCTL get_param osc.*.rpc_stats
9349         for osc_rpc_stats in $($LCTL get_param -N osc.*.rpc_stats); do
9350                 local stats=$($LCTL get_param -n $osc_rpc_stats)
9351                 local lines=$(echo "$stats" | awk 'END {print NR;}')
9352                 local size
9353
9354                 if [ $lines -le 20 ]; then
9355                         echo "continue debug"
9356                         continue
9357                 fi
9358                 for size in 1 2 4 8; do
9359                         local rpc=$(echo "$stats" |
9360                                     awk '($1 == "'$size':") {print $2; exit; }')
9361                         [ $rpc != 0 ] && ((size * PAGE_SIZE < rsize)) &&
9362                                 error "Small $((size*PAGE_SIZE)) read IO $rpc!"
9363                 done
9364                 echo "$osc_rpc_stats check passed!"
9365         done
9366         cleanup_test101bc
9367         true
9368 }
9369 run_test 101c "check stripe_size aligned read-ahead ================="
9370
9371 test_101d() {
9372         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9373
9374         local file=$DIR/$tfile
9375         local sz_MB=${FILESIZE_101d:-80}
9376         local ra_MB=${READAHEAD_MB:-40}
9377
9378         local free_MB=$(($(df -P $DIR | tail -n 1 | awk '{ print $4 }') / 1024))
9379         [ $free_MB -lt $sz_MB ] &&
9380                 skip "Need free space ${sz_MB}M, have ${free_MB}M"
9381
9382         echo "Create test file $file size ${sz_MB}M, ${free_MB}M free"
9383         $LFS setstripe -c -1 $file || error "setstripe failed"
9384
9385         dd if=/dev/zero of=$file bs=1M count=$sz_MB || error "dd failed"
9386         echo Cancel LRU locks on lustre client to flush the client cache
9387         cancel_lru_locks osc
9388
9389         echo Disable read-ahead
9390         local old_RA=$($LCTL get_param -n llite.*.max_read_ahead_mb | head -n 1)
9391         $LCTL set_param -n llite.*.max_read_ahead_mb=0
9392         stack_trap "$LCTL set_param -n llite.*.max_read_ahead_mb $old_RA" EXIT
9393         $LCTL get_param -n llite.*.max_read_ahead_mb
9394
9395         echo "Reading the test file $file with read-ahead disabled"
9396         local sz_KB=$((sz_MB * 1024 / 4))
9397         # 10485760 bytes transferred in 0.000938 secs (11179579337 bytes/sec)
9398         # 104857600 bytes (105 MB) copied, 0.00876352 s, 12.0 GB/s
9399         local raOFF=$(LANG=C dd if=$file of=/dev/null bs=4k count=$sz_KB |&
9400                       sed -e '/records/d' -e 's/.* \([0-9]*\.[0-9]*\) *s.*/\1/')
9401
9402         echo "Cancel LRU locks on lustre client to flush the client cache"
9403         cancel_lru_locks osc
9404         echo Enable read-ahead with ${ra_MB}MB
9405         $LCTL set_param -n llite.*.max_read_ahead_mb=$ra_MB
9406
9407         echo "Reading the test file $file with read-ahead enabled"
9408         local raON=$(LANG=C dd if=$file of=/dev/null bs=4k count=$sz_KB |&
9409                      sed -e '/records/d' -e 's/.* \([0-9]*\.[0-9]*\) *s.*/\1/')
9410
9411         echo "read-ahead disabled time read $raOFF"
9412         echo "read-ahead enabled time read $raON"
9413
9414         rm -f $file
9415         wait_delete_completed
9416
9417         # use awk for this check instead of bash because it handles decimals
9418         awk "{ exit !($raOFF < 1.0 || $raOFF > $raON) }" <<<"ignore_me" ||
9419                 error "readahead ${raON}s > no-readahead ${raOFF}s ${sz_MB}M"
9420 }
9421 run_test 101d "file read with and without read-ahead enabled"
9422
9423 test_101e() {
9424         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9425
9426         local file=$DIR/$tfile
9427         local size_KB=500  #KB
9428         local count=100
9429         local bsize=1024
9430
9431         local free_KB=$(df -P $DIR | tail -n 1 | awk '{ print $4 }')
9432         local need_KB=$((count * size_KB))
9433         [[ $free_KB -le $need_KB ]] &&
9434                 skip_env "Need free space $need_KB, have $free_KB"
9435
9436         echo "Creating $count ${size_KB}K test files"
9437         for ((i = 0; i < $count; i++)); do
9438                 dd if=/dev/zero of=$file.$i bs=$bsize count=$size_KB 2>/dev/null
9439         done
9440
9441         echo "Cancel LRU locks on lustre client to flush the client cache"
9442         cancel_lru_locks $OSC
9443
9444         echo "Reset readahead stats"
9445         $LCTL set_param -n llite.*.read_ahead_stats 0
9446
9447         for ((i = 0; i < $count; i++)); do
9448                 dd if=$file.$i of=/dev/null bs=$bsize count=$size_KB 2>/dev/null
9449         done
9450
9451         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
9452                      get_named_value 'misses' | cut -d" " -f1 | calc_total)
9453
9454         for ((i = 0; i < $count; i++)); do
9455                 rm -rf $file.$i 2>/dev/null
9456         done
9457
9458         #10000 means 20% reads are missing in readahead
9459         [[ $miss -lt 10000 ]] ||  error "misses too much for small reads"
9460 }
9461 run_test 101e "check read-ahead for small read(1k) for small files(500k)"
9462
9463 test_101f() {
9464         which iozone || skip_env "no iozone installed"
9465
9466         local old_debug=$($LCTL get_param debug)
9467         old_debug=${old_debug#*=}
9468         $LCTL set_param debug="reada mmap"
9469
9470         # create a test file
9471         iozone -i 0 -+n -r 1m -s 128m -w -f $DIR/$tfile > /dev/null 2>&1
9472
9473         echo Cancel LRU locks on lustre client to flush the client cache
9474         cancel_lru_locks osc
9475
9476         echo Reset readahead stats
9477         $LCTL set_param -n llite.*.read_ahead_stats 0
9478
9479         echo mmap read the file with small block size
9480         iozone -i 1 -u 1 -l 1 -+n -r 32k -s 128m -B -f $DIR/$tfile \
9481                 > /dev/null 2>&1
9482
9483         echo checking missing pages
9484         $LCTL get_param llite.*.read_ahead_stats
9485         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
9486                         get_named_value 'misses' | cut -d" " -f1 | calc_total)
9487
9488         $LCTL set_param debug="$old_debug"
9489         [ $miss -lt 3 ] || error "misses too much pages ('$miss')!"
9490         rm -f $DIR/$tfile
9491 }
9492 run_test 101f "check mmap read performance"
9493
9494 test_101g_brw_size_test() {
9495         local mb=$1
9496         local pages=$((mb * 1048576 / PAGE_SIZE))
9497         local file=$DIR/$tfile
9498
9499         $LCTL set_param osc.*.max_pages_per_rpc=${mb}M ||
9500                 { error "unable to set max_pages_per_rpc=${mb}M"; return 1; }
9501         for mp in $($LCTL get_param -n osc.*.max_pages_per_rpc); do
9502                 [ $mp -ne $pages ] && error "max_pages_per_rpc $mp != $pages" &&
9503                         return 2
9504         done
9505
9506         stack_trap "rm -f $file" EXIT
9507         $LCTL set_param -n osc.*.rpc_stats=0
9508
9509         # 10 RPCs should be enough for the test
9510         local count=10
9511         dd if=/dev/zero of=$file bs=${mb}M count=$count ||
9512                 { error "dd write ${mb} MB blocks failed"; return 3; }
9513         cancel_lru_locks osc
9514         dd of=/dev/null if=$file bs=${mb}M count=$count ||
9515                 { error "dd write ${mb} MB blocks failed"; return 4; }
9516
9517         # calculate number of full-sized read and write RPCs
9518         rpcs=($($LCTL get_param -n 'osc.*.rpc_stats' |
9519                 sed -n '/pages per rpc/,/^$/p' |
9520                 awk '/'$pages':/ { reads += $2; writes += $6 }; \
9521                 END { print reads,writes }'))
9522         [ ${rpcs[0]} -ne $count ] && error "${rpcs[0]} != $count read RPCs" &&
9523                 return 5
9524         [ ${rpcs[1]} -ne $count ] && error "${rpcs[1]} != $count write RPCs" &&
9525                 return 6
9526
9527         return 0
9528 }
9529
9530 test_101g() {
9531         remote_ost_nodsh && skip "remote OST with nodsh"
9532
9533         local rpcs
9534         local osts=$(get_facets OST)
9535         local list=$(comma_list $(osts_nodes))
9536         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
9537         local brw_size="obdfilter.*.brw_size"
9538
9539         $LFS setstripe -i 0 -c 1 $DIR/$tfile
9540
9541         local orig_mb=$(do_facet ost1 $LCTL get_param -n $brw_size | head -n 1)
9542
9543         if { [ $OST1_VERSION -ge $(version_code 2.8.52) ] ||
9544                 { [ $OST1_VERSION -ge $(version_code 2.7.17) ] &&
9545                   [ $OST1_VERSION -lt $(version_code 2.7.50) ]; }; } &&
9546            { [ $CLIENT_VERSION -ge $(version_code 2.8.52) ] ||
9547                 { [ $CLIENT_VERSION -ge $(version_code 2.7.17) ] &&
9548                   [ $CLIENT_VERSION -lt $(version_code 2.7.50) ]; }; }; then
9549
9550                 [ $OST1_VERSION -ge $(version_code 2.9.52) ] &&
9551                         suffix="M"
9552
9553                 if [[ $orig_mb -lt 16 ]]; then
9554                         save_lustre_params $osts "$brw_size" > $p
9555                         do_nodes $list $LCTL set_param -n $brw_size=16$suffix ||
9556                                 error "set 16MB RPC size failed"
9557
9558                         echo "remount client to enable new RPC size"
9559                         remount_client $MOUNT || error "remount_client failed"
9560                 fi
9561
9562                 test_101g_brw_size_test 16 || error "16MB RPC test failed"
9563                 # should be able to set brw_size=12, but no rpc_stats for that
9564                 test_101g_brw_size_test 8 || error "8MB RPC test failed"
9565         fi
9566
9567         test_101g_brw_size_test 4 || error "4MB RPC test failed"
9568
9569         if [[ $orig_mb -lt 16 ]]; then
9570                 restore_lustre_params < $p
9571                 remount_client $MOUNT || error "remount_client restore failed"
9572         fi
9573
9574         rm -f $p $DIR/$tfile
9575 }
9576 run_test 101g "Big bulk(4/16 MiB) readahead"
9577
9578 test_101h() {
9579         $LFS setstripe -i 0 -c 1 $DIR/$tfile
9580
9581         dd if=/dev/zero of=$DIR/$tfile bs=1M count=70 ||
9582                 error "dd 70M file failed"
9583         echo Cancel LRU locks on lustre client to flush the client cache
9584         cancel_lru_locks osc
9585
9586         echo "Reset readahead stats"
9587         $LCTL set_param -n llite.*.read_ahead_stats 0
9588
9589         echo "Read 10M of data but cross 64M bundary"
9590         dd if=$DIR/$tfile of=/dev/null bs=10M skip=6 count=1
9591         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
9592                         get_named_value 'misses' | cut -d" " -f1 | calc_total)
9593         [ $miss -eq 1 ] || error "expected miss 1 but got $miss"
9594         rm -f $p $DIR/$tfile
9595 }
9596 run_test 101h "Readahead should cover current read window"
9597
9598 test_101i() {
9599         dd if=/dev/zero of=$DIR/$tfile bs=1M count=10 ||
9600                 error "dd 10M file failed"
9601
9602         local max_per_file_mb=$($LCTL get_param -n \
9603                 llite.*.max_read_ahead_per_file_mb 2>/dev/null)
9604         cancel_lru_locks osc
9605         stack_trap "$LCTL set_param llite.*.max_read_ahead_per_file_mb=$max_per_file_mb"
9606         $LCTL set_param llite.*.max_read_ahead_per_file_mb=1 ||
9607                 error "set max_read_ahead_per_file_mb to 1 failed"
9608
9609         echo "Reset readahead stats"
9610         $LCTL set_param llite.*.read_ahead_stats=0
9611
9612         dd if=$DIR/$tfile of=/dev/null bs=2M
9613
9614         $LCTL get_param llite.*.read_ahead_stats
9615         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
9616                      awk '/misses/ { print $2 }')
9617         [ $miss -eq 5 ] || error "expected misses 5 but got $miss"
9618         rm -f $DIR/$tfile
9619 }
9620 run_test 101i "allow current readahead to exceed reservation"
9621
9622 test_101j() {
9623         $LFS setstripe -i 0 -c 1 $DIR/$tfile ||
9624                 error "setstripe $DIR/$tfile failed"
9625         local file_size=$((1048576 * 16))
9626         local old_ra=$($LCTL get_param -n llite.*.max_read_ahead_mb | head -n 1)
9627         stack_trap "$LCTL set_param -n llite.*.max_read_ahead_mb $old_ra" EXIT
9628
9629         echo Disable read-ahead
9630         $LCTL set_param -n llite.*.max_read_ahead_mb=0
9631
9632         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$(($file_size / 1048576))
9633         for blk in $PAGE_SIZE 1048576 $file_size; do
9634                 cancel_lru_locks osc
9635                 echo "Reset readahead stats"
9636                 $LCTL set_param -n llite.*.read_ahead_stats=0
9637                 local count=$(($file_size / $blk))
9638                 dd if=$DIR/$tfile bs=$blk count=$count of=/dev/null
9639                 local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
9640                              get_named_value 'failed to fast read' |
9641                              cut -d" " -f1 | calc_total)
9642                 $LCTL get_param -n llite.*.read_ahead_stats
9643                 [ $miss -eq $count ] || error "expected $count got $miss"
9644         done
9645
9646         rm -f $p $DIR/$tfile
9647 }
9648 run_test 101j "A complete read block should be submitted when no RA"
9649
9650 setup_test102() {
9651         test_mkdir $DIR/$tdir
9652         chown $RUNAS_ID $DIR/$tdir
9653         STRIPE_SIZE=65536
9654         STRIPE_OFFSET=1
9655         STRIPE_COUNT=$OSTCOUNT
9656         [[ $OSTCOUNT -gt 4 ]] && STRIPE_COUNT=4
9657
9658         trap cleanup_test102 EXIT
9659         cd $DIR
9660         $1 $LFS setstripe -S $STRIPE_SIZE -i $STRIPE_OFFSET -c $STRIPE_COUNT $tdir
9661         cd $DIR/$tdir
9662         for num in 1 2 3 4; do
9663                 for count in $(seq 1 $STRIPE_COUNT); do
9664                         for idx in $(seq 0 $[$STRIPE_COUNT - 1]); do
9665                                 local size=`expr $STRIPE_SIZE \* $num`
9666                                 local file=file"$num-$idx-$count"
9667                                 $1 $LFS setstripe -S $size -i $idx -c $count $file
9668                         done
9669                 done
9670         done
9671
9672         cd $DIR
9673         $1 tar cf $TMP/f102.tar $tdir --xattrs
9674 }
9675
9676 cleanup_test102() {
9677         trap 0
9678         rm -f $TMP/f102.tar
9679         rm -rf $DIR/d0.sanity/d102
9680 }
9681
9682 test_102a() {
9683         [ "$UID" != 0 ] && skip "must run as root"
9684         [ -z "$(lctl get_param -n mdc.*-mdc-*.connect_flags | grep xattr)" ] &&
9685                 skip_env "must have user_xattr"
9686
9687         [ -z "$(which setfattr 2>/dev/null)" ] &&
9688                 skip_env "could not find setfattr"
9689
9690         local testfile=$DIR/$tfile
9691
9692         touch $testfile
9693         echo "set/get xattr..."
9694         setfattr -n trusted.name1 -v value1 $testfile ||
9695                 error "setfattr -n trusted.name1=value1 $testfile failed"
9696         getfattr -n trusted.name1 $testfile 2> /dev/null |
9697           grep "trusted.name1=.value1" ||
9698                 error "$testfile missing trusted.name1=value1"
9699
9700         setfattr -n user.author1 -v author1 $testfile ||
9701                 error "setfattr -n user.author1=author1 $testfile failed"
9702         getfattr -n user.author1 $testfile 2> /dev/null |
9703           grep "user.author1=.author1" ||
9704                 error "$testfile missing trusted.author1=author1"
9705
9706         echo "listxattr..."
9707         setfattr -n trusted.name2 -v value2 $testfile ||
9708                 error "$testfile unable to set trusted.name2"
9709         setfattr -n trusted.name3 -v value3 $testfile ||
9710                 error "$testfile unable to set trusted.name3"
9711         [ $(getfattr -d -m "^trusted" $testfile 2> /dev/null |
9712             grep "trusted.name" | wc -l) -eq 3 ] ||
9713                 error "$testfile missing 3 trusted.name xattrs"
9714
9715         setfattr -n user.author2 -v author2 $testfile ||
9716                 error "$testfile unable to set user.author2"
9717         setfattr -n user.author3 -v author3 $testfile ||
9718                 error "$testfile unable to set user.author3"
9719         [ $(getfattr -d -m "^user" $testfile 2> /dev/null |
9720             grep "user.author" | wc -l) -eq 3 ] ||
9721                 error "$testfile missing 3 user.author xattrs"
9722
9723         echo "remove xattr..."
9724         setfattr -x trusted.name1 $testfile ||
9725                 error "$testfile error deleting trusted.name1"
9726         getfattr -d -m trusted $testfile 2> /dev/null | grep "trusted.name1" &&
9727                 error "$testfile did not delete trusted.name1 xattr"
9728
9729         setfattr -x user.author1 $testfile ||
9730                 error "$testfile error deleting user.author1"
9731         echo "set lustre special xattr ..."
9732         $LFS setstripe -c1 $testfile
9733         local lovea=$(getfattr -n "trusted.lov" -e hex $testfile |
9734                 awk -F "=" '/trusted.lov/ { print $2 }' )
9735         setfattr -n "trusted.lov" -v $lovea $testfile ||
9736                 error "$testfile doesn't ignore setting trusted.lov again"
9737         setfattr -n "trusted.lov" -v "invalid_value" $testfile &&
9738                 error "$testfile allow setting invalid trusted.lov"
9739         rm -f $testfile
9740 }
9741 run_test 102a "user xattr test =================================="
9742
9743 check_102b_layout() {
9744         local layout="$*"
9745         local testfile=$DIR/$tfile
9746
9747         echo "test layout '$layout'"
9748         $LFS setstripe $layout $testfile || error "setstripe failed"
9749         $LFS getstripe -y $testfile
9750
9751         echo "get/set/list trusted.lov xattr ..." # b=10930
9752         local value=$(getfattr -n trusted.lov -e hex $testfile | grep trusted)
9753         [[ "$value" =~ "trusted.lov" ]] ||
9754                 error "can't get trusted.lov from $testfile"
9755         local stripe_count_orig=$($LFS getstripe -c $testfile) ||
9756                 error "getstripe failed"
9757
9758         $MCREATE $testfile.2 || error "mcreate $testfile.2 failed"
9759
9760         value=$(cut -d= -f2 <<<$value)
9761         # LU-13168: truncated xattr should fail if short lov_user_md header
9762         [ $CLIENT_VERSION -lt $(version_code 2.13.53) ] &&
9763                 lens="${#value}" || lens="$(seq 4 2 ${#value})"
9764         for len in $lens; do
9765                 echo "setfattr $len $testfile.2"
9766                 setfattr -n trusted.lov -v ${value:0:$len} $testfile.2 &&
9767                         [ $len -lt 66 ] && error "short xattr len=$len worked"
9768         done
9769         local stripe_size=$($LFS getstripe -S $testfile.2)
9770         local stripe_count=$($LFS getstripe -c $testfile.2)
9771         [[ $stripe_size -eq 65536 ]] ||
9772                 error "stripe size $stripe_size != 65536"
9773         [[ $stripe_count -eq $stripe_count_orig ]] ||
9774                 error "stripe count $stripe_count != $stripe_count_orig"
9775         rm $testfile $testfile.2
9776 }
9777
9778 test_102b() {
9779         [ -z "$(which setfattr 2>/dev/null)" ] &&
9780                 skip_env "could not find setfattr"
9781         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
9782
9783         # check plain layout
9784         check_102b_layout -S 65536 -i 1 -c $OSTCOUNT
9785
9786         # and also check composite layout
9787         check_102b_layout -E 1M -S 65536 -i 1 -c $OSTCOUNT -Eeof -S4M
9788
9789 }
9790 run_test 102b "getfattr/setfattr for trusted.lov EAs"
9791
9792 test_102c() {
9793         [ -z "$(which setfattr 2>/dev/null)" ] &&
9794                 skip_env "could not find setfattr"
9795         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
9796
9797         # b10930: get/set/list lustre.lov xattr
9798         echo "get/set/list lustre.lov xattr ..."
9799         test_mkdir $DIR/$tdir
9800         chown $RUNAS_ID $DIR/$tdir
9801         local testfile=$DIR/$tdir/$tfile
9802         $RUNAS $LFS setstripe -S 65536 -i 1 -c $OSTCOUNT $testfile ||
9803                 error "setstripe failed"
9804         local STRIPECOUNT=$($RUNAS $LFS getstripe -c $testfile) ||
9805                 error "getstripe failed"
9806         $RUNAS getfattr -d -m "^lustre" $testfile 2> /dev/null | \
9807         grep "lustre.lov" || error "can't get lustre.lov from $testfile"
9808
9809         local testfile2=${testfile}2
9810         local value=`getfattr -n lustre.lov $testfile 2> /dev/null | \
9811                      grep "lustre.lov" |sed -e 's/[^=]\+=//'  `
9812
9813         $RUNAS $MCREATE $testfile2
9814         $RUNAS setfattr -n lustre.lov -v $value $testfile2
9815         local stripe_size=$($RUNAS $LFS getstripe -S $testfile2)
9816         local stripe_count=$($RUNAS $LFS getstripe -c $testfile2)
9817         [ $stripe_size -eq 65536 ] || error "stripe size $stripe_size != 65536"
9818         [ $stripe_count -eq $STRIPECOUNT ] ||
9819                 error "stripe count $stripe_count != $STRIPECOUNT"
9820 }
9821 run_test 102c "non-root getfattr/setfattr for lustre.lov EAs ==========="
9822
9823 compare_stripe_info1() {
9824         local stripe_index_all_zero=true
9825
9826         for num in 1 2 3 4; do
9827                 for count in $(seq 1 $STRIPE_COUNT); do
9828                         for offset in $(seq 0 $[$STRIPE_COUNT - 1]); do
9829                                 local size=$((STRIPE_SIZE * num))
9830                                 local file=file"$num-$offset-$count"
9831                                 stripe_size=$($LFS getstripe -S $PWD/$file)
9832                                 [[ $stripe_size -ne $size ]] &&
9833                                     error "$file: size $stripe_size != $size"
9834                                 stripe_count=$($LFS getstripe -c $PWD/$file)
9835                                 # allow fewer stripes to be created, ORI-601
9836                                 [[ $stripe_count -lt $(((3 * count + 3) / 4)) ]] &&
9837                                     error "$file: count $stripe_count != $count"
9838                                 stripe_index=$($LFS getstripe -i $PWD/$file)
9839                                 [[ $stripe_index -ne 0 ]] &&
9840                                         stripe_index_all_zero=false
9841                         done
9842                 done
9843         done
9844         $stripe_index_all_zero &&
9845                 error "all files are being extracted starting from OST index 0"
9846         return 0
9847 }
9848
9849 have_xattrs_include() {
9850         tar --help | grep -q xattrs-include &&
9851                 echo --xattrs-include="lustre.*"
9852 }
9853
9854 test_102d() {
9855         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9856         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
9857
9858         XINC=$(have_xattrs_include)
9859         setup_test102
9860         tar xf $TMP/f102.tar -C $DIR/$tdir --xattrs $XINC
9861         cd $DIR/$tdir/$tdir
9862         compare_stripe_info1
9863 }
9864 run_test 102d "tar restore stripe info from tarfile,not keep osts"
9865
9866 test_102f() {
9867         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9868         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
9869
9870         XINC=$(have_xattrs_include)
9871         setup_test102
9872         test_mkdir $DIR/$tdir.restore
9873         cd $DIR
9874         tar cf - --xattrs $tdir | tar xf - \
9875                 -C $DIR/$tdir.restore --xattrs $XINC
9876         cd $DIR/$tdir.restore/$tdir
9877         compare_stripe_info1
9878 }
9879 run_test 102f "tar copy files, not keep osts"
9880
9881 grow_xattr() {
9882         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep xattr)" ] &&
9883                 skip "must have user_xattr"
9884         [ -z "$(which setfattr 2>/dev/null)" ] &&
9885                 skip_env "could not find setfattr"
9886         [ -z "$(which getfattr 2>/dev/null)" ] &&
9887                 skip_env "could not find getfattr"
9888
9889         local xsize=${1:-1024}  # in bytes
9890         local file=$DIR/$tfile
9891         local value="$(generate_string $xsize)"
9892         local xbig=trusted.big
9893         local toobig=$2
9894
9895         touch $file
9896         log "save $xbig on $file"
9897         if [ -z "$toobig" ]
9898         then
9899                 setfattr -n $xbig -v $value $file ||
9900                         error "saving $xbig on $file failed"
9901         else
9902                 setfattr -n $xbig -v $value $file &&
9903                         error "saving $xbig on $file succeeded"
9904                 return 0
9905         fi
9906
9907         local orig=$(get_xattr_value $xbig $file)
9908         [[ "$orig" != "$value" ]] && error "$xbig different after saving $xbig"
9909
9910         local xsml=trusted.sml
9911         log "save $xsml on $file"
9912         setfattr -n $xsml -v val $file || error "saving $xsml on $file failed"
9913
9914         local new=$(get_xattr_value $xbig $file)
9915         [[ "$new" != "$orig" ]] && error "$xbig different after saving $xsml"
9916
9917         log "grow $xsml on $file"
9918         setfattr -n $xsml -v "$value" $file ||
9919                 error "growing $xsml on $file failed"
9920
9921         new=$(get_xattr_value $xbig $file)
9922         [[ "$new" != "$orig" ]] && error "$xbig different after growing $xsml"
9923         log "$xbig still valid after growing $xsml"
9924
9925         rm -f $file
9926 }
9927
9928 test_102h() { # bug 15777
9929         grow_xattr 1024
9930 }
9931 run_test 102h "grow xattr from inside inode to external block"
9932
9933 test_102ha() {
9934         large_xattr_enabled || skip_env "ea_inode feature disabled"
9935
9936         echo "setting xattr of max xattr size: $(max_xattr_size)"
9937         grow_xattr $(max_xattr_size)
9938
9939         echo "setting xattr of > max xattr size: $(max_xattr_size) + 10"
9940         echo "This should fail:"
9941         grow_xattr $(($(max_xattr_size) + 10)) 1
9942 }
9943 run_test 102ha "grow xattr from inside inode to external inode"
9944
9945 test_102i() { # bug 17038
9946         [ -z "$(which getfattr 2>/dev/null)" ] &&
9947                 skip "could not find getfattr"
9948
9949         touch $DIR/$tfile
9950         ln -s $DIR/$tfile $DIR/${tfile}link
9951         getfattr -n trusted.lov $DIR/$tfile ||
9952                 error "lgetxattr on $DIR/$tfile failed"
9953         getfattr -h -n trusted.lov $DIR/${tfile}link 2>&1 |
9954                 grep -i "no such attr" ||
9955                 error "error for lgetxattr on $DIR/${tfile}link is not ENODATA"
9956         rm -f $DIR/$tfile $DIR/${tfile}link
9957 }
9958 run_test 102i "lgetxattr test on symbolic link ============"
9959
9960 test_102j() {
9961         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9962         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
9963
9964         XINC=$(have_xattrs_include)
9965         setup_test102 "$RUNAS"
9966         chown $RUNAS_ID $DIR/$tdir
9967         $RUNAS tar xf $TMP/f102.tar -C $DIR/$tdir --xattrs $XINC
9968         cd $DIR/$tdir/$tdir
9969         compare_stripe_info1 "$RUNAS"
9970 }
9971 run_test 102j "non-root tar restore stripe info from tarfile, not keep osts ==="
9972
9973 test_102k() {
9974         [ -z "$(which setfattr 2>/dev/null)" ] &&
9975                 skip "could not find setfattr"
9976
9977         touch $DIR/$tfile
9978         # b22187 just check that does not crash for regular file.
9979         setfattr -n trusted.lov $DIR/$tfile
9980         # b22187 'setfattr -n trusted.lov' should remove LOV EA for directories
9981         local test_kdir=$DIR/$tdir
9982         test_mkdir $test_kdir
9983         local default_size=$($LFS getstripe -S $test_kdir)
9984         local default_count=$($LFS getstripe -c $test_kdir)
9985         local default_offset=$($LFS getstripe -i $test_kdir)
9986         $LFS setstripe -S 65536 -i 0 -c $OSTCOUNT $test_kdir ||
9987                 error 'dir setstripe failed'
9988         setfattr -n trusted.lov $test_kdir
9989         local stripe_size=$($LFS getstripe -S $test_kdir)
9990         local stripe_count=$($LFS getstripe -c $test_kdir)
9991         local stripe_offset=$($LFS getstripe -i $test_kdir)
9992         [ $stripe_size -eq $default_size ] ||
9993                 error "stripe size $stripe_size != $default_size"
9994         [ $stripe_count -eq $default_count ] ||
9995                 error "stripe count $stripe_count != $default_count"
9996         [ $stripe_offset -eq $default_offset ] ||
9997                 error "stripe offset $stripe_offset != $default_offset"
9998         rm -rf $DIR/$tfile $test_kdir
9999 }
10000 run_test 102k "setfattr without parameter of value shouldn't cause a crash"
10001
10002 test_102l() {
10003         [ -z "$(which getfattr 2>/dev/null)" ] &&
10004                 skip "could not find getfattr"
10005
10006         # LU-532 trusted. xattr is invisible to non-root
10007         local testfile=$DIR/$tfile
10008
10009         touch $testfile
10010
10011         echo "listxattr as user..."
10012         chown $RUNAS_ID $testfile
10013         $RUNAS getfattr -d -m '.*' $testfile 2>&1 |
10014             grep -q "trusted" &&
10015                 error "$testfile trusted xattrs are user visible"
10016
10017         return 0;
10018 }
10019 run_test 102l "listxattr size test =================================="
10020
10021 test_102m() { # LU-3403 llite: error of listxattr when buffer is small
10022         local path=$DIR/$tfile
10023         touch $path
10024
10025         listxattr_size_check $path || error "listattr_size_check $path failed"
10026 }
10027 run_test 102m "Ensure listxattr fails on small bufffer ========"
10028
10029 cleanup_test102
10030
10031 getxattr() { # getxattr path name
10032         # Return the base64 encoding of the value of xattr name on path.
10033         local path=$1
10034         local name=$2
10035
10036         # # getfattr --absolute-names --encoding=base64 --name=trusted.lov $path
10037         # file: $path
10038         # trusted.lov=0s0AvRCwEAAAAGAAAAAAAAAAAEAAACAAAAAAAQAAEAA...AAAAAAAAA=
10039         #
10040         # We print just 0s0AvRCwEAAAAGAAAAAAAAAAAEAAACAAAAAAAQAAEAA...AAAAAAAAA=
10041
10042         getfattr --absolute-names --encoding=base64 --name=$name $path |
10043                 awk -F= -v name=$name '$1 == name {
10044                         print substr($0, index($0, "=") + 1);
10045         }'
10046 }
10047
10048 test_102n() { # LU-4101 mdt: protect internal xattrs
10049         [ -z "$(which setfattr 2>/dev/null)" ] &&
10050                 skip "could not find setfattr"
10051         if [ $MDS1_VERSION -lt $(version_code 2.5.50) ]
10052         then
10053                 skip "MDT < 2.5.50 allows setxattr on internal trusted xattrs"
10054         fi
10055
10056         local file0=$DIR/$tfile.0
10057         local file1=$DIR/$tfile.1
10058         local xattr0=$TMP/$tfile.0
10059         local xattr1=$TMP/$tfile.1
10060         local namelist="lov lma lmv link fid version som hsm"
10061         local name
10062         local value
10063
10064         rm -rf $file0 $file1 $xattr0 $xattr1
10065         touch $file0 $file1
10066
10067         # Get 'before' xattrs of $file1.
10068         getfattr --absolute-names --dump --match=- $file1 > $xattr0
10069
10070         [ $MDS1_VERSION -lt $(version_code 2.8.53) ] &&
10071                 namelist+=" lfsck_namespace"
10072         for name in $namelist; do
10073                 # Try to copy xattr from $file0 to $file1.
10074                 value=$(getxattr $file0 trusted.$name 2> /dev/null)
10075
10076                 setfattr --name=trusted.$name --value="$value" $file1 ||
10077                         error "setxattr 'trusted.$name' failed"
10078
10079                 # Try to set a garbage xattr.
10080                 value=0sVGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIGl0c2VsZi4=
10081
10082                 if [[ x$name == "xlov" ]]; then
10083                         setfattr --name=trusted.lov --value="$value" $file1 &&
10084                         error "setxattr invalid 'trusted.lov' success"
10085                 else
10086                         setfattr --name=trusted.$name --value="$value" $file1 ||
10087                                 error "setxattr invalid 'trusted.$name' failed"
10088                 fi
10089
10090                 # Try to remove the xattr from $file1. We don't care if this
10091                 # appears to succeed or fail, we just don't want there to be
10092                 # any changes or crashes.
10093                 setfattr --remove=$trusted.$name $file1 2> /dev/null
10094         done
10095
10096         if [ $MDS1_VERSION -gt $(version_code 2.6.50) ]
10097         then
10098                 name="lfsck_ns"
10099                 # Try to copy xattr from $file0 to $file1.
10100                 value=$(getxattr $file0 trusted.$name 2> /dev/null)
10101
10102                 setfattr --name=trusted.$name --value="$value" $file1 ||
10103                         error "setxattr 'trusted.$name' failed"
10104
10105                 # Try to set a garbage xattr.
10106                 value=0sVGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIGl0c2VsZi4=
10107
10108                 setfattr --name=trusted.$name --value="$value" $file1 ||
10109                         error "setxattr 'trusted.$name' failed"
10110
10111                 # Try to remove the xattr from $file1. We don't care if this
10112                 # appears to succeed or fail, we just don't want there to be
10113                 # any changes or crashes.
10114                 setfattr --remove=$trusted.$name $file1 2> /dev/null
10115         fi
10116
10117         # Get 'after' xattrs of file1.
10118         getfattr --absolute-names --dump --match=- $file1 > $xattr1
10119
10120         if ! diff $xattr0 $xattr1; then
10121                 error "before and after xattrs of '$file1' differ"
10122         fi
10123
10124         rm -rf $file0 $file1 $xattr0 $xattr1
10125
10126         return 0
10127 }
10128 run_test 102n "silently ignore setxattr on internal trusted xattrs"
10129
10130 test_102p() { # LU-4703 setxattr did not check ownership
10131         [ $MDS1_VERSION -lt $(version_code 2.5.56) ] &&
10132                 skip "MDS needs to be at least 2.5.56"
10133
10134         local testfile=$DIR/$tfile
10135
10136         touch $testfile
10137
10138         echo "setfacl as user..."
10139         $RUNAS setfacl -m "u:$RUNAS_ID:rwx" $testfile
10140         [ $? -ne 0 ] || error "setfacl by $RUNAS_ID was allowed on $testfile"
10141
10142         echo "setfattr as user..."
10143         setfacl -m "u:$RUNAS_ID:---" $testfile
10144         $RUNAS setfattr -x system.posix_acl_access $testfile
10145         [ $? -ne 0 ] || error "setfattr by $RUNAS_ID was allowed on $testfile"
10146 }
10147 run_test 102p "check setxattr(2) correctly fails without permission"
10148
10149 test_102q() {
10150         [ $MDS1_VERSION -lt $(version_code 2.6.92) ] &&
10151                 skip "MDS needs to be at least 2.6.92"
10152
10153         orphan_linkea_check $DIR/$tfile || error "orphan_linkea_check"
10154 }
10155 run_test 102q "flistxattr should not return trusted.link EAs for orphans"
10156
10157 test_102r() {
10158         [ $MDS1_VERSION -lt $(version_code 2.6.93) ] &&
10159                 skip "MDS needs to be at least 2.6.93"
10160
10161         touch $DIR/$tfile || error "touch"
10162         setfattr -n user.$(basename $tfile) $DIR/$tfile || error "setfattr"
10163         getfattr -n user.$(basename $tfile) $DIR/$tfile || error "getfattr"
10164         rm $DIR/$tfile || error "rm"
10165
10166         #normal directory
10167         mkdir -p $DIR/$tdir || error "mkdir"
10168         setfattr -n user.$(basename $tdir) $DIR/$tdir || error "setfattr dir"
10169         getfattr -n user.$(basename $tdir) $DIR/$tdir || error "getfattr dir"
10170         setfattr -x user.$(basename $tdir) $DIR/$tdir ||
10171                 error "$testfile error deleting user.author1"
10172         getfattr -d -m user.$(basename $tdir) 2> /dev/null |
10173                 grep "user.$(basename $tdir)" &&
10174                 error "$tdir did not delete user.$(basename $tdir)"
10175         rmdir $DIR/$tdir || error "rmdir"
10176
10177         #striped directory
10178         test_mkdir $DIR/$tdir
10179         setfattr -n user.$(basename $tdir) $DIR/$tdir || error "setfattr dir"
10180         getfattr -n user.$(basename $tdir) $DIR/$tdir || error "getfattr dir"
10181         setfattr -x user.$(basename $tdir) $DIR/$tdir ||
10182                 error "$testfile error deleting user.author1"
10183         getfattr -d -m user.$(basename $tdir) 2> /dev/null |
10184                 grep "user.$(basename $tdir)" &&
10185                 error "$tdir did not delete user.$(basename $tdir)"
10186         rmdir $DIR/$tdir || error "rm striped dir"
10187 }
10188 run_test 102r "set EAs with empty values"
10189
10190 test_102s() {
10191         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
10192                 skip "MDS needs to be at least 2.11.52"
10193
10194         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
10195
10196         save_lustre_params client "llite.*.xattr_cache" > $save
10197
10198         for cache in 0 1; do
10199                 lctl set_param llite.*.xattr_cache=$cache
10200
10201                 rm -f $DIR/$tfile
10202                 touch $DIR/$tfile || error "touch"
10203                 for prefix in lustre security system trusted user; do
10204                         # Note getxattr() may fail with 'Operation not
10205                         # supported' or 'No such attribute' depending
10206                         # on prefix and cache.
10207                         getfattr -n $prefix.n102s $DIR/$tfile &&
10208                                 error "getxattr '$prefix.n102s' should fail (cache = $cache)"
10209                 done
10210         done
10211
10212         restore_lustre_params < $save
10213 }
10214 run_test 102s "getting nonexistent xattrs should fail"
10215
10216 test_102t() {
10217         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
10218                 skip "MDS needs to be at least 2.11.52"
10219
10220         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
10221
10222         save_lustre_params client "llite.*.xattr_cache" > $save
10223
10224         for cache in 0 1; do
10225                 lctl set_param llite.*.xattr_cache=$cache
10226
10227                 for buf_size in 0 256; do
10228                         rm -f $DIR/$tfile
10229                         touch $DIR/$tfile || error "touch"
10230                         setfattr -n user.multiop $DIR/$tfile
10231                         $MULTIOP $DIR/$tfile oa$buf_size ||
10232                                 error "cannot get zero length xattr value (buf_size = $buf_size)"
10233                 done
10234         done
10235
10236         restore_lustre_params < $save
10237 }
10238 run_test 102t "zero length xattr values handled correctly"
10239
10240 run_acl_subtest()
10241 {
10242     $LUSTRE/tests/acl/run $LUSTRE/tests/acl/$1.test
10243     return $?
10244 }
10245
10246 test_103a() {
10247         [ "$UID" != 0 ] && skip "must run as root"
10248         $GSS && skip_env "could not run under gss"
10249         [ -z "$(lctl get_param -n mdc.*-mdc-*.connect_flags | grep acl)" ] &&
10250                 skip_env "must have acl enabled"
10251         [ -z "$(which setfacl 2>/dev/null)" ] &&
10252                 skip_env "could not find setfacl"
10253         remote_mds_nodsh && skip "remote MDS with nodsh"
10254
10255         gpasswd -a daemon bin                           # LU-5641
10256         do_facet $SINGLEMDS gpasswd -a daemon bin       # LU-5641
10257
10258         declare -a identity_old
10259
10260         for num in $(seq $MDSCOUNT); do
10261                 switch_identity $num true || identity_old[$num]=$?
10262         done
10263
10264         SAVE_UMASK=$(umask)
10265         umask 0022
10266         mkdir -p $DIR/$tdir
10267         cd $DIR/$tdir
10268
10269         echo "performing cp ..."
10270         run_acl_subtest cp || error "run_acl_subtest cp failed"
10271         echo "performing getfacl-noacl..."
10272         run_acl_subtest getfacl-noacl || error "getfacl-noacl test failed"
10273         echo "performing misc..."
10274         run_acl_subtest misc || error  "misc test failed"
10275         echo "performing permissions..."
10276         run_acl_subtest permissions || error "permissions failed"
10277         # LU-1482 mdd: Setting xattr are properly checked with and without ACLs
10278         if [ $MDS1_VERSION -gt $(version_code 2.8.55) ] ||
10279                 { [ $MDS1_VERSION -lt $(version_code 2.6) ] &&
10280                         [ $MDS1_VERSION -ge $(version_code 2.5.29) ]; }
10281         then
10282                 echo "performing permissions xattr..."
10283                 run_acl_subtest permissions_xattr ||
10284                         error "permissions_xattr failed"
10285         fi
10286         echo "performing setfacl..."
10287         run_acl_subtest setfacl || error  "setfacl test failed"
10288
10289         # inheritance test got from HP
10290         echo "performing inheritance..."
10291         cp $LUSTRE/tests/acl/make-tree . || error "cannot copy make-tree"
10292         chmod +x make-tree || error "chmod +x failed"
10293         run_acl_subtest inheritance || error "inheritance test failed"
10294         rm -f make-tree
10295
10296         echo "LU-974 ignore umask when acl is enabled..."
10297         run_acl_subtest 974 || error "LU-974 umask test failed"
10298         if [ $MDSCOUNT -ge 2 ]; then
10299                 run_acl_subtest 974_remote ||
10300                         error "LU-974 umask test failed under remote dir"
10301         fi
10302
10303         echo "LU-2561 newly created file is same size as directory..."
10304         if [ "$mds1_FSTYPE" != "zfs" ]; then
10305                 run_acl_subtest 2561 || error "LU-2561 test failed"
10306         else
10307                 run_acl_subtest 2561_zfs || error "LU-2561 zfs test failed"
10308         fi
10309
10310         run_acl_subtest 4924 || error "LU-4924 test failed"
10311
10312         cd $SAVE_PWD
10313         umask $SAVE_UMASK
10314
10315         for num in $(seq $MDSCOUNT); do
10316                 if [ "${identity_old[$num]}" = 1 ]; then
10317                         switch_identity $num false || identity_old[$num]=$?
10318                 fi
10319         done
10320 }
10321 run_test 103a "acl test"
10322
10323 test_103b() {
10324         declare -a pids
10325         local U
10326
10327         for U in {0..511}; do
10328                 {
10329                 local O=$(printf "%04o" $U)
10330
10331                 umask $(printf "%04o" $((511 ^ $O)))
10332                 $LFS setstripe -c 1 $DIR/$tfile.s$O
10333                 local S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.s$O))
10334
10335                 (( $S == ($O & 0666) )) ||
10336                         error "lfs setstripe $DIR/$tfile.s$O '$S' != '$O'"
10337
10338                 $LFS setstripe -E16M -c 1 -E1G -S4M $DIR/$tfile.p$O
10339                 S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.p$O))
10340                 (( $S == ($O & 0666) )) ||
10341                         error "lfs setstripe -E $DIR/$tfile.p$O '$S' != '$O'"
10342
10343                 $LFS setstripe -N2 -c 1 $DIR/$tfile.m$O
10344                 S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.m$O))
10345                 (( $S == ($O & 0666) )) ||
10346                         error "lfs setstripe -N2 $DIR/$tfile.m$O '$S' != '$O'"
10347                 rm -f $DIR/$tfile.[smp]$0
10348                 } &
10349                 local pid=$!
10350
10351                 # limit the concurrently running threads to 64. LU-11878
10352                 local idx=$((U % 64))
10353                 [ -z "${pids[idx]}" ] || wait ${pids[idx]}
10354                 pids[idx]=$pid
10355         done
10356         wait
10357 }
10358 run_test 103b "umask lfs setstripe"
10359
10360 test_103c() {
10361         mkdir -p $DIR/$tdir
10362         cp -rp $DIR/$tdir $DIR/$tdir.bak
10363
10364         [ -n "$(getfattr -d -m. $DIR/$tdir | grep posix_acl_default)" ] &&
10365                 error "$DIR/$tdir shouldn't contain default ACL"
10366         [ -n "$(getfattr -d -m. $DIR/$tdir.bak | grep posix_acl_default)" ] &&
10367                 error "$DIR/$tdir.bak shouldn't contain default ACL"
10368         true
10369 }
10370 run_test 103c "'cp -rp' won't set empty acl"
10371
10372 test_104a() {
10373         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10374
10375         touch $DIR/$tfile
10376         lfs df || error "lfs df failed"
10377         lfs df -ih || error "lfs df -ih failed"
10378         lfs df -h $DIR || error "lfs df -h $DIR failed"
10379         lfs df -i $DIR || error "lfs df -i $DIR failed"
10380         lfs df $DIR/$tfile || error "lfs df $DIR/$tfile failed"
10381         lfs df -ih $DIR/$tfile || error "lfs df -ih $DIR/$tfile failed"
10382
10383         local OSC=$(lctl dl | grep OST0000-osc-[^M] | awk '{ print $4 }')
10384         lctl --device %$OSC deactivate
10385         lfs df || error "lfs df with deactivated OSC failed"
10386         lctl --device %$OSC activate
10387         # wait the osc back to normal
10388         wait_osc_import_ready client ost
10389
10390         lfs df || error "lfs df with reactivated OSC failed"
10391         rm -f $DIR/$tfile
10392 }
10393 run_test 104a "lfs df [-ih] [path] test ========================="
10394
10395 test_104b() {
10396         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10397         [ $RUNAS_ID -eq $UID ] &&
10398                 skip_env "RUNAS_ID = UID = $UID -- skipping"
10399
10400         denied_cnt=$(($($RUNAS $LFS check servers 2>&1 |
10401                         grep "Permission denied" | wc -l)))
10402         if [ $denied_cnt -ne 0 ]; then
10403                 error "lfs check servers test failed"
10404         fi
10405 }
10406 run_test 104b "$RUNAS lfs check servers test ===================="
10407
10408 test_105a() {
10409         # doesn't work on 2.4 kernels
10410         touch $DIR/$tfile
10411         if $(flock_is_enabled); then
10412                 flocks_test 1 on -f $DIR/$tfile || error "fail flock on"
10413         else
10414                 flocks_test 1 off -f $DIR/$tfile || error "fail flock off"
10415         fi
10416         rm -f $DIR/$tfile
10417 }
10418 run_test 105a "flock when mounted without -o flock test ========"
10419
10420 test_105b() {
10421         touch $DIR/$tfile
10422         if $(flock_is_enabled); then
10423                 flocks_test 1 on -c $DIR/$tfile || error "fail flock on"
10424         else
10425                 flocks_test 1 off -c $DIR/$tfile || error "fail flock off"
10426         fi
10427         rm -f $DIR/$tfile
10428 }
10429 run_test 105b "fcntl when mounted without -o flock test ========"
10430
10431 test_105c() {
10432         touch $DIR/$tfile
10433         if $(flock_is_enabled); then
10434                 flocks_test 1 on -l $DIR/$tfile || error "fail flock on"
10435         else
10436                 flocks_test 1 off -l $DIR/$tfile || error "fail flock off"
10437         fi
10438         rm -f $DIR/$tfile
10439 }
10440 run_test 105c "lockf when mounted without -o flock test"
10441
10442 test_105d() { # bug 15924
10443         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10444
10445         test_mkdir $DIR/$tdir
10446         flock_is_enabled || skip_env "mount w/o flock enabled"
10447         #define OBD_FAIL_LDLM_CP_CB_WAIT  0x315
10448         $LCTL set_param fail_loc=0x80000315
10449         flocks_test 2 $DIR/$tdir
10450 }
10451 run_test 105d "flock race (should not freeze) ========"
10452
10453 test_105e() { # bug 22660 && 22040
10454         flock_is_enabled || skip_env "mount w/o flock enabled"
10455
10456         touch $DIR/$tfile
10457         flocks_test 3 $DIR/$tfile
10458 }
10459 run_test 105e "Two conflicting flocks from same process"
10460
10461 test_106() { #bug 10921
10462         test_mkdir $DIR/$tdir
10463         $DIR/$tdir && error "exec $DIR/$tdir succeeded"
10464         chmod 777 $DIR/$tdir || error "chmod $DIR/$tdir failed"
10465 }
10466 run_test 106 "attempt exec of dir followed by chown of that dir"
10467
10468 test_107() {
10469         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10470
10471         CDIR=`pwd`
10472         local file=core
10473
10474         cd $DIR
10475         rm -f $file
10476
10477         local save_pattern=$(sysctl -n kernel.core_pattern)
10478         local save_uses_pid=$(sysctl -n kernel.core_uses_pid)
10479         sysctl -w kernel.core_pattern=$file
10480         sysctl -w kernel.core_uses_pid=0
10481
10482         ulimit -c unlimited
10483         sleep 60 &
10484         SLEEPPID=$!
10485
10486         sleep 1
10487
10488         kill -s 11 $SLEEPPID
10489         wait $SLEEPPID
10490         if [ -e $file ]; then
10491                 size=`stat -c%s $file`
10492                 [ $size -eq 0 ] && error "Fail to create core file $file"
10493         else
10494                 error "Fail to create core file $file"
10495         fi
10496         rm -f $file
10497         sysctl -w kernel.core_pattern=$save_pattern
10498         sysctl -w kernel.core_uses_pid=$save_uses_pid
10499         cd $CDIR
10500 }
10501 run_test 107 "Coredump on SIG"
10502
10503 test_110() {
10504         test_mkdir $DIR/$tdir
10505         test_mkdir $DIR/$tdir/$(str_repeat 'a' 255)
10506         $LFS mkdir -c $MDSCOUNT $DIR/$tdir/$(str_repeat 'b' 256) &&
10507                 error "mkdir with 256 char should fail, but did not"
10508         touch $DIR/$tdir/$(str_repeat 'x' 255) ||
10509                 error "create with 255 char failed"
10510         touch $DIR/$tdir/$(str_repeat 'y' 256) &&
10511                 error "create with 256 char should fail, but did not"
10512
10513         ls -l $DIR/$tdir
10514         rm -rf $DIR/$tdir
10515 }
10516 run_test 110 "filename length checking"
10517
10518 #
10519 # Purpose: To verify dynamic thread (OSS) creation.
10520 #
10521 test_115() {
10522         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10523         remote_ost_nodsh && skip "remote OST with nodsh"
10524
10525         # Lustre does not stop service threads once they are started.
10526         # Reset number of running threads to default.
10527         stopall
10528         setupall
10529
10530         local OSTIO_pre
10531         local save_params="$TMP/sanity-$TESTNAME.parameters"
10532
10533         # Get ll_ost_io count before I/O
10534         OSTIO_pre=$(do_facet ost1 \
10535                 "$LCTL get_param ost.OSS.ost_io.threads_started | cut -d= -f2")
10536         # Exit if lustre is not running (ll_ost_io not running).
10537         [ -z "$OSTIO_pre" ] && error "no OSS threads"
10538
10539         echo "Starting with $OSTIO_pre threads"
10540         local thread_max=$((OSTIO_pre * 2))
10541         local rpc_in_flight=$((thread_max * 2))
10542         # Number of I/O Process proposed to be started.
10543         local nfiles
10544         local facets=$(get_facets OST)
10545
10546         save_lustre_params client "osc.*OST*.max_rpcs_in_flight" > $save_params
10547         save_lustre_params $facets "ost.OSS.ost_io.threads_max" >> $save_params
10548
10549         # Set in_flight to $rpc_in_flight
10550         $LCTL set_param osc.*OST*.max_rpcs_in_flight=$rpc_in_flight ||
10551                 error "Failed to set max_rpcs_in_flight to $rpc_in_flight"
10552         nfiles=${rpc_in_flight}
10553         # Set ost thread_max to $thread_max
10554         do_facet ost1 "$LCTL set_param ost.OSS.ost_io.threads_max=$thread_max"
10555
10556         # 5 Minutes should be sufficient for max number of OSS
10557         # threads(thread_max) to be created.
10558         local timeout=300
10559
10560         # Start I/O.
10561         local WTL=${WTL:-"$LUSTRE/tests/write_time_limit"}
10562         test_mkdir $DIR/$tdir
10563         for i in $(seq $nfiles); do
10564                 local file=$DIR/$tdir/${tfile}-$i
10565                 $LFS setstripe -c -1 -i 0 $file
10566                 ($WTL $file $timeout)&
10567         done
10568
10569         # I/O Started - Wait for thread_started to reach thread_max or report
10570         # error if thread_started is more than thread_max.
10571         echo "Waiting for thread_started to reach thread_max"
10572         local thread_started=0
10573         local end_time=$((SECONDS + timeout))
10574
10575         while [ $SECONDS -le $end_time ] ; do
10576                 echo -n "."
10577                 # Get ost i/o thread_started count.
10578                 thread_started=$(do_facet ost1 \
10579                         "$LCTL get_param \
10580                         ost.OSS.ost_io.threads_started | cut -d= -f2")
10581                 # Break out if thread_started is equal/greater than thread_max
10582                 if [[ $thread_started -ge $thread_max ]]; then
10583                         echo ll_ost_io thread_started $thread_started, \
10584                                 equal/greater than thread_max $thread_max
10585                         break
10586                 fi
10587                 sleep 1
10588         done
10589
10590         # Cleanup - We have the numbers, Kill i/o jobs if running.
10591         jobcount=($(jobs -p))
10592         for i in $(seq 0 $((${#jobcount[@]}-1)))
10593         do
10594                 kill -9 ${jobcount[$i]}
10595                 if [ $? -ne 0 ] ; then
10596                         echo Warning: \
10597                         Failed to Kill \'WTL\(I/O\)\' with pid ${jobcount[$i]}
10598                 fi
10599         done
10600
10601         # Cleanup files left by WTL binary.
10602         for i in $(seq $nfiles); do
10603                 local file=$DIR/$tdir/${tfile}-$i
10604                 rm -rf $file
10605                 if [ $? -ne 0 ] ; then
10606                         echo "Warning: Failed to delete file $file"
10607                 fi
10608         done
10609
10610         restore_lustre_params <$save_params
10611         rm -f $save_params || echo "Warning: delete file '$save_params' failed"
10612
10613         # Error out if no new thread has started or Thread started is greater
10614         # than thread max.
10615         if [[ $thread_started -le $OSTIO_pre ||
10616                         $thread_started -gt $thread_max ]]; then
10617                 error "ll_ost_io: thread_started $thread_started" \
10618                       "OSTIO_pre $OSTIO_pre, thread_max $thread_max." \
10619                       "No new thread started or thread started greater " \
10620                       "than thread_max."
10621         fi
10622 }
10623 run_test 115 "verify dynamic thread creation===================="
10624
10625 free_min_max () {
10626         wait_delete_completed
10627         AVAIL=($(lctl get_param -n osc.*[oO][sS][cC]-[^M]*.kbytesavail))
10628         echo "OST kbytes available: ${AVAIL[@]}"
10629         MAXV=${AVAIL[0]}
10630         MAXI=0
10631         MINV=${AVAIL[0]}
10632         MINI=0
10633         for ((i = 0; i < ${#AVAIL[@]}; i++)); do
10634                 #echo OST $i: ${AVAIL[i]}kb
10635                 if [[ ${AVAIL[i]} -gt $MAXV ]]; then
10636                         MAXV=${AVAIL[i]}
10637                         MAXI=$i
10638                 fi
10639                 if [[ ${AVAIL[i]} -lt $MINV ]]; then
10640                         MINV=${AVAIL[i]}
10641                         MINI=$i
10642                 fi
10643         done
10644         echo "Min free space: OST $MINI: $MINV"
10645         echo "Max free space: OST $MAXI: $MAXV"
10646 }
10647
10648 test_116a() { # was previously test_116()
10649         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10650         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
10651         remote_mds_nodsh && skip "remote MDS with nodsh"
10652
10653         echo -n "Free space priority "
10654         do_facet $SINGLEMDS lctl get_param -n lo[vd].*-mdtlov.qos_prio_free |
10655                 head -n1
10656         declare -a AVAIL
10657         free_min_max
10658
10659         [ $MINV -eq 0 ] && skip "no free space in OST$MINI, skip"
10660         [ $MINV -gt 10000000 ] && skip "too much free space in OST$MINI, skip"
10661         trap simple_cleanup_common EXIT
10662
10663         # Check if we need to generate uneven OSTs
10664         test_mkdir -p $DIR/$tdir/OST${MINI}
10665         local FILL=$((MINV / 4))
10666         local DIFF=$((MAXV - MINV))
10667         local DIFF2=$((DIFF * 100 / MINV))
10668
10669         local threshold=$(do_facet $SINGLEMDS \
10670                 lctl get_param -n *.*MDT0000-mdtlov.qos_threshold_rr | head -n1)
10671         threshold=${threshold%%%}
10672         echo -n "Check for uneven OSTs: "
10673         echo -n "diff=${DIFF}KB (${DIFF2}%) must be > ${threshold}% ..."
10674
10675         if [[ $DIFF2 -gt $threshold ]]; then
10676                 echo "ok"
10677                 echo "Don't need to fill OST$MINI"
10678         else
10679                 # generate uneven OSTs. Write 2% over the QOS threshold value
10680                 echo "no"
10681                 DIFF=$((threshold - DIFF2 + 2))
10682                 DIFF2=$((MINV * DIFF / 100))
10683                 echo "Fill $DIFF% remaining space in OST$MINI with ${DIFF2}KB"
10684                 $LFS setstripe -i $MINI -c 1 $DIR/$tdir/OST${MINI} ||
10685                         error "setstripe failed"
10686                 DIFF=$((DIFF2 / 2048))
10687                 i=0
10688                 while [ $i -lt $DIFF ]; do
10689                         i=$((i + 1))
10690                         dd if=/dev/zero of=$DIR/$tdir/OST${MINI}/$tfile-$i \
10691                                 bs=2M count=1 2>/dev/null
10692                         echo -n .
10693                 done
10694                 echo .
10695                 sync
10696                 sleep_maxage
10697                 free_min_max
10698         fi
10699
10700         DIFF=$((MAXV - MINV))
10701         DIFF2=$((DIFF * 100 / MINV))
10702         echo -n "diff=$DIFF=$DIFF2% must be > $threshold% for QOS mode..."
10703         if [ $DIFF2 -gt $threshold ]; then
10704                 echo "ok"
10705         else
10706                 echo "failed - QOS mode won't be used"
10707                 simple_cleanup_common
10708                 skip "QOS imbalance criteria not met"
10709         fi
10710
10711         MINI1=$MINI
10712         MINV1=$MINV
10713         MAXI1=$MAXI
10714         MAXV1=$MAXV
10715
10716         # now fill using QOS
10717         $LFS setstripe -c 1 $DIR/$tdir
10718         FILL=$((FILL / 200))
10719         if [ $FILL -gt 600 ]; then
10720                 FILL=600
10721         fi
10722         echo "writing $FILL files to QOS-assigned OSTs"
10723         i=0
10724         while [ $i -lt $FILL ]; do
10725                 i=$((i + 1))
10726                 dd if=/dev/zero of=$DIR/$tdir/$tfile-$i bs=200k \
10727                         count=1 2>/dev/null
10728                 echo -n .
10729         done
10730         echo "wrote $i 200k files"
10731         sync
10732         sleep_maxage
10733
10734         echo "Note: free space may not be updated, so measurements might be off"
10735         free_min_max
10736         DIFF2=$((MAXV - MINV))
10737         echo "free space delta: orig $DIFF final $DIFF2"
10738         [ $DIFF2 -gt $DIFF ] && echo "delta got worse!"
10739         DIFF=$((MINV1 - ${AVAIL[$MINI1]}))
10740         echo "Wrote ${DIFF}KB to smaller OST $MINI1"
10741         DIFF2=$((MAXV1 - ${AVAIL[$MAXI1]}))
10742         echo "Wrote ${DIFF2}KB to larger OST $MAXI1"
10743         if [[ $DIFF -gt 0 ]]; then
10744                 FILL=$((DIFF2 * 100 / DIFF - 100))
10745                 echo "Wrote ${FILL}% more data to larger OST $MAXI1"
10746         fi
10747
10748         # Figure out which files were written where
10749         UUID=$(lctl get_param -n lov.${FSNAME}-clilov-*.target_obd |
10750                awk '/'$MINI1': / {print $2; exit}')
10751         echo $UUID
10752         MINC=$($LFS getstripe --ost $UUID $DIR/$tdir | grep $DIR | wc -l)
10753         echo "$MINC files created on smaller OST $MINI1"
10754         UUID=$(lctl get_param -n lov.${FSNAME}-clilov-*.target_obd |
10755                awk '/'$MAXI1': / {print $2; exit}')
10756         echo $UUID
10757         MAXC=$($LFS getstripe --ost $UUID $DIR/$tdir | grep $DIR | wc -l)
10758         echo "$MAXC files created on larger OST $MAXI1"
10759         if [[ $MINC -gt 0 ]]; then
10760                 FILL=$((MAXC * 100 / MINC - 100))
10761                 echo "Wrote ${FILL}% more files to larger OST $MAXI1"
10762         fi
10763         [[ $MAXC -gt $MINC ]] ||
10764                 error_ignore LU-9 "stripe QOS didn't balance free space"
10765         simple_cleanup_common
10766 }
10767 run_test 116a "stripe QOS: free space balance ==================="
10768
10769 test_116b() { # LU-2093
10770         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10771         remote_mds_nodsh && skip "remote MDS with nodsh"
10772
10773 #define OBD_FAIL_MDS_OSC_CREATE_FAIL     0x147
10774         local old_rr=$(do_facet $SINGLEMDS lctl get_param -n \
10775                        lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr | head -1)
10776         [ -z "$old_rr" ] && skip "no QOS"
10777         do_facet $SINGLEMDS lctl set_param \
10778                 lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr=0
10779         mkdir -p $DIR/$tdir
10780         do_facet $SINGLEMDS lctl set_param fail_loc=0x147
10781         createmany -o $DIR/$tdir/f- 20 || error "can't create"
10782         do_facet $SINGLEMDS lctl set_param fail_loc=0
10783         rm -rf $DIR/$tdir
10784         do_facet $SINGLEMDS lctl set_param \
10785                 lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr=$old_rr
10786 }
10787 run_test 116b "QoS shouldn't LBUG if not enough OSTs found on the 2nd pass"
10788
10789 test_117() # bug 10891
10790 {
10791         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10792
10793         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
10794         #define OBD_FAIL_OST_SETATTR_CREDITS 0x21e
10795         lctl set_param fail_loc=0x21e
10796         > $DIR/$tfile || error "truncate failed"
10797         lctl set_param fail_loc=0
10798         echo "Truncate succeeded."
10799         rm -f $DIR/$tfile
10800 }
10801 run_test 117 "verify osd extend =========="
10802
10803 NO_SLOW_RESENDCOUNT=4
10804 export OLD_RESENDCOUNT=""
10805 set_resend_count () {
10806         local PROC_RESENDCOUNT="osc.${FSNAME}-OST*-osc-*.resend_count"
10807         OLD_RESENDCOUNT=$(lctl get_param -n $PROC_RESENDCOUNT | head -n1)
10808         lctl set_param -n $PROC_RESENDCOUNT $1
10809         echo resend_count is set to $(lctl get_param -n $PROC_RESENDCOUNT)
10810 }
10811
10812 # for reduce test_118* time (b=14842)
10813 [ "$SLOW" = "no" ] && set_resend_count $NO_SLOW_RESENDCOUNT
10814
10815 # Reset async IO behavior after error case
10816 reset_async() {
10817         FILE=$DIR/reset_async
10818
10819         # Ensure all OSCs are cleared
10820         $LFS setstripe -c -1 $FILE
10821         dd if=/dev/zero of=$FILE bs=64k count=$OSTCOUNT
10822         sync
10823         rm $FILE
10824 }
10825
10826 test_118a() #bug 11710
10827 {
10828         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10829
10830         reset_async
10831
10832         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
10833         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
10834         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
10835
10836         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
10837                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
10838                 return 1;
10839         fi
10840         rm -f $DIR/$tfile
10841 }
10842 run_test 118a "verify O_SYNC works =========="
10843
10844 test_118b()
10845 {
10846         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10847         remote_ost_nodsh && skip "remote OST with nodsh"
10848
10849         reset_async
10850
10851         #define OBD_FAIL_SRV_ENOENT 0x217
10852         set_nodes_failloc "$(osts_nodes)" 0x217
10853         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
10854         RC=$?
10855         set_nodes_failloc "$(osts_nodes)" 0
10856         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
10857         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
10858                     grep -c writeback)
10859
10860         if [[ $RC -eq 0 ]]; then
10861                 error "Must return error due to dropped pages, rc=$RC"
10862                 return 1;
10863         fi
10864
10865         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
10866                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
10867                 return 1;
10868         fi
10869
10870         echo "Dirty pages not leaked on ENOENT"
10871
10872         # Due to the above error the OSC will issue all RPCs syncronously
10873         # until a subsequent RPC completes successfully without error.
10874         $MULTIOP $DIR/$tfile Ow4096yc
10875         rm -f $DIR/$tfile
10876
10877         return 0
10878 }
10879 run_test 118b "Reclaim dirty pages on fatal error =========="
10880
10881 test_118c()
10882 {
10883         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10884
10885         # for 118c, restore the original resend count, LU-1940
10886         [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] &&
10887                                 set_resend_count $OLD_RESENDCOUNT
10888         remote_ost_nodsh && skip "remote OST with nodsh"
10889
10890         reset_async
10891
10892         #define OBD_FAIL_OST_EROFS               0x216
10893         set_nodes_failloc "$(osts_nodes)" 0x216
10894
10895         # multiop should block due to fsync until pages are written
10896         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
10897         MULTIPID=$!
10898         sleep 1
10899
10900         if [[ `ps h -o comm -p $MULTIPID` != "multiop" ]]; then
10901                 error "Multiop failed to block on fsync, pid=$MULTIPID"
10902         fi
10903
10904         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
10905                     grep -c writeback)
10906         if [[ $WRITEBACK -eq 0 ]]; then
10907                 error "No page in writeback, writeback=$WRITEBACK"
10908         fi
10909
10910         set_nodes_failloc "$(osts_nodes)" 0
10911         wait $MULTIPID
10912         RC=$?
10913         if [[ $RC -ne 0 ]]; then
10914                 error "Multiop fsync failed, rc=$RC"
10915         fi
10916
10917         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
10918         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
10919                     grep -c writeback)
10920         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
10921                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
10922         fi
10923
10924         rm -f $DIR/$tfile
10925         echo "Dirty pages flushed via fsync on EROFS"
10926         return 0
10927 }
10928 run_test 118c "Fsync blocks on EROFS until dirty pages are flushed =========="
10929
10930 # continue to use small resend count to reduce test_118* time (b=14842)
10931 [ "$SLOW" = "no" ] && set_resend_count $NO_SLOW_RESENDCOUNT
10932
10933 test_118d()
10934 {
10935         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10936         remote_ost_nodsh && skip "remote OST with nodsh"
10937
10938         reset_async
10939
10940         #define OBD_FAIL_OST_BRW_PAUSE_BULK
10941         set_nodes_failloc "$(osts_nodes)" 0x214
10942         # multiop should block due to fsync until pages are written
10943         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
10944         MULTIPID=$!
10945         sleep 1
10946
10947         if [[ `ps h -o comm -p $MULTIPID` != "multiop" ]]; then
10948                 error "Multiop failed to block on fsync, pid=$MULTIPID"
10949         fi
10950
10951         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
10952                     grep -c writeback)
10953         if [[ $WRITEBACK -eq 0 ]]; then
10954                 error "No page in writeback, writeback=$WRITEBACK"
10955         fi
10956
10957         wait $MULTIPID || error "Multiop fsync failed, rc=$?"
10958         set_nodes_failloc "$(osts_nodes)" 0
10959
10960         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
10961         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
10962                     grep -c writeback)
10963         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
10964                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
10965         fi
10966
10967         rm -f $DIR/$tfile
10968         echo "Dirty pages gaurenteed flushed via fsync"
10969         return 0
10970 }
10971 run_test 118d "Fsync validation inject a delay of the bulk =========="
10972
10973 test_118f() {
10974         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10975
10976         reset_async
10977
10978         #define OBD_FAIL_OSC_BRW_PREP_REQ2        0x40a
10979         lctl set_param fail_loc=0x8000040a
10980
10981         # Should simulate EINVAL error which is fatal
10982         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
10983         RC=$?
10984         if [[ $RC -eq 0 ]]; then
10985                 error "Must return error due to dropped pages, rc=$RC"
10986         fi
10987
10988         lctl set_param fail_loc=0x0
10989
10990         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
10991         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
10992         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
10993                     grep -c writeback)
10994         if [[ $LOCKED -ne 0 ]]; then
10995                 error "Locked pages remain in cache, locked=$LOCKED"
10996         fi
10997
10998         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
10999                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
11000         fi
11001
11002         rm -f $DIR/$tfile
11003         echo "No pages locked after fsync"
11004
11005         reset_async
11006         return 0
11007 }
11008 run_test 118f "Simulate unrecoverable OSC side error =========="
11009
11010 test_118g() {
11011         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11012
11013         reset_async
11014
11015         #define OBD_FAIL_OSC_BRW_PREP_REQ        0x406
11016         lctl set_param fail_loc=0x406
11017
11018         # simulate local -ENOMEM
11019         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
11020         RC=$?
11021
11022         lctl set_param fail_loc=0
11023         if [[ $RC -eq 0 ]]; then
11024                 error "Must return error due to dropped pages, rc=$RC"
11025         fi
11026
11027         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
11028         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
11029         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
11030                         grep -c writeback)
11031         if [[ $LOCKED -ne 0 ]]; then
11032                 error "Locked pages remain in cache, locked=$LOCKED"
11033         fi
11034
11035         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
11036                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
11037         fi
11038
11039         rm -f $DIR/$tfile
11040         echo "No pages locked after fsync"
11041
11042         reset_async
11043         return 0
11044 }
11045 run_test 118g "Don't stay in wait if we got local -ENOMEM  =========="
11046
11047 test_118h() {
11048         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11049         remote_ost_nodsh && skip "remote OST with nodsh"
11050
11051         reset_async
11052
11053         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
11054         set_nodes_failloc "$(osts_nodes)" 0x20e
11055         # Should simulate ENOMEM error which is recoverable and should be handled by timeout
11056         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
11057         RC=$?
11058
11059         set_nodes_failloc "$(osts_nodes)" 0
11060         if [[ $RC -eq 0 ]]; then
11061                 error "Must return error due to dropped pages, rc=$RC"
11062         fi
11063
11064         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
11065         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
11066         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
11067                     grep -c writeback)
11068         if [[ $LOCKED -ne 0 ]]; then
11069                 error "Locked pages remain in cache, locked=$LOCKED"
11070         fi
11071
11072         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
11073                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
11074         fi
11075
11076         rm -f $DIR/$tfile
11077         echo "No pages locked after fsync"
11078
11079         return 0
11080 }
11081 run_test 118h "Verify timeout in handling recoverables errors  =========="
11082
11083 [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] && set_resend_count $OLD_RESENDCOUNT
11084
11085 test_118i() {
11086         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11087         remote_ost_nodsh && skip "remote OST with nodsh"
11088
11089         reset_async
11090
11091         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
11092         set_nodes_failloc "$(osts_nodes)" 0x20e
11093
11094         # Should simulate ENOMEM error which is recoverable and should be handled by timeout
11095         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
11096         PID=$!
11097         sleep 5
11098         set_nodes_failloc "$(osts_nodes)" 0
11099
11100         wait $PID
11101         RC=$?
11102         if [[ $RC -ne 0 ]]; then
11103                 error "got error, but should be not, rc=$RC"
11104         fi
11105
11106         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
11107         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
11108         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
11109         if [[ $LOCKED -ne 0 ]]; then
11110                 error "Locked pages remain in cache, locked=$LOCKED"
11111         fi
11112
11113         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
11114                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
11115         fi
11116
11117         rm -f $DIR/$tfile
11118         echo "No pages locked after fsync"
11119
11120         return 0
11121 }
11122 run_test 118i "Fix error before timeout in recoverable error  =========="
11123
11124 [ "$SLOW" = "no" ] && set_resend_count 4
11125
11126 test_118j() {
11127         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11128         remote_ost_nodsh && skip "remote OST with nodsh"
11129
11130         reset_async
11131
11132         #define OBD_FAIL_OST_BRW_WRITE_BULK2     0x220
11133         set_nodes_failloc "$(osts_nodes)" 0x220
11134
11135         # return -EIO from OST
11136         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
11137         RC=$?
11138         set_nodes_failloc "$(osts_nodes)" 0x0
11139         if [[ $RC -eq 0 ]]; then
11140                 error "Must return error due to dropped pages, rc=$RC"
11141         fi
11142
11143         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
11144         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
11145         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
11146         if [[ $LOCKED -ne 0 ]]; then
11147                 error "Locked pages remain in cache, locked=$LOCKED"
11148         fi
11149
11150         # in recoverable error on OST we want resend and stay until it finished
11151         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
11152                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
11153         fi
11154
11155         rm -f $DIR/$tfile
11156         echo "No pages locked after fsync"
11157
11158         return 0
11159 }
11160 run_test 118j "Simulate unrecoverable OST side error =========="
11161
11162 test_118k()
11163 {
11164         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11165         remote_ost_nodsh && skip "remote OSTs with nodsh"
11166
11167         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
11168         set_nodes_failloc "$(osts_nodes)" 0x20e
11169         test_mkdir $DIR/$tdir
11170
11171         for ((i=0;i<10;i++)); do
11172                 (dd if=/dev/zero of=$DIR/$tdir/$tfile-$i bs=1M count=10 || \
11173                         error "dd to $DIR/$tdir/$tfile-$i failed" )&
11174                 SLEEPPID=$!
11175                 sleep 0.500s
11176                 kill $SLEEPPID
11177                 wait $SLEEPPID
11178         done
11179
11180         set_nodes_failloc "$(osts_nodes)" 0
11181         rm -rf $DIR/$tdir
11182 }
11183 run_test 118k "bio alloc -ENOMEM and IO TERM handling ========="
11184
11185 test_118l() # LU-646
11186 {
11187         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11188
11189         test_mkdir $DIR/$tdir
11190         $MULTIOP $DIR/$tdir Dy || error "fsync dir failed"
11191         rm -rf $DIR/$tdir
11192 }
11193 run_test 118l "fsync dir"
11194
11195 test_118m() # LU-3066
11196 {
11197         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11198
11199         test_mkdir $DIR/$tdir
11200         $MULTIOP $DIR/$tdir DY || error "fdatasync dir failed"
11201         rm -rf $DIR/$tdir
11202 }
11203 run_test 118m "fdatasync dir ========="
11204
11205 [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] && set_resend_count $OLD_RESENDCOUNT
11206
11207 test_118n()
11208 {
11209         local begin
11210         local end
11211
11212         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11213         remote_ost_nodsh && skip "remote OSTs with nodsh"
11214
11215         # Sleep to avoid a cached response.
11216         #define OBD_STATFS_CACHE_SECONDS 1
11217         sleep 2
11218
11219         # Inject a 10 second delay in the OST_STATFS handler.
11220         #define OBD_FAIL_OST_STATFS_DELAY 0x242
11221         set_nodes_failloc "$(osts_nodes)" 0x242
11222
11223         begin=$SECONDS
11224         stat --file-system $MOUNT > /dev/null
11225         end=$SECONDS
11226
11227         set_nodes_failloc "$(osts_nodes)" 0
11228
11229         if ((end - begin > 20)); then
11230             error "statfs took $((end - begin)) seconds, expected 10"
11231         fi
11232 }
11233 run_test 118n "statfs() sends OST_STATFS requests in parallel"
11234
11235 test_119a() # bug 11737
11236 {
11237         BSIZE=$((512 * 1024))
11238         directio write $DIR/$tfile 0 1 $BSIZE
11239         # We ask to read two blocks, which is more than a file size.
11240         # directio will indicate an error when requested and actual
11241         # sizes aren't equeal (a normal situation in this case) and
11242         # print actual read amount.
11243         NOB=`directio read $DIR/$tfile 0 2 $BSIZE | awk '/error/ {print $6}'`
11244         if [ "$NOB" != "$BSIZE" ]; then
11245                 error "read $NOB bytes instead of $BSIZE"
11246         fi
11247         rm -f $DIR/$tfile
11248 }
11249 run_test 119a "Short directIO read must return actual read amount"
11250
11251 test_119b() # bug 11737
11252 {
11253         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11254
11255         $LFS setstripe -c 2 $DIR/$tfile || error "setstripe failed"
11256         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=1 || error "dd failed"
11257         sync
11258         $MULTIOP $DIR/$tfile oO_RDONLY:O_DIRECT:r$((2048 * 1024)) ||
11259                 error "direct read failed"
11260         rm -f $DIR/$tfile
11261 }
11262 run_test 119b "Sparse directIO read must return actual read amount"
11263
11264 test_119c() # bug 13099
11265 {
11266         BSIZE=1048576
11267         directio write $DIR/$tfile 3 1 $BSIZE || error "direct write failed"
11268         directio readhole $DIR/$tfile 0 2 $BSIZE || error "reading hole failed"
11269         rm -f $DIR/$tfile
11270 }
11271 run_test 119c "Testing for direct read hitting hole"
11272
11273 test_119d() # bug 15950
11274 {
11275         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11276
11277         MAX_RPCS_IN_FLIGHT=`$LCTL get_param -n osc.*OST0000-osc-[^mM]*.max_rpcs_in_flight`
11278         $LCTL set_param -n osc.*OST0000-osc-[^mM]*.max_rpcs_in_flight 1
11279         BSIZE=1048576
11280         $LFS setstripe $DIR/$tfile -i 0 -c 1 || error "setstripe failed"
11281         $DIRECTIO write $DIR/$tfile 0 1 $BSIZE || error "first directio failed"
11282         #define OBD_FAIL_OSC_DIO_PAUSE           0x40d
11283         lctl set_param fail_loc=0x40d
11284         $DIRECTIO write $DIR/$tfile 1 4 $BSIZE &
11285         pid_dio=$!
11286         sleep 1
11287         cat $DIR/$tfile > /dev/null &
11288         lctl set_param fail_loc=0
11289         pid_reads=$!
11290         wait $pid_dio
11291         log "the DIO writes have completed, now wait for the reads (should not block very long)"
11292         sleep 2
11293         [ -n "`ps h -p $pid_reads -o comm`" ] && \
11294         error "the read rpcs have not completed in 2s"
11295         rm -f $DIR/$tfile
11296         $LCTL set_param -n osc.*OST0000-osc-[^mM]*.max_rpcs_in_flight $MAX_RPCS_IN_FLIGHT
11297 }
11298 run_test 119d "The DIO path should try to send a new rpc once one is completed"
11299
11300 test_120a() {
11301         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11302         remote_mds_nodsh && skip "remote MDS with nodsh"
11303         test_mkdir -i0 -c1 $DIR/$tdir
11304         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
11305                 skip_env "no early lock cancel on server"
11306
11307         lru_resize_disable mdc
11308         lru_resize_disable osc
11309         cancel_lru_locks mdc
11310         # asynchronous object destroy at MDT could cause bl ast to client
11311         cancel_lru_locks osc
11312
11313         stat $DIR/$tdir > /dev/null
11314         can1=$(do_facet mds1 \
11315                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11316                awk '/ldlm_cancel/ {print $2}')
11317         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11318                awk '/ldlm_bl_callback/ {print $2}')
11319         test_mkdir -i0 -c1 $DIR/$tdir/d1
11320         can2=$(do_facet mds1 \
11321                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11322                awk '/ldlm_cancel/ {print $2}')
11323         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11324                awk '/ldlm_bl_callback/ {print $2}')
11325         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
11326         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
11327         lru_resize_enable mdc
11328         lru_resize_enable osc
11329 }
11330 run_test 120a "Early Lock Cancel: mkdir test"
11331
11332 test_120b() {
11333         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11334         remote_mds_nodsh && skip "remote MDS with nodsh"
11335         test_mkdir $DIR/$tdir
11336         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
11337                 skip_env "no early lock cancel on server"
11338
11339         lru_resize_disable mdc
11340         lru_resize_disable osc
11341         cancel_lru_locks mdc
11342         stat $DIR/$tdir > /dev/null
11343         can1=$(do_facet $SINGLEMDS \
11344                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11345                awk '/ldlm_cancel/ {print $2}')
11346         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11347                awk '/ldlm_bl_callback/ {print $2}')
11348         touch $DIR/$tdir/f1
11349         can2=$(do_facet $SINGLEMDS \
11350                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11351                awk '/ldlm_cancel/ {print $2}')
11352         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11353                awk '/ldlm_bl_callback/ {print $2}')
11354         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
11355         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
11356         lru_resize_enable mdc
11357         lru_resize_enable osc
11358 }
11359 run_test 120b "Early Lock Cancel: create test"
11360
11361 test_120c() {
11362         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11363         remote_mds_nodsh && skip "remote MDS with nodsh"
11364         test_mkdir -i0 -c1 $DIR/$tdir
11365         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
11366                 skip "no early lock cancel on server"
11367
11368         lru_resize_disable mdc
11369         lru_resize_disable osc
11370         test_mkdir -i0 -c1 $DIR/$tdir/d1
11371         test_mkdir -i0 -c1 $DIR/$tdir/d2
11372         touch $DIR/$tdir/d1/f1
11373         cancel_lru_locks mdc
11374         stat $DIR/$tdir/d1 $DIR/$tdir/d2 $DIR/$tdir/d1/f1 > /dev/null
11375         can1=$(do_facet mds1 \
11376                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11377                awk '/ldlm_cancel/ {print $2}')
11378         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11379                awk '/ldlm_bl_callback/ {print $2}')
11380         ln $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2
11381         can2=$(do_facet mds1 \
11382                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11383                awk '/ldlm_cancel/ {print $2}')
11384         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11385                awk '/ldlm_bl_callback/ {print $2}')
11386         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
11387         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
11388         lru_resize_enable mdc
11389         lru_resize_enable osc
11390 }
11391 run_test 120c "Early Lock Cancel: link test"
11392
11393 test_120d() {
11394         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11395         remote_mds_nodsh && skip "remote MDS with nodsh"
11396         test_mkdir -i0 -c1 $DIR/$tdir
11397         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
11398                 skip_env "no early lock cancel on server"
11399
11400         lru_resize_disable mdc
11401         lru_resize_disable osc
11402         touch $DIR/$tdir
11403         cancel_lru_locks mdc
11404         stat $DIR/$tdir > /dev/null
11405         can1=$(do_facet mds1 \
11406                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11407                awk '/ldlm_cancel/ {print $2}')
11408         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11409                awk '/ldlm_bl_callback/ {print $2}')
11410         chmod a+x $DIR/$tdir
11411         can2=$(do_facet mds1 \
11412                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11413                awk '/ldlm_cancel/ {print $2}')
11414         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11415                awk '/ldlm_bl_callback/ {print $2}')
11416         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
11417         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
11418         lru_resize_enable mdc
11419         lru_resize_enable osc
11420 }
11421 run_test 120d "Early Lock Cancel: setattr test"
11422
11423 test_120e() {
11424         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11425         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
11426                 skip_env "no early lock cancel on server"
11427         remote_mds_nodsh && skip "remote MDS with nodsh"
11428
11429         local dlmtrace_set=false
11430
11431         test_mkdir -i0 -c1 $DIR/$tdir
11432         lru_resize_disable mdc
11433         lru_resize_disable osc
11434         ! $LCTL get_param debug | grep -q dlmtrace &&
11435                 $LCTL set_param debug=+dlmtrace && dlmtrace_set=true
11436         dd if=/dev/zero of=$DIR/$tdir/f1 count=1
11437         cancel_lru_locks mdc
11438         cancel_lru_locks osc
11439         dd if=$DIR/$tdir/f1 of=/dev/null
11440         stat $DIR/$tdir $DIR/$tdir/f1 > /dev/null
11441         # XXX client can not do early lock cancel of OST lock
11442         # during unlink (LU-4206), so cancel osc lock now.
11443         sleep 2
11444         cancel_lru_locks osc
11445         can1=$(do_facet mds1 \
11446                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11447                awk '/ldlm_cancel/ {print $2}')
11448         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11449                awk '/ldlm_bl_callback/ {print $2}')
11450         unlink $DIR/$tdir/f1
11451         sleep 5
11452         can2=$(do_facet mds1 \
11453                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11454                awk '/ldlm_cancel/ {print $2}')
11455         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11456                awk '/ldlm_bl_callback/ {print $2}')
11457         [ $can1 -ne $can2 ] && error "$((can2 - can1)) cancel RPC occured" &&
11458                 $LCTL dk $TMP/cancel.debug.txt
11459         [ $blk1 -ne $blk2 ] && error "$((blk2 - blk1)) blocking RPC occured" &&
11460                 $LCTL dk $TMP/blocking.debug.txt
11461         $dlmtrace_set && $LCTL set_param debug=-dlmtrace
11462         lru_resize_enable mdc
11463         lru_resize_enable osc
11464 }
11465 run_test 120e "Early Lock Cancel: unlink test"
11466
11467 test_120f() {
11468         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11469         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
11470                 skip_env "no early lock cancel on server"
11471         remote_mds_nodsh && skip "remote MDS with nodsh"
11472
11473         test_mkdir -i0 -c1 $DIR/$tdir
11474         lru_resize_disable mdc
11475         lru_resize_disable osc
11476         test_mkdir -i0 -c1 $DIR/$tdir/d1
11477         test_mkdir -i0 -c1 $DIR/$tdir/d2
11478         dd if=/dev/zero of=$DIR/$tdir/d1/f1 count=1
11479         dd if=/dev/zero of=$DIR/$tdir/d2/f2 count=1
11480         cancel_lru_locks mdc
11481         cancel_lru_locks osc
11482         dd if=$DIR/$tdir/d1/f1 of=/dev/null
11483         dd if=$DIR/$tdir/d2/f2 of=/dev/null
11484         stat $DIR/$tdir/d1 $DIR/$tdir/d2 $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2 > /dev/null
11485         # XXX client can not do early lock cancel of OST lock
11486         # during rename (LU-4206), so cancel osc lock now.
11487         sleep 2
11488         cancel_lru_locks osc
11489         can1=$(do_facet mds1 \
11490                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11491                awk '/ldlm_cancel/ {print $2}')
11492         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11493                awk '/ldlm_bl_callback/ {print $2}')
11494         mrename $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2
11495         sleep 5
11496         can2=$(do_facet mds1 \
11497                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11498                awk '/ldlm_cancel/ {print $2}')
11499         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11500                awk '/ldlm_bl_callback/ {print $2}')
11501         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
11502         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
11503         lru_resize_enable mdc
11504         lru_resize_enable osc
11505 }
11506 run_test 120f "Early Lock Cancel: rename test"
11507
11508 test_120g() {
11509         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11510         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
11511                 skip_env "no early lock cancel on server"
11512         remote_mds_nodsh && skip "remote MDS with nodsh"
11513
11514         lru_resize_disable mdc
11515         lru_resize_disable osc
11516         count=10000
11517         echo create $count files
11518         test_mkdir $DIR/$tdir
11519         cancel_lru_locks mdc
11520         cancel_lru_locks osc
11521         t0=$(date +%s)
11522
11523         can0=$(do_facet $SINGLEMDS \
11524                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11525                awk '/ldlm_cancel/ {print $2}')
11526         blk0=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11527                awk '/ldlm_bl_callback/ {print $2}')
11528         createmany -o $DIR/$tdir/f $count
11529         sync
11530         can1=$(do_facet $SINGLEMDS \
11531                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11532                awk '/ldlm_cancel/ {print $2}')
11533         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11534                awk '/ldlm_bl_callback/ {print $2}')
11535         t1=$(date +%s)
11536         echo total: $((can1-can0)) cancels, $((blk1-blk0)) blockings
11537         echo rm $count files
11538         rm -r $DIR/$tdir
11539         sync
11540         can2=$(do_facet $SINGLEMDS \
11541                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11542                awk '/ldlm_cancel/ {print $2}')
11543         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11544                awk '/ldlm_bl_callback/ {print $2}')
11545         t2=$(date +%s)
11546         echo total: $count removes in $((t2-t1))
11547         echo total: $((can2-can1)) cancels, $((blk2-blk1)) blockings
11548         sleep 2
11549         # wait for commitment of removal
11550         lru_resize_enable mdc
11551         lru_resize_enable osc
11552 }
11553 run_test 120g "Early Lock Cancel: performance test"
11554
11555 test_121() { #bug #10589
11556         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11557
11558         rm -rf $DIR/$tfile
11559         writes=$(LANG=C dd if=/dev/zero of=$DIR/$tfile count=1 2>&1 | awk -F '+' '/out$/ {print $1}')
11560 #define OBD_FAIL_LDLM_CANCEL_RACE        0x310
11561         lctl set_param fail_loc=0x310
11562         cancel_lru_locks osc > /dev/null
11563         reads=$(LANG=C dd if=$DIR/$tfile of=/dev/null 2>&1 | awk -F '+' '/in$/ {print $1}')
11564         lctl set_param fail_loc=0
11565         [[ $reads -eq $writes ]] ||
11566                 error "read $reads blocks, must be $writes blocks"
11567 }
11568 run_test 121 "read cancel race ========="
11569
11570 test_123a_base() { # was test 123, statahead(bug 11401)
11571         local lsx="$1"
11572
11573         SLOWOK=0
11574         if ! grep -q "processor.*: 1" /proc/cpuinfo; then
11575                 log "testing UP system. Performance may be lower than expected."
11576                 SLOWOK=1
11577         fi
11578
11579         rm -rf $DIR/$tdir
11580         test_mkdir $DIR/$tdir
11581         NUMFREE=$(df -i -P $DIR | tail -n 1 | awk '{ print $4 }')
11582         [[ $NUMFREE -gt 100000 ]] && NUMFREE=100000 || NUMFREE=$((NUMFREE-1000))
11583         MULT=10
11584         for ((i=100, j=0; i<=$NUMFREE; j=$i, i=$((i * MULT)) )); do
11585                 createmany -o $DIR/$tdir/$tfile $j $((i - j))
11586
11587                 max=$(lctl get_param -n llite.*.statahead_max | head -n 1)
11588                 lctl set_param -n llite.*.statahead_max 0
11589                 lctl get_param llite.*.statahead_max
11590                 cancel_lru_locks mdc
11591                 cancel_lru_locks osc
11592                 stime=$(date +%s)
11593                 time $lsx $DIR/$tdir | wc -l
11594                 etime=$(date +%s)
11595                 delta=$((etime - stime))
11596                 log "$lsx $i files without statahead: $delta sec"
11597                 lctl set_param llite.*.statahead_max=$max
11598
11599                 swrong=$(lctl get_param -n llite.*.statahead_stats |
11600                         grep "statahead wrong:" | awk '{print $3}')
11601                 lctl get_param -n llite.*.statahead_max | grep '[0-9]'
11602                 cancel_lru_locks mdc
11603                 cancel_lru_locks osc
11604                 stime=$(date +%s)
11605                 time $lsx $DIR/$tdir | wc -l
11606                 etime=$(date +%s)
11607                 delta_sa=$((etime - stime))
11608                 log "$lsx $i files with statahead: $delta_sa sec"
11609                 lctl get_param -n llite.*.statahead_stats
11610                 ewrong=$(lctl get_param -n llite.*.statahead_stats |
11611                         grep "statahead wrong:" | awk '{print $3}')
11612
11613                 [[ $swrong -lt $ewrong ]] &&
11614                         log "statahead was stopped, maybe too many locks held!"
11615                 [[ $delta -eq 0 || $delta_sa -eq 0 ]] && continue
11616
11617                 if [ $((delta_sa * 100)) -gt $((delta * 105)) -a $delta_sa -gt $((delta + 2)) ]; then
11618                         max=$(lctl get_param -n llite.*.statahead_max |
11619                                 head -n 1)
11620                         lctl set_param -n llite.*.statahead_max 0
11621                         lctl get_param llite.*.statahead_max
11622                         cancel_lru_locks mdc
11623                         cancel_lru_locks osc
11624                         stime=$(date +%s)
11625                         time $lsx $DIR/$tdir | wc -l
11626                         etime=$(date +%s)
11627                         delta=$((etime - stime))
11628                         log "$lsx $i files again without statahead: $delta sec"
11629                         lctl set_param llite.*.statahead_max=$max
11630                         if [ $((delta_sa * 100 > delta * 105 && delta_sa > delta + 2)) ]; then
11631                                 if [  $SLOWOK -eq 0 ]; then
11632                                         error "$lsx $i files is slower with statahead!"
11633                                 else
11634                                         log "$lsx $i files is slower with statahead!"
11635                                 fi
11636                                 break
11637                         fi
11638                 fi
11639
11640                 [ $delta -gt 20 ] && break
11641                 [ $delta -gt 8 ] && MULT=$((50 / delta))
11642                 [ "$SLOW" = "no" -a $delta -gt 5 ] && break
11643         done
11644         log "$lsx done"
11645
11646         stime=$(date +%s)
11647         rm -r $DIR/$tdir
11648         sync
11649         etime=$(date +%s)
11650         delta=$((etime - stime))
11651         log "rm -r $DIR/$tdir/: $delta seconds"
11652         log "rm done"
11653         lctl get_param -n llite.*.statahead_stats
11654 }
11655
11656 test_123aa() {
11657         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11658
11659         test_123a_base "ls -l"
11660 }
11661 run_test 123aa "verify statahead work"
11662
11663 test_123ab() {
11664         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11665
11666         statx_supported || skip_env "Test must be statx() syscall supported"
11667
11668         test_123a_base "$STATX -l"
11669 }
11670 run_test 123ab "verify statahead work by using statx"
11671
11672 test_123ac() {
11673         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11674
11675         statx_supported || skip_env "Test must be statx() syscall supported"
11676
11677         local rpcs_before
11678         local rpcs_after
11679         local agl_before
11680         local agl_after
11681
11682         cancel_lru_locks $OSC
11683         rpcs_before=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
11684         agl_before=$($LCTL get_param -n llite.*.statahead_stats |
11685                 awk '/agl.total:/ {print $3}')
11686         test_123a_base "$STATX -c \"%n %i %A %h %u %g %W %X %Z\" -D"
11687         test_123a_base "$STATX --cached=always -D"
11688         agl_after=$($LCTL get_param -n llite.*.statahead_stats |
11689                 awk '/agl.total:/ {print $3}')
11690         [ $agl_before -eq $agl_after ] ||
11691                 error "Should not trigger AGL thread - $agl_before:$agl_after"
11692         rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
11693         [ $rpcs_after -eq $rpcs_before ] ||
11694                 error "$STATX should not send glimpse RPCs to $OSC"
11695 }
11696 run_test 123ac "verify statahead work by using statx without glimpse RPCs"
11697
11698 test_123b () { # statahead(bug 15027)
11699         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11700
11701         test_mkdir $DIR/$tdir
11702         createmany -o $DIR/$tdir/$tfile-%d 1000
11703
11704         cancel_lru_locks mdc
11705         cancel_lru_locks osc
11706
11707 #define OBD_FAIL_MDC_GETATTR_ENQUEUE     0x803
11708         lctl set_param fail_loc=0x80000803
11709         ls -lR $DIR/$tdir > /dev/null
11710         log "ls done"
11711         lctl set_param fail_loc=0x0
11712         lctl get_param -n llite.*.statahead_stats
11713         rm -r $DIR/$tdir
11714         sync
11715
11716 }
11717 run_test 123b "not panic with network error in statahead enqueue (bug 15027)"
11718
11719 test_123c() {
11720         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
11721
11722         test_mkdir -i 0 -c 1 $DIR/$tdir.0
11723         test_mkdir -i 1 -c 1 $DIR/$tdir.1
11724         touch $DIR/$tdir.1/{1..3}
11725         mv $DIR/$tdir.1/{1..3} $DIR/$tdir.0
11726
11727         remount_client $MOUNT
11728
11729         $MULTIOP $DIR/$tdir.0 Q
11730
11731         # let statahead to complete
11732         ls -l $DIR/$tdir.0 > /dev/null
11733
11734         testid=$(echo $TESTNAME | tr '_' ' ')
11735         dmesg | tac | sed "/$testid/,$ d" | grep "Can not initialize inode" &&
11736                 error "statahead warning" || true
11737 }
11738 run_test 123c "Can not initialize inode warning on DNE statahead"
11739
11740 test_124a() {
11741         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11742         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
11743                 skip_env "no lru resize on server"
11744
11745         local NR=2000
11746
11747         test_mkdir $DIR/$tdir
11748
11749         log "create $NR files at $DIR/$tdir"
11750         createmany -o $DIR/$tdir/f $NR ||
11751                 error "failed to create $NR files in $DIR/$tdir"
11752
11753         cancel_lru_locks mdc
11754         ls -l $DIR/$tdir > /dev/null
11755
11756         local NSDIR=""
11757         local LRU_SIZE=0
11758         for VALUE in $($LCTL get_param ldlm.namespaces.*mdc-*.lru_size); do
11759                 local PARAM=$(echo ${VALUE[0]} | cut -d "=" -f1)
11760                 LRU_SIZE=$($LCTL get_param -n $PARAM)
11761                 if [[ $LRU_SIZE -gt $(default_lru_size) ]]; then
11762                         NSDIR=$(echo $PARAM | cut -d "." -f1-3)
11763                         log "NSDIR=$NSDIR"
11764                         log "NS=$(basename $NSDIR)"
11765                         break
11766                 fi
11767         done
11768
11769         if [[ -z "$NSDIR" || $LRU_SIZE -lt $(default_lru_size) ]]; then
11770                 skip "Not enough cached locks created!"
11771         fi
11772         log "LRU=$LRU_SIZE"
11773
11774         local SLEEP=30
11775
11776         # We know that lru resize allows one client to hold $LIMIT locks
11777         # for 10h. After that locks begin to be killed by client.
11778         local MAX_HRS=10
11779         local LIMIT=$($LCTL get_param -n $NSDIR.pool.limit)
11780         log "LIMIT=$LIMIT"
11781         if [ $LIMIT -lt $LRU_SIZE ]; then
11782                 skip "Limit is too small $LIMIT"
11783         fi
11784
11785         # Make LVF so higher that sleeping for $SLEEP is enough to _start_
11786         # killing locks. Some time was spent for creating locks. This means
11787         # that up to the moment of sleep finish we must have killed some of
11788         # them (10-100 locks). This depends on how fast ther were created.
11789         # Many of them were touched in almost the same moment and thus will
11790         # be killed in groups.
11791         local LVF=$(($MAX_HRS * 60 * 60 / $SLEEP * $LIMIT / $LRU_SIZE))
11792
11793         # Use $LRU_SIZE_B here to take into account real number of locks
11794         # created in the case of CMD, LRU_SIZE_B != $NR in most of cases
11795         local LRU_SIZE_B=$LRU_SIZE
11796         log "LVF=$LVF"
11797         local OLD_LVF=$($LCTL get_param -n $NSDIR.pool.lock_volume_factor)
11798         log "OLD_LVF=$OLD_LVF"
11799         $LCTL set_param -n $NSDIR.pool.lock_volume_factor $LVF
11800
11801         # Let's make sure that we really have some margin. Client checks
11802         # cached locks every 10 sec.
11803         SLEEP=$((SLEEP+20))
11804         log "Sleep ${SLEEP} sec"
11805         local SEC=0
11806         while ((SEC<$SLEEP)); do
11807                 echo -n "..."
11808                 sleep 5
11809                 SEC=$((SEC+5))
11810                 LRU_SIZE=$($LCTL get_param -n $NSDIR/lru_size)
11811                 echo -n "$LRU_SIZE"
11812         done
11813         echo ""
11814         $LCTL set_param -n $NSDIR.pool.lock_volume_factor $OLD_LVF
11815         local LRU_SIZE_A=$($LCTL get_param -n $NSDIR.lru_size)
11816
11817         [[ $LRU_SIZE_B -gt $LRU_SIZE_A ]] || {
11818                 error "No locks dropped in ${SLEEP}s. LRU size: $LRU_SIZE_A"
11819                 unlinkmany $DIR/$tdir/f $NR
11820                 return
11821         }
11822
11823         log "Dropped "$((LRU_SIZE_B-LRU_SIZE_A))" locks in ${SLEEP}s"
11824         log "unlink $NR files at $DIR/$tdir"
11825         unlinkmany $DIR/$tdir/f $NR
11826 }
11827 run_test 124a "lru resize ======================================="
11828
11829 get_max_pool_limit()
11830 {
11831         local limit=$($LCTL get_param \
11832                       -n ldlm.namespaces.*-MDT0000-mdc-*.pool.limit)
11833         local max=0
11834         for l in $limit; do
11835                 if [[ $l -gt $max ]]; then
11836                         max=$l
11837                 fi
11838         done
11839         echo $max
11840 }
11841
11842 test_124b() {
11843         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11844         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
11845                 skip_env "no lru resize on server"
11846
11847         LIMIT=$(get_max_pool_limit)
11848
11849         NR=$(($(default_lru_size)*20))
11850         if [[ $NR -gt $LIMIT ]]; then
11851                 log "Limit lock number by $LIMIT locks"
11852                 NR=$LIMIT
11853         fi
11854
11855         IFree=$(mdsrate_inodes_available)
11856         if [ $IFree -lt $NR ]; then
11857                 log "Limit lock number by $IFree inodes"
11858                 NR=$IFree
11859         fi
11860
11861         lru_resize_disable mdc
11862         test_mkdir -p $DIR/$tdir/disable_lru_resize
11863
11864         createmany -o $DIR/$tdir/disable_lru_resize/f $NR
11865         log "doing ls -la $DIR/$tdir/disable_lru_resize 3 times"
11866         cancel_lru_locks mdc
11867         stime=`date +%s`
11868         PID=""
11869         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
11870         PID="$PID $!"
11871         sleep 2
11872         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
11873         PID="$PID $!"
11874         sleep 2
11875         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
11876         PID="$PID $!"
11877         wait $PID
11878         etime=`date +%s`
11879         nolruresize_delta=$((etime-stime))
11880         log "ls -la time: $nolruresize_delta seconds"
11881         log "lru_size = $(lctl get_param -n ldlm.namespaces.*mdc*.lru_size)"
11882         unlinkmany $DIR/$tdir/disable_lru_resize/f $NR
11883
11884         lru_resize_enable mdc
11885         test_mkdir -p $DIR/$tdir/enable_lru_resize
11886
11887         createmany -o $DIR/$tdir/enable_lru_resize/f $NR
11888         log "doing ls -la $DIR/$tdir/enable_lru_resize 3 times"
11889         cancel_lru_locks mdc
11890         stime=`date +%s`
11891         PID=""
11892         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
11893         PID="$PID $!"
11894         sleep 2
11895         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
11896         PID="$PID $!"
11897         sleep 2
11898         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
11899         PID="$PID $!"
11900         wait $PID
11901         etime=`date +%s`
11902         lruresize_delta=$((etime-stime))
11903         log "ls -la time: $lruresize_delta seconds"
11904         log "lru_size = $(lctl get_param -n ldlm.namespaces.*mdc*.lru_size)"
11905
11906         if [ $lruresize_delta -gt $nolruresize_delta ]; then
11907                 log "ls -la is $(((lruresize_delta - $nolruresize_delta) * 100 / $nolruresize_delta))% slower with lru resize enabled"
11908         elif [ $nolruresize_delta -gt $lruresize_delta ]; then
11909                 log "ls -la is $(((nolruresize_delta - $lruresize_delta) * 100 / $nolruresize_delta))% faster with lru resize enabled"
11910         else
11911                 log "lru resize performs the same with no lru resize"
11912         fi
11913         unlinkmany $DIR/$tdir/enable_lru_resize/f $NR
11914 }
11915 run_test 124b "lru resize (performance test) ======================="
11916
11917 test_124c() {
11918         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11919         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
11920                 skip_env "no lru resize on server"
11921
11922         # cache ununsed locks on client
11923         local nr=100
11924         cancel_lru_locks mdc
11925         test_mkdir $DIR/$tdir
11926         createmany -o $DIR/$tdir/f $nr ||
11927                 error "failed to create $nr files in $DIR/$tdir"
11928         ls -l $DIR/$tdir > /dev/null
11929
11930         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
11931         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
11932         local max_age=$($LCTL get_param -n $nsdir.lru_max_age)
11933         local recalc_p=$($LCTL get_param -n $nsdir.pool.recalc_period)
11934         echo "unused=$unused, max_age=$max_age, recalc_p=$recalc_p"
11935
11936         # set lru_max_age to 1 sec
11937         $LCTL set_param $nsdir.lru_max_age=1000 # milliseconds
11938         echo "sleep $((recalc_p * 2)) seconds..."
11939         sleep $((recalc_p * 2))
11940
11941         local remaining=$($LCTL get_param -n $nsdir.lock_unused_count)
11942         # restore lru_max_age
11943         $LCTL set_param -n $nsdir.lru_max_age $max_age
11944         [ $remaining -eq 0 ] || error "$remaining locks are not canceled"
11945         unlinkmany $DIR/$tdir/f $nr
11946 }
11947 run_test 124c "LRUR cancel very aged locks"
11948
11949 test_124d() {
11950         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11951         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
11952                 skip_env "no lru resize on server"
11953
11954         # cache ununsed locks on client
11955         local nr=100
11956
11957         lru_resize_disable mdc
11958         stack_trap "lru_resize_enable mdc" EXIT
11959
11960         cancel_lru_locks mdc
11961
11962         # asynchronous object destroy at MDT could cause bl ast to client
11963         test_mkdir $DIR/$tdir
11964         createmany -o $DIR/$tdir/f $nr ||
11965                 error "failed to create $nr files in $DIR/$tdir"
11966         stack_trap "unlinkmany $DIR/$tdir/f $nr" EXIT
11967
11968         ls -l $DIR/$tdir > /dev/null
11969
11970         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
11971         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
11972         local max_age=$($LCTL get_param -n $nsdir.lru_max_age)
11973         local recalc_p=$($LCTL get_param -n $nsdir.pool.recalc_period)
11974
11975         echo "unused=$unused, max_age=$max_age, recalc_p=$recalc_p"
11976
11977         # set lru_max_age to 1 sec
11978         $LCTL set_param $nsdir.lru_max_age=1000 # milliseconds
11979         stack_trap "$LCTL set_param -n $nsdir.lru_max_age $max_age" EXIT
11980
11981         echo "sleep $((recalc_p * 2)) seconds..."
11982         sleep $((recalc_p * 2))
11983
11984         local remaining=$($LCTL get_param -n $nsdir.lock_unused_count)
11985
11986         [ $remaining -eq 0 ] || error "$remaining locks are not canceled"
11987 }
11988 run_test 124d "cancel very aged locks if lru-resize diasbaled"
11989
11990 test_125() { # 13358
11991         $LCTL get_param -n llite.*.client_type | grep -q local ||
11992                 skip "must run as local client"
11993         $LCTL get_param -n mdc.*-mdc-*.connect_flags | grep -q acl ||
11994                 skip_env "must have acl enabled"
11995         [ -z "$(which setfacl)" ] && skip_env "must have setfacl tool"
11996
11997         test_mkdir $DIR/$tdir
11998         $LFS setstripe -S 65536 -c -1 $DIR/$tdir || error "setstripe failed"
11999         setfacl -R -m u:bin:rwx $DIR/$tdir || error "setfacl $DIR/$tdir failed"
12000         ls -ld $DIR/$tdir || error "cannot access $DIR/$tdir"
12001 }
12002 run_test 125 "don't return EPROTO when a dir has a non-default striping and ACLs"
12003
12004 test_126() { # bug 12829/13455
12005         $GSS && skip_env "must run as gss disabled"
12006         $LCTL get_param -n llite.*.client_type | grep -q local ||
12007                 skip "must run as local client"
12008         [ "$UID" != 0 ] && skip "must run as root, not UID $UID"
12009
12010         $RUNAS -u 0 -g 1 touch $DIR/$tfile || error "touch failed"
12011         gid=`ls -n $DIR/$tfile | awk '{print $4}'`
12012         rm -f $DIR/$tfile
12013         [ $gid -eq "1" ] || error "gid is set to" $gid "instead of 1"
12014 }
12015 run_test 126 "check that the fsgid provided by the client is taken into account"
12016
12017 test_127a() { # bug 15521
12018         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12019         local name count samp unit min max sum sumsq
12020
12021         $LFS setstripe -i 0 -c 1 $DIR/$tfile || error "setstripe failed"
12022         echo "stats before reset"
12023         $LCTL get_param osc.*.stats
12024         $LCTL set_param osc.*.stats=0
12025         local fsize=$((2048 * 1024))
12026
12027         dd if=/dev/zero of=$DIR/$tfile bs=$fsize count=1
12028         cancel_lru_locks osc
12029         dd if=$DIR/$tfile of=/dev/null bs=$fsize
12030
12031         $LCTL get_param osc.*0000-osc-*.stats | grep samples > $DIR/$tfile.tmp
12032         stack_trap "rm -f $TMP/$tfile.tmp"
12033         while read name count samp unit min max sum sumsq; do
12034                 echo "got name=$name count=$count unit=$unit min=$min max=$max"
12035                 [ ! $min ] && error "Missing min value for $name proc entry"
12036                 eval $name=$count || error "Wrong proc format"
12037
12038                 case $name in
12039                 read_bytes|write_bytes)
12040                         [[ "$unit" =~ "bytes" ]] ||
12041                                 error "unit is not 'bytes': $unit"
12042                         (( $min >= 4096 )) || error "min is too small: $min"
12043                         (( $min <= $fsize )) || error "min is too big: $min"
12044                         (( $max >= 4096 )) || error "max is too small: $max"
12045                         (( $max <= $fsize )) || error "max is too big: $max"
12046                         (( $sum == $fsize )) || error "sum is wrong: $sum"
12047                         (( $sumsq >= ($fsize / 4096) * (4096 * 4096) )) ||
12048                                 error "sumsquare is too small: $sumsq"
12049                         (( $sumsq <= $fsize * $fsize )) ||
12050                                 error "sumsquare is too big: $sumsq"
12051                         ;;
12052                 ost_read|ost_write)
12053                         [[ "$unit" =~ "usec" ]] ||
12054                                 error "unit is not 'usec': $unit"
12055                         ;;
12056                 *)      ;;
12057                 esac
12058         done < $DIR/$tfile.tmp
12059
12060         #check that we actually got some stats
12061         [ "$read_bytes" ] || error "Missing read_bytes stats"
12062         [ "$write_bytes" ] || error "Missing write_bytes stats"
12063         [ "$read_bytes" != 0 ] || error "no read done"
12064         [ "$write_bytes" != 0 ] || error "no write done"
12065 }
12066 run_test 127a "verify the client stats are sane"
12067
12068 test_127b() { # bug LU-333
12069         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12070         local name count samp unit min max sum sumsq
12071
12072         echo "stats before reset"
12073         $LCTL get_param llite.*.stats
12074         $LCTL set_param llite.*.stats=0
12075
12076         # perform 2 reads and writes so MAX is different from SUM.
12077         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1
12078         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1
12079         cancel_lru_locks osc
12080         dd if=$DIR/$tfile of=/dev/null bs=$PAGE_SIZE count=1
12081         dd if=$DIR/$tfile of=/dev/null bs=$PAGE_SIZE count=1
12082
12083         $LCTL get_param llite.*.stats | grep samples > $TMP/$tfile.tmp
12084         stack_trap "rm -f $TMP/$tfile.tmp"
12085         while read name count samp unit min max sum sumsq; do
12086                 echo "got name=$name count=$count unit=$unit min=$min max=$max"
12087                 eval $name=$count || error "Wrong proc format"
12088
12089                 case $name in
12090                 read_bytes|write_bytes)
12091                         [[ "$unit" =~ "bytes" ]] ||
12092                                 error "unit is not 'bytes': $unit"
12093                         (( $count == 2 )) || error "count is not 2: $count"
12094                         (( $min == $PAGE_SIZE )) ||
12095                                 error "min is not $PAGE_SIZE: $min"
12096                         (( $max == $PAGE_SIZE )) ||
12097                                 error "max is not $PAGE_SIZE: $max"
12098                         (( $sum == $PAGE_SIZE * 2 )) ||
12099                                 error "sum is not $((PAGE_SIZE * 2)): $sum"
12100                         ;;
12101                 read|write)
12102                         [[ "$unit" =~ "usec" ]] ||
12103                                 error "unit is not 'usec': $unit"
12104                         ;;
12105                 *)      ;;
12106                 esac
12107         done < $TMP/$tfile.tmp
12108
12109         #check that we actually got some stats
12110         [ "$read_bytes" ] || error "Missing read_bytes stats"
12111         [ "$write_bytes" ] || error "Missing write_bytes stats"
12112         [ "$read_bytes" != 0 ] || error "no read done"
12113         [ "$write_bytes" != 0 ] || error "no write done"
12114 }
12115 run_test 127b "verify the llite client stats are sane"
12116
12117 test_127c() { # LU-12394
12118         [ "$OSTCOUNT" -lt "2" ] && skip_env "needs >= 2 OSTs"
12119         local size
12120         local bsize
12121         local reads
12122         local writes
12123         local count
12124
12125         $LCTL set_param llite.*.extents_stats=1
12126         stack_trap "$LCTL set_param llite.*.extents_stats=0" EXIT
12127
12128         # Use two stripes so there is enough space in default config
12129         $LFS setstripe -c 2 $DIR/$tfile
12130
12131         # Extent stats start at 0-4K and go in power of two buckets
12132         # LL_HIST_START = 12 --> 2^12 = 4K
12133         # We do 3K*2^i, so 3K, 6K, 12K, 24K... hitting each bucket.
12134         # We do not do buckets larger than 64 MiB to avoid ENOSPC issues on
12135         # small configs
12136         for size in 3K 6K 12K 24K 48K 96K 192K 384K 768K 1536K 3M 6M 12M 24M 48M;
12137                 do
12138                 # Write and read, 2x each, second time at a non-zero offset
12139                 dd if=/dev/zero of=$DIR/$tfile bs=$size count=1
12140                 dd if=/dev/zero of=$DIR/$tfile bs=$size count=1 seek=10
12141                 dd if=$DIR/$tfile of=/dev/null bs=$size count=1
12142                 dd if=$DIR/$tfile of=/dev/null bs=$size count=1 seek=10
12143                 rm -f $DIR/$tfile
12144         done
12145
12146         $LCTL get_param llite.*.extents_stats
12147
12148         count=2
12149         for bsize in 4K 8K 16K 32K 64K 128K 256K 512K 1M 2M 4M 8M 16M 32M 64M;
12150                 do
12151                 local bucket=$($LCTL get_param -n llite.*.extents_stats |
12152                                 grep -m 1 $bsize)
12153                 reads=$(echo $bucket | awk '{print $5}')
12154                 writes=$(echo $bucket | awk '{print $9}')
12155                 [ "$reads" -eq $count ] ||
12156                         error "$reads reads in < $bsize bucket, expect $count"
12157                 [ "$writes" -eq $count ] ||
12158                         error "$writes writes in < $bsize bucket, expect $count"
12159         done
12160
12161         # Test mmap write and read
12162         $LCTL set_param llite.*.extents_stats=c
12163         size=512
12164         dd if=/dev/zero of=$DIR/$tfile bs=${size}K count=1
12165         $MULTIOP $DIR/$tfile OSMRUc || error "$MULTIOP $DIR/$tfile failed"
12166         $MULTIOP $DIR/$tfile OSMWUc || error "$MULTIOP $DIR/$tfile failed"
12167
12168         $LCTL get_param llite.*.extents_stats
12169
12170         count=$(((size*1024) / PAGE_SIZE))
12171
12172         bsize=$((2 * PAGE_SIZE / 1024))K
12173
12174         bucket=$($LCTL get_param -n llite.*.extents_stats |
12175                         grep -m 1 $bsize)
12176         reads=$(echo $bucket | awk '{print $5}')
12177         writes=$(echo $bucket | awk '{print $9}')
12178         # mmap writes fault in the page first, creating an additonal read
12179         [ "$reads" -eq $((2 * count)) ] ||
12180                 error "$reads reads in < $bsize bucket, expect $count"
12181         [ "$writes" -eq $count ] ||
12182                 error "$writes writes in < $bsize bucket, expect $count"
12183 }
12184 run_test 127c "test llite extent stats with regular & mmap i/o"
12185
12186 test_128() { # bug 15212
12187         touch $DIR/$tfile
12188         $LFS 2>&1 <<-EOF | tee $TMP/$tfile.log
12189                 find $DIR/$tfile
12190                 find $DIR/$tfile
12191         EOF
12192
12193         result=$(grep error $TMP/$tfile.log)
12194         rm -f $DIR/$tfile $TMP/$tfile.log
12195         [ -z "$result" ] ||
12196                 error "consecutive find's under interactive lfs failed"
12197 }
12198 run_test 128 "interactive lfs for 2 consecutive find's"
12199
12200 set_dir_limits () {
12201         local mntdev
12202         local canondev
12203         local node
12204
12205         local ldproc=/proc/fs/ldiskfs
12206         local facets=$(get_facets MDS)
12207
12208         for facet in ${facets//,/ }; do
12209                 canondev=$(ldiskfs_canon \
12210                            *.$(convert_facet2label $facet).mntdev $facet)
12211                 do_facet $facet "test -e $ldproc/$canondev/max_dir_size" ||
12212                         ldproc=/sys/fs/ldiskfs
12213                 do_facet $facet "echo $1 >$ldproc/$canondev/max_dir_size"
12214                 do_facet $facet "echo $2 >$ldproc/$canondev/warning_dir_size"
12215         done
12216 }
12217
12218 check_mds_dmesg() {
12219         local facets=$(get_facets MDS)
12220         for facet in ${facets//,/ }; do
12221                 do_facet $facet "dmesg | tail -3 | grep $1" && return 0
12222         done
12223         return 1
12224 }
12225
12226 test_129() {
12227         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12228         [[ $MDS1_VERSION -ge $(version_code 2.5.56) ]] ||
12229                 skip "Need MDS version with at least 2.5.56"
12230         if [ "$mds1_FSTYPE" != ldiskfs ]; then
12231                 skip_env "ldiskfs only test"
12232         fi
12233         remote_mds_nodsh && skip "remote MDS with nodsh"
12234
12235         local ENOSPC=28
12236         local has_warning=false
12237
12238         rm -rf $DIR/$tdir
12239         mkdir -p $DIR/$tdir
12240
12241         # block size of mds1
12242         local maxsize=$(($($LCTL get_param -n mdc.*MDT0000*.blocksize) * 8))
12243         set_dir_limits $maxsize $((maxsize * 6 / 8))
12244         stack_trap "set_dir_limits 0 0"
12245         stack_trap "unlinkmany $DIR/$tdir/file_base_ 2000 || true"
12246         local dirsize=$(stat -c%s "$DIR/$tdir")
12247         local nfiles=0
12248         while (( $dirsize <= $maxsize )); do
12249                 $MCREATE $DIR/$tdir/file_base_$nfiles
12250                 rc=$?
12251                 # check two errors:
12252                 # ENOSPC for ext4 max_dir_size, which has been used since
12253                 # kernel v3.6-rc1-8-gdf981d03ee, lustre v2_4_50_0-79-gaed82035c0
12254                 if (( rc == ENOSPC )); then
12255                         set_dir_limits 0 0
12256                         echo "rc=$rc returned as expected after $nfiles files"
12257
12258                         createmany -o $DIR/$tdir/file_extra_$nfiles. 5 ||
12259                                 error "create failed w/o dir size limit"
12260
12261                         # messages may be rate limited if test is run repeatedly
12262                         check_mds_dmesg '"is approaching max"' ||
12263                                 echo "warning message should be output"
12264                         check_mds_dmesg '"has reached max"' ||
12265                                 echo "reached message should be output"
12266
12267                         dirsize=$(stat -c%s "$DIR/$tdir")
12268
12269                         [[ $dirsize -ge $maxsize ]] && return 0
12270                         error "dirsize $dirsize < $maxsize after $nfiles files"
12271                 elif (( rc != 0 )); then
12272                         break
12273                 fi
12274                 nfiles=$((nfiles + 1))
12275                 dirsize=$(stat -c%s "$DIR/$tdir")
12276         done
12277
12278         error "rc=$rc, size=$dirsize/$maxsize, mdt=$MDSCOUNT, nfiles=$nfiles"
12279 }
12280 run_test 129 "test directory size limit ========================"
12281
12282 OLDIFS="$IFS"
12283 cleanup_130() {
12284         trap 0
12285         IFS="$OLDIFS"
12286 }
12287
12288 test_130a() {
12289         local filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
12290         [ -n "$filefrag_op" ] && skip_env "filefrag does not support FIEMAP"
12291
12292         trap cleanup_130 EXIT RETURN
12293
12294         local fm_file=$DIR/$tfile
12295         $LFS setstripe -S 65536 -c 1 $fm_file || error "setstripe on $fm_file"
12296         dd if=/dev/zero of=$fm_file bs=65536 count=1 ||
12297                 error "dd failed for $fm_file"
12298
12299         # LU-1795: test filefrag/FIEMAP once, even if unsupported
12300         filefrag -ves $fm_file
12301         RC=$?
12302         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
12303                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
12304         [ $RC != 0 ] && error "filefrag $fm_file failed"
12305
12306         filefrag_op=$(filefrag -ve -k $fm_file |
12307                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
12308         lun=$($LFS getstripe -i $fm_file)
12309
12310         start_blk=`echo $filefrag_op | cut -d: -f2 | cut -d. -f1`
12311         IFS=$'\n'
12312         tot_len=0
12313         for line in $filefrag_op
12314         do
12315                 frag_lun=`echo $line | cut -d: -f5`
12316                 ext_len=`echo $line | cut -d: -f4`
12317                 if (( $frag_lun != $lun )); then
12318                         cleanup_130
12319                         error "FIEMAP on 1-stripe file($fm_file) failed"
12320                         return
12321                 fi
12322                 (( tot_len += ext_len ))
12323         done
12324
12325         if (( lun != frag_lun || start_blk != 0 || tot_len != 64 )); then
12326                 cleanup_130
12327                 error "FIEMAP on 1-stripe file($fm_file) failed;"
12328                 return
12329         fi
12330
12331         cleanup_130
12332
12333         echo "FIEMAP on single striped file succeeded"
12334 }
12335 run_test 130a "FIEMAP (1-stripe file)"
12336
12337 test_130b() {
12338         [ "$OSTCOUNT" -lt "2" ] && skip_env "needs >= 2 OSTs"
12339
12340         local filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
12341         [ -n "$filefrag_op" ] && skip_env "filefrag does not support FIEMAP"
12342
12343         trap cleanup_130 EXIT RETURN
12344
12345         local fm_file=$DIR/$tfile
12346         $LFS setstripe -S 65536 -c $OSTCOUNT $fm_file ||
12347                         error "setstripe on $fm_file"
12348         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
12349                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
12350
12351         dd if=/dev/zero of=$fm_file bs=1M count=$OSTCOUNT ||
12352                 error "dd failed on $fm_file"
12353
12354         filefrag -ves $fm_file || error "filefrag $fm_file failed"
12355         filefrag_op=$(filefrag -ve -k $fm_file |
12356                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
12357
12358         last_lun=$(echo $filefrag_op | cut -d: -f5 |
12359                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
12360
12361         IFS=$'\n'
12362         tot_len=0
12363         num_luns=1
12364         for line in $filefrag_op
12365         do
12366                 frag_lun=$(echo $line | cut -d: -f5 |
12367                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
12368                 ext_len=$(echo $line | cut -d: -f4)
12369                 if (( $frag_lun != $last_lun )); then
12370                         if (( tot_len != 1024 )); then
12371                                 cleanup_130
12372                                 error "FIEMAP on $fm_file failed; returned " \
12373                                 "len $tot_len for OST $last_lun instead of 1024"
12374                                 return
12375                         else
12376                                 (( num_luns += 1 ))
12377                                 tot_len=0
12378                         fi
12379                 fi
12380                 (( tot_len += ext_len ))
12381                 last_lun=$frag_lun
12382         done
12383         if (( num_luns != $OSTCOUNT || tot_len != 1024 )); then
12384                 cleanup_130
12385                 error "FIEMAP on $fm_file failed; returned wrong number of " \
12386                         "luns or wrong len for OST $last_lun"
12387                 return
12388         fi
12389
12390         cleanup_130
12391
12392         echo "FIEMAP on $OSTCOUNT-stripe file succeeded"
12393 }
12394 run_test 130b "FIEMAP ($OSTCOUNT-stripe file)"
12395
12396 test_130c() {
12397         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
12398
12399         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
12400         [ -n "$filefrag_op" ] && skip "filefrag does not support FIEMAP"
12401
12402         trap cleanup_130 EXIT RETURN
12403
12404         local fm_file=$DIR/$tfile
12405         $LFS setstripe -S 65536 -c 2 $fm_file || error "setstripe on $fm_file"
12406         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
12407                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
12408
12409         dd if=/dev/zero of=$fm_file seek=1 bs=1M count=1 ||
12410                         error "dd failed on $fm_file"
12411
12412         filefrag -ves $fm_file || error "filefrag $fm_file failed"
12413         filefrag_op=$(filefrag -ve -k $fm_file |
12414                 sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
12415
12416         last_lun=$(echo $filefrag_op | cut -d: -f5 |
12417                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
12418
12419         IFS=$'\n'
12420         tot_len=0
12421         num_luns=1
12422         for line in $filefrag_op
12423         do
12424                 frag_lun=$(echo $line | cut -d: -f5 |
12425                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
12426                 ext_len=$(echo $line | cut -d: -f4)
12427                 if (( $frag_lun != $last_lun )); then
12428                         logical=`echo $line | cut -d: -f2 | cut -d. -f1`
12429                         if (( logical != 512 )); then
12430                                 cleanup_130
12431                                 error "FIEMAP on $fm_file failed; returned " \
12432                                 "logical start for lun $logical instead of 512"
12433                                 return
12434                         fi
12435                         if (( tot_len != 512 )); then
12436                                 cleanup_130
12437                                 error "FIEMAP on $fm_file failed; returned " \
12438                                 "len $tot_len for OST $last_lun instead of 1024"
12439                                 return
12440                         else
12441                                 (( num_luns += 1 ))
12442                                 tot_len=0
12443                         fi
12444                 fi
12445                 (( tot_len += ext_len ))
12446                 last_lun=$frag_lun
12447         done
12448         if (( num_luns != 2 || tot_len != 512 )); then
12449                 cleanup_130
12450                 error "FIEMAP on $fm_file failed; returned wrong number of " \
12451                         "luns or wrong len for OST $last_lun"
12452                 return
12453         fi
12454
12455         cleanup_130
12456
12457         echo "FIEMAP on 2-stripe file with hole succeeded"
12458 }
12459 run_test 130c "FIEMAP (2-stripe file with hole)"
12460
12461 test_130d() {
12462         [[ $OSTCOUNT -lt 3 ]] && skip_env "needs >= 3 OSTs"
12463
12464         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
12465         [ -n "$filefrag_op" ] && skip "filefrag does not support FIEMAP"
12466
12467         trap cleanup_130 EXIT RETURN
12468
12469         local fm_file=$DIR/$tfile
12470         $LFS setstripe -S 65536 -c $OSTCOUNT $fm_file ||
12471                         error "setstripe on $fm_file"
12472         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
12473                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
12474
12475         local actual_stripe_count=$($LFS getstripe -c $fm_file)
12476         dd if=/dev/zero of=$fm_file bs=1M count=$actual_stripe_count ||
12477                 error "dd failed on $fm_file"
12478
12479         filefrag -ves $fm_file || error "filefrag $fm_file failed"
12480         filefrag_op=$(filefrag -ve -k $fm_file |
12481                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
12482
12483         last_lun=$(echo $filefrag_op | cut -d: -f5 |
12484                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
12485
12486         IFS=$'\n'
12487         tot_len=0
12488         num_luns=1
12489         for line in $filefrag_op
12490         do
12491                 frag_lun=$(echo $line | cut -d: -f5 |
12492                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
12493                 ext_len=$(echo $line | cut -d: -f4)
12494                 if (( $frag_lun != $last_lun )); then
12495                         if (( tot_len != 1024 )); then
12496                                 cleanup_130
12497                                 error "FIEMAP on $fm_file failed; returned " \
12498                                 "len $tot_len for OST $last_lun instead of 1024"
12499                                 return
12500                         else
12501                                 (( num_luns += 1 ))
12502                                 tot_len=0
12503                         fi
12504                 fi
12505                 (( tot_len += ext_len ))
12506                 last_lun=$frag_lun
12507         done
12508         if (( num_luns != actual_stripe_count || tot_len != 1024 )); then
12509                 cleanup_130
12510                 error "FIEMAP on $fm_file failed; returned wrong number of " \
12511                         "luns or wrong len for OST $last_lun"
12512                 return
12513         fi
12514
12515         cleanup_130
12516
12517         echo "FIEMAP on N-stripe file succeeded"
12518 }
12519 run_test 130d "FIEMAP (N-stripe file)"
12520
12521 test_130e() {
12522         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
12523
12524         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
12525         [ -n "$filefrag_op" ] && skip_env "filefrag does not support FIEMAP"
12526
12527         trap cleanup_130 EXIT RETURN
12528
12529         local fm_file=$DIR/$tfile
12530         $LFS setstripe -S 131072 -c 2 $fm_file || error "setstripe on $fm_file"
12531         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
12532                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
12533
12534         NUM_BLKS=512
12535         EXPECTED_LEN=$(( (NUM_BLKS / 2) * 64 ))
12536         for ((i = 0; i < $NUM_BLKS; i++))
12537         do
12538                 dd if=/dev/zero of=$fm_file count=1 bs=64k seek=$((2*$i)) conv=notrunc > /dev/null 2>&1
12539         done
12540
12541         filefrag -ves $fm_file || error "filefrag $fm_file failed"
12542         filefrag_op=$(filefrag -ve -k $fm_file |
12543                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
12544
12545         last_lun=$(echo $filefrag_op | cut -d: -f5 |
12546                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
12547
12548         IFS=$'\n'
12549         tot_len=0
12550         num_luns=1
12551         for line in $filefrag_op
12552         do
12553                 frag_lun=$(echo $line | cut -d: -f5 |
12554                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
12555                 ext_len=$(echo $line | cut -d: -f4)
12556                 if (( $frag_lun != $last_lun )); then
12557                         if (( tot_len != $EXPECTED_LEN )); then
12558                                 cleanup_130
12559                                 error "FIEMAP on $fm_file failed; returned " \
12560                                 "len $tot_len for OST $last_lun instead " \
12561                                 "of $EXPECTED_LEN"
12562                                 return
12563                         else
12564                                 (( num_luns += 1 ))
12565                                 tot_len=0
12566                         fi
12567                 fi
12568                 (( tot_len += ext_len ))
12569                 last_lun=$frag_lun
12570         done
12571         if (( num_luns != 2 || tot_len != $EXPECTED_LEN )); then
12572                 cleanup_130
12573                 error "FIEMAP on $fm_file failed; returned wrong number " \
12574                         "of luns or wrong len for OST $last_lun"
12575                 return
12576         fi
12577
12578         cleanup_130
12579
12580         echo "FIEMAP with continuation calls succeeded"
12581 }
12582 run_test 130e "FIEMAP (test continuation FIEMAP calls)"
12583
12584 test_130f() {
12585         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
12586         [ -n "$filefrag_op" ] && skip "filefrag does not support FIEMAP"
12587
12588         local fm_file=$DIR/$tfile
12589         $MULTIOP $fm_file oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:T33554432c ||
12590                 error "multiop create with lov_delay_create on $fm_file"
12591
12592         filefrag -ves $fm_file || error "filefrag $fm_file failed"
12593         filefrag_extents=$(filefrag -vek $fm_file |
12594                            awk '/extents? found/ { print $2 }')
12595         if [[ "$filefrag_extents" != "0" ]]; then
12596                 error "FIEMAP on $fm_file failed; " \
12597                       "returned $filefrag_extents expected 0"
12598         fi
12599
12600         rm -f $fm_file
12601 }
12602 run_test 130f "FIEMAP (unstriped file)"
12603
12604 # Test for writev/readv
12605 test_131a() {
12606         rwv -f $DIR/$tfile -w -n 3 524288 1048576 1572864 ||
12607                 error "writev test failed"
12608         rwv -f $DIR/$tfile -r -v -n 2 1572864 1048576 ||
12609                 error "readv failed"
12610         rm -f $DIR/$tfile
12611 }
12612 run_test 131a "test iov's crossing stripe boundary for writev/readv"
12613
12614 test_131b() {
12615         local fsize=$((524288 + 1048576 + 1572864))
12616         rwv -f $DIR/$tfile -w -a -n 3 524288 1048576 1572864 &&
12617                 $CHECKSTAT -t file $DIR/$tfile -s $fsize ||
12618                         error "append writev test failed"
12619
12620         ((fsize += 1572864 + 1048576))
12621         rwv -f $DIR/$tfile -w -a -n 2 1572864 1048576 &&
12622                 $CHECKSTAT -t file $DIR/$tfile -s $fsize ||
12623                         error "append writev test failed"
12624         rm -f $DIR/$tfile
12625 }
12626 run_test 131b "test append writev"
12627
12628 test_131c() {
12629         rwv -f $DIR/$tfile -w -d -n 1 1048576 || return 0
12630         error "NOT PASS"
12631 }
12632 run_test 131c "test read/write on file w/o objects"
12633
12634 test_131d() {
12635         rwv -f $DIR/$tfile -w -n 1 1572864
12636         NOB=`rwv -f $DIR/$tfile -r -n 3 524288 524288 1048576 | awk '/error/ {print $6}'`
12637         if [ "$NOB" != 1572864 ]; then
12638                 error "Short read filed: read $NOB bytes instead of 1572864"
12639         fi
12640         rm -f $DIR/$tfile
12641 }
12642 run_test 131d "test short read"
12643
12644 test_131e() {
12645         rwv -f $DIR/$tfile -w -s 1048576 -n 1 1048576
12646         rwv -f $DIR/$tfile -r -z -s 0 -n 1 524288 || \
12647         error "read hitting hole failed"
12648         rm -f $DIR/$tfile
12649 }
12650 run_test 131e "test read hitting hole"
12651
12652 check_stats() {
12653         local facet=$1
12654         local op=$2
12655         local want=${3:-0}
12656         local res
12657
12658         case $facet in
12659         mds*) res=$(do_facet $facet \
12660                    $LCTL get_param mdt.$FSNAME-MDT0000.md_stats | grep "$op")
12661                  ;;
12662         ost*) res=$(do_facet $facet \
12663                    $LCTL get_param obdfilter.$FSNAME-OST0000.stats | grep "$op")
12664                  ;;
12665         *) error "Wrong facet '$facet'" ;;
12666         esac
12667         [ "$res" ] || error "The counter for $op on $facet was not incremented"
12668         # if the argument $3 is zero, it means any stat increment is ok.
12669         if [[ $want -gt 0 ]]; then
12670                 local count=$(echo $res | awk '{ print $2 }')
12671                 [[ $count -ne $want ]] &&
12672                         error "The $op counter on $facet is $count, not $want"
12673         fi
12674 }
12675
12676 test_133a() {
12677         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12678         remote_ost_nodsh && skip "remote OST with nodsh"
12679         remote_mds_nodsh && skip "remote MDS with nodsh"
12680         do_facet $SINGLEMDS $LCTL list_param mdt.*.rename_stats ||
12681                 skip_env "MDS doesn't support rename stats"
12682
12683         local testdir=$DIR/${tdir}/stats_testdir
12684
12685         mkdir -p $DIR/${tdir}
12686
12687         # clear stats.
12688         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
12689         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
12690
12691         # verify mdt stats first.
12692         mkdir ${testdir} || error "mkdir failed"
12693         check_stats $SINGLEMDS "mkdir" 1
12694         touch ${testdir}/${tfile} || error "touch failed"
12695         check_stats $SINGLEMDS "open" 1
12696         check_stats $SINGLEMDS "close" 1
12697         [ $MDS1_VERSION -ge $(version_code 2.8.54) ] && {
12698                 mknod ${testdir}/${tfile}-pipe p || error "mknod failed"
12699                 check_stats $SINGLEMDS "mknod" 2
12700         }
12701         rm -f ${testdir}/${tfile}-pipe || error "pipe remove failed"
12702         check_stats $SINGLEMDS "unlink" 1
12703         rm -f ${testdir}/${tfile} || error "file remove failed"
12704         check_stats $SINGLEMDS "unlink" 2
12705
12706         # remove working dir and check mdt stats again.
12707         rmdir ${testdir} || error "rmdir failed"
12708         check_stats $SINGLEMDS "rmdir" 1
12709
12710         local testdir1=$DIR/${tdir}/stats_testdir1
12711         mkdir -p ${testdir}
12712         mkdir -p ${testdir1}
12713         touch ${testdir1}/test1
12714         mv ${testdir1}/test1 ${testdir} || error "file crossdir rename"
12715         check_stats $SINGLEMDS "crossdir_rename" 1
12716
12717         mv ${testdir}/test1 ${testdir}/test0 || error "file samedir rename"
12718         check_stats $SINGLEMDS "samedir_rename" 1
12719
12720         rm -rf $DIR/${tdir}
12721 }
12722 run_test 133a "Verifying MDT stats ========================================"
12723
12724 test_133b() {
12725         local res
12726
12727         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12728         remote_ost_nodsh && skip "remote OST with nodsh"
12729         remote_mds_nodsh && skip "remote MDS with nodsh"
12730
12731         local testdir=$DIR/${tdir}/stats_testdir
12732
12733         mkdir -p ${testdir} || error "mkdir failed"
12734         touch ${testdir}/${tfile} || error "touch failed"
12735         cancel_lru_locks mdc
12736
12737         # clear stats.
12738         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
12739         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
12740
12741         # extra mdt stats verification.
12742         chmod 444 ${testdir}/${tfile} || error "chmod failed"
12743         check_stats $SINGLEMDS "setattr" 1
12744         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
12745         if [ $MDS1_VERSION -ne $(version_code 2.2.0) ]
12746         then            # LU-1740
12747                 ls -l ${testdir}/${tfile} > /dev/null|| error "ls failed"
12748                 check_stats $SINGLEMDS "getattr" 1
12749         fi
12750         rm -rf $DIR/${tdir}
12751
12752         # when DNE is enabled, MDT uses STATFS RPC to ping other targets
12753         # so the check below is not reliable
12754         [ $MDSCOUNT -eq 1 ] || return 0
12755
12756         # Sleep to avoid a cached response.
12757         #define OBD_STATFS_CACHE_SECONDS 1
12758         sleep 2
12759         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
12760         do_facet ost1 $LCTL set_param obdfilter.*.exports.*.stats=clear
12761         $LFS df || error "lfs failed"
12762         check_stats $SINGLEMDS "statfs" 1
12763
12764         # check aggregated statfs (LU-10018)
12765         [ $MDS1_VERSION -lt $(version_code 2.11.54) ] &&
12766                 return 0
12767         [ $CLIENT_VERSION -lt $(version_code 2.11.54) ] &&
12768                 return 0
12769         sleep 2
12770         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
12771         do_facet ost1 $LCTL set_param obdfilter.*.exports.*.stats=clear
12772         df $DIR
12773         check_stats $SINGLEMDS "statfs" 1
12774
12775         # We want to check that the client didn't send OST_STATFS to
12776         # ost1 but the MDT also uses OST_STATFS for precreate. So some
12777         # extra care is needed here.
12778         if remote_mds; then
12779                 local nid=$($LCTL list_nids | head -1 | sed  "s/\./\\\./g")
12780                 local param="obdfilter.$FSNAME-OST0000.exports.'$nid'.stats"
12781
12782                 res=$(do_facet ost1 $LCTL get_param $param | grep statfs)
12783                 [ "$res" ] && error "OST got STATFS"
12784         fi
12785
12786         return 0
12787 }
12788 run_test 133b "Verifying extra MDT stats =================================="
12789
12790 test_133c() {
12791         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12792         remote_ost_nodsh && skip "remote OST with nodsh"
12793         remote_mds_nodsh && skip "remote MDS with nodsh"
12794
12795         local testdir=$DIR/$tdir/stats_testdir
12796
12797         test_mkdir -p $testdir
12798
12799         # verify obdfilter stats.
12800         $LFS setstripe -c 1 -i 0 $testdir/$tfile
12801         sync
12802         cancel_lru_locks osc
12803         wait_delete_completed
12804
12805         # clear stats.
12806         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
12807         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
12808
12809         dd if=/dev/zero of=$testdir/$tfile conv=notrunc bs=512k count=1 ||
12810                 error "dd failed"
12811         sync
12812         cancel_lru_locks osc
12813         check_stats ost1 "write" 1
12814
12815         dd if=$testdir/$tfile of=/dev/null bs=1k count=1 || error "dd failed"
12816         check_stats ost1 "read" 1
12817
12818         > $testdir/$tfile || error "truncate failed"
12819         check_stats ost1 "punch" 1
12820
12821         rm -f $testdir/$tfile || error "file remove failed"
12822         wait_delete_completed
12823         check_stats ost1 "destroy" 1
12824
12825         rm -rf $DIR/$tdir
12826 }
12827 run_test 133c "Verifying OST stats ========================================"
12828
12829 order_2() {
12830         local value=$1
12831         local orig=$value
12832         local order=1
12833
12834         while [ $value -ge 2 ]; do
12835                 order=$((order*2))
12836                 value=$((value/2))
12837         done
12838
12839         if [ $orig -gt $order ]; then
12840                 order=$((order*2))
12841         fi
12842         echo $order
12843 }
12844
12845 size_in_KMGT() {
12846     local value=$1
12847     local size=('K' 'M' 'G' 'T');
12848     local i=0
12849     local size_string=$value
12850
12851     while [ $value -ge 1024 ]; do
12852         if [ $i -gt 3 ]; then
12853             #T is the biggest unit we get here, if that is bigger,
12854             #just return XXXT
12855             size_string=${value}T
12856             break
12857         fi
12858         value=$((value >> 10))
12859         if [ $value -lt 1024 ]; then
12860             size_string=${value}${size[$i]}
12861             break
12862         fi
12863         i=$((i + 1))
12864     done
12865
12866     echo $size_string
12867 }
12868
12869 get_rename_size() {
12870         local size=$1
12871         local context=${2:-.}
12872         local sample=$(do_facet $SINGLEMDS $LCTL \
12873                 get_param mdt.$FSNAME-MDT0000.rename_stats |
12874                 grep -A1 $context |
12875                 awk '/ '${size}'/ {print $4}' | sed -e "s/,//g")
12876         echo $sample
12877 }
12878
12879 test_133d() {
12880         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12881         remote_ost_nodsh && skip "remote OST with nodsh"
12882         remote_mds_nodsh && skip "remote MDS with nodsh"
12883         do_facet $SINGLEMDS $LCTL list_param mdt.*.rename_stats ||
12884                 skip_env "MDS doesn't support rename stats"
12885
12886         local testdir1=$DIR/${tdir}/stats_testdir1
12887         local testdir2=$DIR/${tdir}/stats_testdir2
12888         mkdir -p $DIR/${tdir}
12889
12890         do_facet $SINGLEMDS $LCTL set_param mdt.*.rename_stats=clear
12891
12892         lfs mkdir -i 0 -c 1 ${testdir1} || error "mkdir failed"
12893         lfs mkdir -i 0 -c 1 ${testdir2} || error "mkdir failed"
12894
12895         createmany -o $testdir1/test 512 || error "createmany failed"
12896
12897         # check samedir rename size
12898         mv ${testdir1}/test0 ${testdir1}/test_0
12899
12900         local testdir1_size=$(ls -l $DIR/${tdir} |
12901                 awk '/stats_testdir1/ {print $5}')
12902         local testdir2_size=$(ls -l $DIR/${tdir} |
12903                 awk '/stats_testdir2/ {print $5}')
12904
12905         testdir1_size=$(order_2 $testdir1_size)
12906         testdir2_size=$(order_2 $testdir2_size)
12907
12908         testdir1_size=$(size_in_KMGT $testdir1_size)
12909         testdir2_size=$(size_in_KMGT $testdir2_size)
12910
12911         echo "source rename dir size: ${testdir1_size}"
12912         echo "target rename dir size: ${testdir2_size}"
12913
12914         local cmd="do_facet $SINGLEMDS $LCTL "
12915         cmd+="get_param mdt.$FSNAME-MDT0000.rename_stats"
12916
12917         eval $cmd || error "$cmd failed"
12918         local samedir=$($cmd | grep 'same_dir')
12919         local same_sample=$(get_rename_size $testdir1_size)
12920         [ -z "$samedir" ] && error "samedir_rename_size count error"
12921         [[ $same_sample -eq 1 ]] ||
12922                 error "samedir_rename_size error $same_sample"
12923         echo "Check same dir rename stats success"
12924
12925         do_facet $SINGLEMDS $LCTL set_param mdt.*.rename_stats=clear
12926
12927         # check crossdir rename size
12928         mv ${testdir1}/test_0 ${testdir2}/test_0
12929
12930         testdir1_size=$(ls -l $DIR/${tdir} |
12931                 awk '/stats_testdir1/ {print $5}')
12932         testdir2_size=$(ls -l $DIR/${tdir} |
12933                 awk '/stats_testdir2/ {print $5}')
12934
12935         testdir1_size=$(order_2 $testdir1_size)
12936         testdir2_size=$(order_2 $testdir2_size)
12937
12938         testdir1_size=$(size_in_KMGT $testdir1_size)
12939         testdir2_size=$(size_in_KMGT $testdir2_size)
12940
12941         echo "source rename dir size: ${testdir1_size}"
12942         echo "target rename dir size: ${testdir2_size}"
12943
12944         eval $cmd || error "$cmd failed"
12945         local crossdir=$($cmd | grep 'crossdir')
12946         local src_sample=$(get_rename_size $testdir1_size crossdir_src)
12947         local tgt_sample=$(get_rename_size $testdir2_size crossdir_tgt)
12948         [ -z "$crossdir" ] && error "crossdir_rename_size count error"
12949         [[ $src_sample -eq 1 ]] ||
12950                 error "crossdir_rename_size error $src_sample"
12951         [[ $tgt_sample -eq 1 ]] ||
12952                 error "crossdir_rename_size error $tgt_sample"
12953         echo "Check cross dir rename stats success"
12954         rm -rf $DIR/${tdir}
12955 }
12956 run_test 133d "Verifying rename_stats ========================================"
12957
12958 test_133e() {
12959         remote_mds_nodsh && skip "remote MDS with nodsh"
12960         remote_ost_nodsh && skip "remote OST with nodsh"
12961         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12962
12963         local testdir=$DIR/${tdir}/stats_testdir
12964         local ctr f0 f1 bs=32768 count=42 sum
12965
12966         mkdir -p ${testdir} || error "mkdir failed"
12967
12968         $LFS setstripe -c 1 -i 0 ${testdir}/${tfile}
12969
12970         for ctr in {write,read}_bytes; do
12971                 sync
12972                 cancel_lru_locks osc
12973
12974                 do_facet ost1 $LCTL set_param -n \
12975                         "obdfilter.*.exports.clear=clear"
12976
12977                 if [ $ctr = write_bytes ]; then
12978                         f0=/dev/zero
12979                         f1=${testdir}/${tfile}
12980                 else
12981                         f0=${testdir}/${tfile}
12982                         f1=/dev/null
12983                 fi
12984
12985                 dd if=$f0 of=$f1 conv=notrunc bs=$bs count=$count || \
12986                         error "dd failed"
12987                 sync
12988                 cancel_lru_locks osc
12989
12990                 sum=$(do_facet ost1 $LCTL get_param \
12991                         "obdfilter.*.exports.*.stats" |
12992                         awk -v ctr=$ctr 'BEGIN { sum = 0 }
12993                                 $1 == ctr { sum += $7 }
12994                                 END { printf("%0.0f", sum) }')
12995
12996                 if ((sum != bs * count)); then
12997                         error "Bad $ctr sum, expected $((bs * count)), got $sum"
12998                 fi
12999         done
13000
13001         rm -rf $DIR/${tdir}
13002 }
13003 run_test 133e "Verifying OST {read,write}_bytes nid stats ================="
13004
13005 test_133f() {
13006         [[ $(lustre_version_code $facet) -ge $(version_code 2.7.65) ]] ||
13007                 skip "too old lustre for get_param -R ($facet_ver)"
13008
13009         # verifying readability.
13010         $LCTL get_param -R '*' &> /dev/null
13011
13012         # Verifing writability with badarea_io.
13013         $LCTL list_param -FR '*' | grep '=' | tr -d = |
13014                 egrep -v 'force_lbug|changelog_mask' | xargs badarea_io ||
13015                 error "client badarea_io failed"
13016
13017         # remount the FS in case writes/reads /proc break the FS
13018         cleanup || error "failed to unmount"
13019         setup || error "failed to setup"
13020 }
13021 run_test 133f "Check reads/writes of client lustre proc files with bad area io"
13022
13023 test_133g() {
13024         remote_mds_nodsh && skip "remote MDS with nodsh"
13025         remote_ost_nodsh && skip "remote OST with nodsh"
13026
13027         local facet
13028         for facet in mds1 ost1; do
13029                 local facet_ver=$(lustre_version_code $facet)
13030                 if [ $facet_ver -ge $(version_code 2.7.65) ]; then
13031                         do_facet $facet "$LCTL get_param -R '*'" &> /dev/null
13032                 else
13033                         log "$facet: too old lustre for get_param -R"
13034                 fi
13035                 if [ $facet_ver -ge $(version_code 2.5.54) ]; then
13036                         do_facet $facet "$LCTL list_param -FR '*' | grep '=' |
13037                                 tr -d = | egrep -v 'force_lbug|changelog_mask' |
13038                                 xargs badarea_io" ||
13039                                         error "$facet badarea_io failed"
13040                 else
13041                         skip_noexit "$facet: too old lustre for get_param -R"
13042                 fi
13043         done
13044
13045         # remount the FS in case writes/reads /proc break the FS
13046         cleanup || error "failed to unmount"
13047         setup || error "failed to setup"
13048 }
13049 run_test 133g "Check reads/writes of server lustre proc files with bad area io"
13050
13051 test_133h() {
13052         remote_mds_nodsh && skip "remote MDS with nodsh"
13053         remote_ost_nodsh && skip "remote OST with nodsh"
13054         [[ $MDS1_VERSION -lt $(version_code 2.9.54) ]] &&
13055                 skip "Need MDS version at least 2.9.54"
13056
13057         local facet
13058         for facet in client mds1 ost1; do
13059                 # Get the list of files that are missing the terminating newline
13060                 local plist=$(do_facet $facet
13061                         $LCTL list_param -FR '*' | grep '=' | tr -d =)
13062                 local ent
13063                 for ent in $plist; do
13064                         local missing=$(do_facet $facet $LCTL get_param $ent \|\
13065                                 awk -v FS='\v' -v RS='\v\v' \
13066                                 "'END { if(NR>0 && \\\$NF !~ /.*\\\n\$/) \
13067                                         print FILENAME}'" 2>/dev/null)
13068                         [ -z $missing ] || {
13069                                 do_facet $facet $LCTL get_param $ent | od -An -tx1
13070                                 error "file does not end with newline: $facet-$ent"
13071                         }
13072                 done
13073         done
13074 }
13075 run_test 133h "Proc files should end with newlines"
13076
13077 test_134a() {
13078         remote_mds_nodsh && skip "remote MDS with nodsh"
13079         [[ $MDS1_VERSION -lt $(version_code 2.7.54) ]] &&
13080                 skip "Need MDS version at least 2.7.54"
13081
13082         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
13083         cancel_lru_locks mdc
13084
13085         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
13086         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
13087         [ $unused -eq 0 ] || error "$unused locks are not cleared"
13088
13089         local nr=1000
13090         createmany -o $DIR/$tdir/f $nr ||
13091                 error "failed to create $nr files in $DIR/$tdir"
13092         unused=$($LCTL get_param -n $nsdir.lock_unused_count)
13093
13094         #define OBD_FAIL_LDLM_WATERMARK_LOW     0x327
13095         do_facet mds1 $LCTL set_param fail_loc=0x327
13096         do_facet mds1 $LCTL set_param fail_val=500
13097         touch $DIR/$tdir/m
13098
13099         echo "sleep 10 seconds ..."
13100         sleep 10
13101         local lck_cnt=$($LCTL get_param -n $nsdir.lock_unused_count)
13102
13103         do_facet mds1 $LCTL set_param fail_loc=0
13104         do_facet mds1 $LCTL set_param fail_val=0
13105         [ $lck_cnt -lt $unused ] ||
13106                 error "No locks reclaimed, before:$unused, after:$lck_cnt"
13107
13108         rm $DIR/$tdir/m
13109         unlinkmany $DIR/$tdir/f $nr
13110 }
13111 run_test 134a "Server reclaims locks when reaching lock_reclaim_threshold"
13112
13113 test_134b() {
13114         remote_mds_nodsh && skip "remote MDS with nodsh"
13115         [[ $MDS1_VERSION -lt $(version_code 2.7.54) ]] &&
13116                 skip "Need MDS version at least 2.7.54"
13117
13118         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
13119         cancel_lru_locks mdc
13120
13121         local low_wm=$(do_facet mds1 $LCTL get_param -n \
13122                         ldlm.lock_reclaim_threshold_mb)
13123         # disable reclaim temporarily
13124         do_facet mds1 $LCTL set_param ldlm.lock_reclaim_threshold_mb=0
13125
13126         #define OBD_FAIL_LDLM_WATERMARK_HIGH     0x328
13127         do_facet mds1 $LCTL set_param fail_loc=0x328
13128         do_facet mds1 $LCTL set_param fail_val=500
13129
13130         $LCTL set_param debug=+trace
13131
13132         local nr=600
13133         createmany -o $DIR/$tdir/f $nr &
13134         local create_pid=$!
13135
13136         echo "Sleep $TIMEOUT seconds ..."
13137         sleep $TIMEOUT
13138         if ! ps -p $create_pid  > /dev/null 2>&1; then
13139                 do_facet mds1 $LCTL set_param fail_loc=0
13140                 do_facet mds1 $LCTL set_param fail_val=0
13141                 do_facet mds1 $LCTL set_param \
13142                         ldlm.lock_reclaim_threshold_mb=${low_wm}m
13143                 error "createmany finished incorrectly!"
13144         fi
13145         do_facet mds1 $LCTL set_param fail_loc=0
13146         do_facet mds1 $LCTL set_param fail_val=0
13147         do_facet mds1 $LCTL set_param ldlm.lock_reclaim_threshold_mb=${low_wm}m
13148         wait $create_pid || return 1
13149
13150         unlinkmany $DIR/$tdir/f $nr
13151 }
13152 run_test 134b "Server rejects lock request when reaching lock_limit_mb"
13153
13154 test_135() {
13155         remote_mds_nodsh && skip "remote MDS with nodsh"
13156         [[ $MDS1_VERSION -lt $(version_code 2.13.50) ]] &&
13157                 skip "Need MDS version at least 2.13.50"
13158         local fname
13159
13160         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
13161
13162 #define OBD_FAIL_PLAIN_RECORDS 0x1319
13163         #set only one record at plain llog
13164         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x1319 fail_val=1
13165
13166         #fill already existed plain llog each 64767
13167         #wrapping whole catalog
13168         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 1))
13169
13170         createmany -o $DIR/$tdir/$tfile_ 64700
13171         for (( i = 0; i < 64700; i = i + 2 ))
13172         do
13173                 rm $DIR/$tdir/$tfile_$i &
13174                 rm $DIR/$tdir/$tfile_$((i + 1)) &
13175                 local pid=$!
13176                 wait $pid
13177         done
13178
13179         #waiting osp synchronization
13180         wait_delete_completed
13181 }
13182 run_test 135 "Race catalog processing"
13183
13184 test_136() {
13185         remote_mds_nodsh && skip "remote MDS with nodsh"
13186         [[ $MDS1_VERSION -lt $(version_code 2.13.50) ]] &&
13187                 skip "Need MDS version at least 2.13.50"
13188         local fname
13189
13190         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
13191         $LFS setstripe -c 1 -i 0 $DIR/$tdir || error "failed to set striping"
13192         #set only one record at plain llog
13193 #define OBD_FAIL_CATALOG_FULL_CHECK                0x131a
13194         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x131a fail_val=1
13195
13196         #fill already existed 2 plain llogs each 64767
13197         #wrapping whole catalog
13198         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 1))
13199         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 3 / 2))
13200         wait_delete_completed
13201
13202         createmany -o $DIR/$tdir/$tfile_ 10
13203         sleep 25
13204
13205         do_facet $SINGLEMDS $LCTL set_param fail_val=3
13206         for (( i = 0; i < 10; i = i + 3 ))
13207         do
13208                 rm $DIR/$tdir/$tfile_$i &
13209                 rm $DIR/$tdir/$tfile_$((i + 1)) &
13210                 local pid=$!
13211                 wait $pid
13212                 sleep 7
13213                 rm $DIR/$tdir/$tfile_$((i + 2)) &
13214         done
13215
13216         #waiting osp synchronization
13217         wait_delete_completed
13218 }
13219 run_test 136 "Race catalog processing 2"
13220
13221 test_140() { #bug-17379
13222         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13223
13224         test_mkdir $DIR/$tdir
13225         cd $DIR/$tdir || error "Changing to $DIR/$tdir"
13226         cp $(which stat) . || error "Copying stat to $DIR/$tdir"
13227
13228         # VFS limits max symlink depth to 5(4KSTACK) or 7(8KSTACK) or 8
13229         # For kernel > 3.5, bellow only tests consecutive symlink (MAX 40)
13230         local i=0
13231         while i=$((i + 1)); do
13232                 test_mkdir $i
13233                 cd $i || error "Changing to $i"
13234                 ln -s ../stat stat || error "Creating stat symlink"
13235                 # Read the symlink until ELOOP present,
13236                 # not LBUGing the system is considered success,
13237                 # we didn't overrun the stack.
13238                 $OPENFILE -f O_RDONLY stat >/dev/null 2>&1; ret=$?
13239                 if [ $ret -ne 0 ]; then
13240                         if [ $ret -eq 40 ]; then
13241                                 break  # -ELOOP
13242                         else
13243                                 error "Open stat symlink"
13244                                         return
13245                         fi
13246                 fi
13247         done
13248         i=$((i - 1))
13249         echo "The symlink depth = $i"
13250         [ $i -eq 5 ] || [ $i -eq 7 ] || [ $i -eq 8 ] || [ $i -eq 40 ] ||
13251                 error "Invalid symlink depth"
13252
13253         # Test recursive symlink
13254         ln -s symlink_self symlink_self
13255         $OPENFILE -f O_RDONLY symlink_self >/dev/null 2>&1; ret=$?
13256         echo "open symlink_self returns $ret"
13257         [ $ret -eq 40 ] || error "recursive symlink doesn't return -ELOOP"
13258 }
13259 run_test 140 "Check reasonable stack depth (shouldn't LBUG) ===="
13260
13261 test_150a() {
13262         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13263
13264         local TF="$TMP/$tfile"
13265
13266         dd if=/dev/urandom of=$TF bs=6096 count=1 || error "dd failed"
13267         cp $TF $DIR/$tfile
13268         cancel_lru_locks $OSC
13269         cmp $TF $DIR/$tfile || error "$TMP/$tfile $DIR/$tfile differ"
13270         remount_client $MOUNT
13271         df -P $MOUNT
13272         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (remount)"
13273
13274         $TRUNCATE $TF 6000
13275         $TRUNCATE $DIR/$tfile 6000
13276         cancel_lru_locks $OSC
13277         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (truncate1)"
13278
13279         echo "12345" >>$TF
13280         echo "12345" >>$DIR/$tfile
13281         cancel_lru_locks $OSC
13282         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (append1)"
13283
13284         echo "12345" >>$TF
13285         echo "12345" >>$DIR/$tfile
13286         cancel_lru_locks $OSC
13287         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (append2)"
13288
13289         rm -f $TF
13290         true
13291 }
13292 run_test 150a "truncate/append tests"
13293
13294 test_150b() {
13295         [ "$ost1_FSTYPE" != ldiskfs ] && skip "non-ldiskfs backend"
13296         [ $OST1_VERSION -lt $(version_code 2.13.50) ] &&
13297                 skip "Need OST version at least 2.13.53"
13298         touch $DIR/$tfile
13299         check_fallocate $DIR/$tfile || error "fallocate failed"
13300 }
13301 run_test 150b "Verify fallocate (prealloc) functionality"
13302
13303 test_150c() {
13304         local bytes
13305         local want
13306
13307         [ "$ost1_FSTYPE" != ldiskfs ] && skip "non-ldiskfs backend"
13308         [ $OST1_VERSION -lt $(version_code 2.13.50) ] &&
13309                 skip "Need OST version at least 2.13.53"
13310
13311         $LFS setstripe -c $OSTCOUNT -S1M $DIR/$tdir || error "setstripe failed"
13312         fallocate -l ${OSTCOUNT}m $DIR/$tdir || error "fallocate failed"
13313         sync; sync_all_data
13314         cancel_lru_locks $OSC
13315         sleep 5
13316         bytes=$(($(stat -c '%b * %B' $DIR/$tdir)))
13317         want=$((OSTCOUNT * 1048576))
13318
13319         # Must allocate all requested space, not more than 5% extra
13320         (( $bytes >= $want && $bytes < $want * 105 / 100 )) ||
13321                 error "bytes $bytes is not $want"
13322 }
13323 run_test 150c "Verify fallocate Size and Blocks"
13324
13325 test_150d() {
13326         local bytes
13327         local want
13328
13329         [ "$ost1_FSTYPE" != ldiskfs ] && skip "non-ldiskfs backend"
13330         [ $OST1_VERSION -lt $(version_code 2.13.50) ] &&
13331                 skip "Need OST version at least 2.13.53"
13332
13333         $LFS setstripe -c $OSTCOUNT -S1M $DIR/$tdir || error "setstripe failed"
13334         fallocate -o 1G -l ${OSTCOUNT}m $DIR/$tdir || error "fallocate failed"
13335         sync; sync_all_data
13336         cancel_lru_locks $OSC
13337         sleep 5
13338         bytes=$(($(stat -c '%b * %B' $DIR/$tdir)))
13339         want=$((OSTCOUNT * 1048576))
13340
13341         # Must allocate all requested space, not more than 5% extra
13342         (( $bytes >= $want && $bytes < $want * 105 / 100 )) ||
13343                 error "bytes $bytes is not $want"
13344 }
13345 run_test 150d "Verify fallocate Size and Blocks - Non zero start"
13346
13347 #LU-2902 roc_hit was not able to read all values from lproc
13348 function roc_hit_init() {
13349         local list=$(comma_list $(osts_nodes))
13350         local dir=$DIR/$tdir-check
13351         local file=$dir/$tfile
13352         local BEFORE
13353         local AFTER
13354         local idx
13355
13356         test_mkdir $dir
13357         #use setstripe to do a write to every ost
13358         for i in $(seq 0 $((OSTCOUNT-1))); do
13359                 $LFS setstripe -c 1 -i $i $dir || error "$LFS setstripe $file failed"
13360                 dd if=/dev/urandom of=$file bs=4k count=4 2>&1 > /dev/null
13361                 idx=$(printf %04x $i)
13362                 BEFORE=$(get_osd_param $list *OST*$idx stats |
13363                         awk '$1 == "cache_access" {sum += $7}
13364                                 END { printf("%0.0f", sum) }')
13365
13366                 cancel_lru_locks osc
13367                 cat $file >/dev/null
13368
13369                 AFTER=$(get_osd_param $list *OST*$idx stats |
13370                         awk '$1 == "cache_access" {sum += $7}
13371                                 END { printf("%0.0f", sum) }')
13372
13373                 echo BEFORE:$BEFORE AFTER:$AFTER
13374                 if ! let "AFTER - BEFORE == 4"; then
13375                         rm -rf $dir
13376                         error "roc_hit is not safe to use"
13377                 fi
13378                 rm $file
13379         done
13380
13381         rm -rf $dir
13382 }
13383
13384 function roc_hit() {
13385         local list=$(comma_list $(osts_nodes))
13386         echo $(get_osd_param $list '' stats |
13387                 awk '$1 == "cache_hit" {sum += $7}
13388                         END { printf("%0.0f", sum) }')
13389 }
13390
13391 function set_cache() {
13392         local on=1
13393
13394         if [ "$2" == "off" ]; then
13395                 on=0;
13396         fi
13397         local list=$(comma_list $(osts_nodes))
13398         set_osd_param $list '' $1_cache_enable $on
13399
13400         cancel_lru_locks osc
13401 }
13402
13403 test_151() {
13404         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13405         remote_ost_nodsh && skip "remote OST with nodsh"
13406
13407         local CPAGES=3
13408         local list=$(comma_list $(osts_nodes))
13409
13410         # check whether obdfilter is cache capable at all
13411         if ! get_osd_param $list '' read_cache_enable >/dev/null; then
13412                 skip "not cache-capable obdfilter"
13413         fi
13414
13415         # check cache is enabled on all obdfilters
13416         if get_osd_param $list '' read_cache_enable | grep 0; then
13417                 skip "oss cache is disabled"
13418         fi
13419
13420         set_osd_param $list '' writethrough_cache_enable 1
13421
13422         # check write cache is enabled on all obdfilters
13423         if get_osd_param $list '' writethrough_cache_enable | grep 0; then
13424                 skip "oss write cache is NOT enabled"
13425         fi
13426
13427         roc_hit_init
13428
13429         #define OBD_FAIL_OBD_NO_LRU  0x609
13430         do_nodes $list $LCTL set_param fail_loc=0x609
13431
13432         # pages should be in the case right after write
13433         dd if=/dev/urandom of=$DIR/$tfile bs=4k count=$CPAGES ||
13434                 error "dd failed"
13435
13436         local BEFORE=$(roc_hit)
13437         cancel_lru_locks osc
13438         cat $DIR/$tfile >/dev/null
13439         local AFTER=$(roc_hit)
13440
13441         do_nodes $list $LCTL set_param fail_loc=0
13442
13443         if ! let "AFTER - BEFORE == CPAGES"; then
13444                 error "NOT IN CACHE: before: $BEFORE, after: $AFTER"
13445         fi
13446
13447         cancel_lru_locks osc
13448         # invalidates OST cache
13449         do_nodes $list "echo 1 > /proc/sys/vm/drop_caches"
13450         set_osd_param $list '' read_cache_enable 0
13451         cat $DIR/$tfile >/dev/null
13452
13453         # now data shouldn't be found in the cache
13454         BEFORE=$(roc_hit)
13455         cancel_lru_locks osc
13456         cat $DIR/$tfile >/dev/null
13457         AFTER=$(roc_hit)
13458         if let "AFTER - BEFORE != 0"; then
13459                 error "IN CACHE: before: $BEFORE, after: $AFTER"
13460         fi
13461
13462         set_osd_param $list '' read_cache_enable 1
13463         rm -f $DIR/$tfile
13464 }
13465 run_test 151 "test cache on oss and controls ==============================="
13466
13467 test_152() {
13468         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13469
13470         local TF="$TMP/$tfile"
13471
13472         # simulate ENOMEM during write
13473 #define OBD_FAIL_OST_NOMEM      0x226
13474         lctl set_param fail_loc=0x80000226
13475         dd if=/dev/urandom of=$TF bs=6096 count=1 || error "dd failed"
13476         cp $TF $DIR/$tfile
13477         sync || error "sync failed"
13478         lctl set_param fail_loc=0
13479
13480         # discard client's cache
13481         cancel_lru_locks osc
13482
13483         # simulate ENOMEM during read
13484         lctl set_param fail_loc=0x80000226
13485         cmp $TF $DIR/$tfile || error "cmp failed"
13486         lctl set_param fail_loc=0
13487
13488         rm -f $TF
13489 }
13490 run_test 152 "test read/write with enomem ============================"
13491
13492 test_153() {
13493         $MULTIOP $DIR/$tfile Ow4096Ycu || error "multiop failed"
13494 }
13495 run_test 153 "test if fdatasync does not crash ======================="
13496
13497 dot_lustre_fid_permission_check() {
13498         local fid=$1
13499         local ffid=$MOUNT/.lustre/fid/$fid
13500         local test_dir=$2
13501
13502         echo "stat fid $fid"
13503         stat $ffid > /dev/null || error "stat $ffid failed."
13504         echo "touch fid $fid"
13505         touch $ffid || error "touch $ffid failed."
13506         echo "write to fid $fid"
13507         cat /etc/hosts > $ffid || error "write $ffid failed."
13508         echo "read fid $fid"
13509         diff /etc/hosts $ffid || error "read $ffid failed."
13510         echo "append write to fid $fid"
13511         cat /etc/hosts >> $ffid || error "append write $ffid failed."
13512         echo "rename fid $fid"
13513         mv $ffid $test_dir/$tfile.1 &&
13514                 error "rename $ffid to $tfile.1 should fail."
13515         touch $test_dir/$tfile.1
13516         mv $test_dir/$tfile.1 $ffid &&
13517                 error "rename $tfile.1 to $ffid should fail."
13518         rm -f $test_dir/$tfile.1
13519         echo "truncate fid $fid"
13520         $TRUNCATE $ffid 777 || error "truncate $ffid failed."
13521         echo "link fid $fid"
13522         ln -f $ffid $test_dir/tfile.lnk || error "link $ffid failed."
13523         if [[ $($LCTL get_param -n mdc.*-mdc-*.connect_flags) =~ acl ]]; then
13524                 echo "setfacl fid $fid"
13525                 setfacl -R -m u:bin:rwx $ffid || error "setfacl $ffid failed."
13526                 echo "getfacl fid $fid"
13527                 getfacl $ffid >/dev/null || error "getfacl $ffid failed."
13528         fi
13529         echo "unlink fid $fid"
13530         unlink $MOUNT/.lustre/fid/$fid && error "unlink $ffid should fail."
13531         echo "mknod fid $fid"
13532         mknod $ffid c 1 3 && error "mknod $ffid should fail."
13533
13534         fid=[0xf00000400:0x1:0x0]
13535         ffid=$MOUNT/.lustre/fid/$fid
13536
13537         echo "stat non-exist fid $fid"
13538         stat $ffid > /dev/null && error "stat non-exist $ffid should fail."
13539         echo "write to non-exist fid $fid"
13540         cat /etc/hosts > $ffid && error "write non-exist $ffid should fail."
13541         echo "link new fid $fid"
13542         ln $test_dir/$tfile $ffid && error "link $ffid should fail."
13543
13544         mkdir -p $test_dir/$tdir
13545         touch $test_dir/$tdir/$tfile
13546         fid=$($LFS path2fid $test_dir/$tdir)
13547         rc=$?
13548         [ $rc -ne 0 ] &&
13549                 error "error: could not get fid for $test_dir/$dir/$tfile."
13550
13551         ffid=$MOUNT/.lustre/fid/$fid
13552
13553         echo "ls $fid"
13554         ls $ffid > /dev/null || error "ls $ffid failed."
13555         echo "touch $fid/$tfile.1"
13556         touch $ffid/$tfile.1 || error "touch $ffid/$tfile.1 failed."
13557
13558         echo "touch $MOUNT/.lustre/fid/$tfile"
13559         touch $MOUNT/.lustre/fid/$tfile && \
13560                 error "touch $MOUNT/.lustre/fid/$tfile should fail."
13561
13562         echo "setxattr to $MOUNT/.lustre/fid"
13563         setfattr -n trusted.name1 -v value1 $MOUNT/.lustre/fid
13564
13565         echo "listxattr for $MOUNT/.lustre/fid"
13566         getfattr -d -m "^trusted" $MOUNT/.lustre/fid
13567
13568         echo "delxattr from $MOUNT/.lustre/fid"
13569         setfattr -x trusted.name1 $MOUNT/.lustre/fid
13570
13571         echo "touch invalid fid: $MOUNT/.lustre/fid/[0x200000400:0x2:0x3]"
13572         touch $MOUNT/.lustre/fid/[0x200000400:0x2:0x3] &&
13573                 error "touch invalid fid should fail."
13574
13575         echo "touch non-normal fid: $MOUNT/.lustre/fid/[0x1:0x2:0x0]"
13576         touch $MOUNT/.lustre/fid/[0x1:0x2:0x0] &&
13577                 error "touch non-normal fid should fail."
13578
13579         echo "rename $tdir to $MOUNT/.lustre/fid"
13580         mrename $test_dir/$tdir $MOUNT/.lustre/fid &&
13581                 error "rename to $MOUNT/.lustre/fid should fail."
13582
13583         if [ $MDS1_VERSION -ge $(version_code 2.3.51) ]
13584         then            # LU-3547
13585                 local old_obf_mode=$(stat --format="%a" $DIR/.lustre/fid)
13586                 local new_obf_mode=777
13587
13588                 echo "change mode of $DIR/.lustre/fid to $new_obf_mode"
13589                 chmod $new_obf_mode $DIR/.lustre/fid ||
13590                         error "chmod $new_obf_mode $DIR/.lustre/fid failed"
13591
13592                 local obf_mode=$(stat --format=%a $DIR/.lustre/fid)
13593                 [ $obf_mode -eq $new_obf_mode ] ||
13594                         error "stat $DIR/.lustre/fid returned wrong mode $obf_mode"
13595
13596                 echo "restore mode of $DIR/.lustre/fid to $old_obf_mode"
13597                 chmod $old_obf_mode $DIR/.lustre/fid ||
13598                         error "chmod $old_obf_mode $DIR/.lustre/fid failed"
13599         fi
13600
13601         $OPENFILE -f O_LOV_DELAY_CREATE:O_CREAT $test_dir/$tfile-2
13602         fid=$($LFS path2fid $test_dir/$tfile-2)
13603
13604         if [ $MDS1_VERSION -ge $(version_code 2.6.50) ]
13605         then # LU-5424
13606                 echo "cp /etc/passwd $MOUNT/.lustre/fid/$fid"
13607                 cp /etc/passwd $MOUNT/.lustre/fid/$fid ||
13608                         error "create lov data thru .lustre failed"
13609         fi
13610         echo "cp /etc/passwd $test_dir/$tfile-2"
13611         cp /etc/passwd $test_dir/$tfile-2 ||
13612                 error "copy to $test_dir/$tfile-2 failed."
13613         echo "diff /etc/passwd $MOUNT/.lustre/fid/$fid"
13614         diff /etc/passwd $MOUNT/.lustre/fid/$fid ||
13615                 error "diff /etc/passwd $MOUNT/.lustre/fid/$fid failed."
13616
13617         rm -rf $test_dir/tfile.lnk
13618         rm -rf $test_dir/$tfile-2
13619 }
13620
13621 test_154A() {
13622         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
13623                 skip "Need MDS version at least 2.4.1"
13624
13625         local tf=$DIR/$tfile
13626         touch $tf
13627
13628         local fid=$($LFS path2fid $tf)
13629         [ -z "$fid" ] && error "path2fid unable to get $tf FID"
13630
13631         # check that we get the same pathname back
13632         local rootpath
13633         local found
13634         for rootpath in "$MOUNT" "$MOUNT///" "$MOUNT/$tfile"; do
13635                 echo "$rootpath $fid"
13636                 found=$($LFS fid2path $rootpath "$fid")
13637                 [ -z "$found" ] && error "fid2path unable to get '$fid' path"
13638                 [ "$found" == "$tf" ] || error "fid2path $found != $tf"
13639         done
13640
13641         # check wrong root path format
13642         rootpath=$MOUNT"_wrong"
13643         found=$($LFS fid2path $rootpath "$fid")
13644         [ -z "$found" ] || error "should fail ($rootpath != $MOUNT)"
13645 }
13646 run_test 154A "lfs path2fid and fid2path basic checks"
13647
13648 test_154B() {
13649         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
13650                 skip "Need MDS version at least 2.4.1"
13651
13652         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
13653         touch $DIR/$tdir/$tfile || error "touch $DIR/$tdir/$tfile failed"
13654         local linkea=$($LL_DECODE_LINKEA $DIR/$tdir/$tfile | grep 'pfid')
13655         [ -z "$linkea" ] && error "decode linkea $DIR/$tdir/$tfile failed"
13656
13657         local name=$(echo $linkea | awk '/pfid/ {print $5}' | sed -e "s/'//g")
13658         local PFID=$(echo $linkea | awk '/pfid/ {print $3}' | sed -e "s/,//g")
13659
13660         # check that we get the same pathname
13661         echo "PFID: $PFID, name: $name"
13662         local FOUND=$($LFS fid2path $MOUNT "$PFID")
13663         [ -z "$FOUND" ] && error "fid2path unable to get $PFID path"
13664         [ "$FOUND/$name" != "$DIR/$tdir/$tfile" ] &&
13665                 error "ll_decode_linkea has $FOUND/$name != $DIR/$tdir/$tfile"
13666
13667         rm -rf $DIR/$tdir || error "Can not delete directory $DIR/$tdir"
13668 }
13669 run_test 154B "verify the ll_decode_linkea tool"
13670
13671 test_154a() {
13672         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13673         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
13674         [[ $MDS1_VERSION -ge $(version_code 2.2.51) ]] ||
13675                 skip "Need MDS version at least 2.2.51"
13676         [ -z "$(which setfacl)" ] && skip_env "must have setfacl tool"
13677
13678         cp /etc/hosts $DIR/$tfile
13679
13680         fid=$($LFS path2fid $DIR/$tfile)
13681         rc=$?
13682         [ $rc -ne 0 ] && error "error: could not get fid for $DIR/$tfile."
13683
13684         dot_lustre_fid_permission_check "$fid" $DIR ||
13685                 error "dot lustre permission check $fid failed"
13686
13687         ls -a $MOUNT | grep "\.lustre" && error ".lustre should not be listed"
13688
13689         rm -rf $MOUNT/.lustre && error ".lustre is not allowed to be unlinked"
13690
13691         touch $MOUNT/.lustre/file &&
13692                 error "creation is not allowed under .lustre"
13693
13694         mkdir $MOUNT/.lustre/dir &&
13695                 error "mkdir is not allowed under .lustre"
13696
13697         rm -rf $DIR/$tfile
13698 }
13699 run_test 154a "Open-by-FID"
13700
13701 test_154b() {
13702         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13703         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
13704         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
13705         [[ $MDS1_VERSION -ge $(version_code 2.2.51) ]] ||
13706                 skip "Need MDS version at least 2.2.51"
13707
13708         local remote_dir=$DIR/$tdir/remote_dir
13709         local MDTIDX=1
13710         local rc=0
13711
13712         mkdir -p $DIR/$tdir
13713         $LFS mkdir -i $MDTIDX $remote_dir ||
13714                 error "create remote directory failed"
13715
13716         cp /etc/hosts $remote_dir/$tfile
13717
13718         fid=$($LFS path2fid $remote_dir/$tfile)
13719         rc=$?
13720         [ $rc -ne 0 ] && error "error: could not get fid for $remote_dir/$tfile"
13721
13722         dot_lustre_fid_permission_check "$fid" $remote_dir ||
13723                 error "dot lustre permission check $fid failed"
13724         rm -rf $DIR/$tdir
13725 }
13726 run_test 154b "Open-by-FID for remote directory"
13727
13728 test_154c() {
13729         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
13730                 skip "Need MDS version at least 2.4.1"
13731
13732         touch $DIR/$tfile.1 $DIR/$tfile.2 $DIR/$tfile.3
13733         local FID1=$($LFS path2fid $DIR/$tfile.1)
13734         local FID2=$($LFS path2fid $DIR/$tfile.2)
13735         local FID3=$($LFS path2fid $DIR/$tfile.3)
13736
13737         local N=1
13738         $LFS path2fid $DIR/$tfile.[123] | while read PATHNAME FID; do
13739                 [ "$PATHNAME" = "$DIR/$tfile.$N:" ] ||
13740                         error "path2fid pathname $PATHNAME != $DIR/$tfile.$N:"
13741                 local want=FID$N
13742                 [ "$FID" = "${!want}" ] ||
13743                         error "path2fid $PATHNAME FID $FID != FID$N ${!want}"
13744                 N=$((N + 1))
13745         done
13746
13747         $LFS fid2path $MOUNT "$FID1" "$FID2" "$FID3" | while read PATHNAME;
13748         do
13749                 [ "$PATHNAME" = "$DIR/$tfile.$N" ] ||
13750                         error "fid2path pathname $PATHNAME != $DIR/$tfile.$N:"
13751                 N=$((N + 1))
13752         done
13753 }
13754 run_test 154c "lfs path2fid and fid2path multiple arguments"
13755
13756 test_154d() {
13757         remote_mds_nodsh && skip "remote MDS with nodsh"
13758         [[ $MDS1_VERSION -lt $(version_code 2.5.53) ]] &&
13759                 skip "Need MDS version at least 2.5.53"
13760
13761         if remote_mds; then
13762                 nid=$($LCTL list_nids | sed  "s/\./\\\./g")
13763         else
13764                 nid="0@lo"
13765         fi
13766         local proc_ofile="mdt.*.exports.'$nid'.open_files"
13767         local fd
13768         local cmd
13769
13770         rm -f $DIR/$tfile
13771         touch $DIR/$tfile
13772
13773         local fid=$($LFS path2fid $DIR/$tfile)
13774         # Open the file
13775         fd=$(free_fd)
13776         cmd="exec $fd<$DIR/$tfile"
13777         eval $cmd
13778         local fid_list=$(do_facet $SINGLEMDS $LCTL get_param $proc_ofile)
13779         echo "$fid_list" | grep "$fid"
13780         rc=$?
13781
13782         cmd="exec $fd>/dev/null"
13783         eval $cmd
13784         if [ $rc -ne 0 ]; then
13785                 error "FID $fid not found in open files list $fid_list"
13786         fi
13787 }
13788 run_test 154d "Verify open file fid"
13789
13790 test_154e()
13791 {
13792         [[ $MDS1_VERSION -lt $(version_code 2.6.50) ]] &&
13793                 skip "Need MDS version at least 2.6.50"
13794
13795         if ls -a $MOUNT | grep -q '^\.lustre$'; then
13796                 error ".lustre returned by readdir"
13797         fi
13798 }
13799 run_test 154e ".lustre is not returned by readdir"
13800
13801 test_154f() {
13802         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
13803
13804         # create parent directory on a single MDT to avoid cross-MDT hardlinks
13805         test_mkdir -p -c1 $DIR/$tdir/d
13806         # test dirs inherit from its stripe
13807         mkdir -p $DIR/$tdir/d/foo1 || error "mkdir error"
13808         mkdir -p $DIR/$tdir/d/foo2 || error "mkdir error"
13809         cp /etc/hosts $DIR/$tdir/d/foo1/$tfile
13810         ln $DIR/$tdir/d/foo1/$tfile $DIR/$tdir/d/foo2/link
13811         touch $DIR/f
13812
13813         # get fid of parents
13814         local FID0=$($LFS path2fid $DIR/$tdir/d)
13815         local FID1=$($LFS path2fid $DIR/$tdir/d/foo1)
13816         local FID2=$($LFS path2fid $DIR/$tdir/d/foo2)
13817         local FID3=$($LFS path2fid $DIR)
13818
13819         # check that path2fid --parents returns expected <parent_fid>/name
13820         # 1) test for a directory (single parent)
13821         local parent=$($LFS path2fid --parents $DIR/$tdir/d/foo1)
13822         [ "$parent" == "$FID0/foo1" ] ||
13823                 error "expected parent: $FID0/foo1, got: $parent"
13824
13825         # 2) test for a file with nlink > 1 (multiple parents)
13826         parent=$($LFS path2fid --parents $DIR/$tdir/d/foo1/$tfile)
13827         echo "$parent" | grep -F "$FID1/$tfile" ||
13828                 error "$FID1/$tfile not returned in parent list"
13829         echo "$parent" | grep -F "$FID2/link" ||
13830                 error "$FID2/link not returned in parent list"
13831
13832         # 3) get parent by fid
13833         local file_fid=$($LFS path2fid $DIR/$tdir/d/foo1/$tfile)
13834         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
13835         echo "$parent" | grep -F "$FID1/$tfile" ||
13836                 error "$FID1/$tfile not returned in parent list (by fid)"
13837         echo "$parent" | grep -F "$FID2/link" ||
13838                 error "$FID2/link not returned in parent list (by fid)"
13839
13840         # 4) test for entry in root directory
13841         parent=$($LFS path2fid --parents $DIR/f)
13842         echo "$parent" | grep -F "$FID3/f" ||
13843                 error "$FID3/f not returned in parent list"
13844
13845         # 5) test it on root directory
13846         [ -z "$($LFS path2fid --parents $MOUNT 2>/dev/null)" ] ||
13847                 error "$MOUNT should not have parents"
13848
13849         # enable xattr caching and check that linkea is correctly updated
13850         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
13851         save_lustre_params client "llite.*.xattr_cache" > $save
13852         lctl set_param llite.*.xattr_cache 1
13853
13854         # 6.1) linkea update on rename
13855         mv $DIR/$tdir/d/foo1/$tfile $DIR/$tdir/d/foo2/$tfile.moved
13856
13857         # get parents by fid
13858         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
13859         # foo1 should no longer be returned in parent list
13860         echo "$parent" | grep -F "$FID1" &&
13861                 error "$FID1 should no longer be in parent list"
13862         # the new path should appear
13863         echo "$parent" | grep -F "$FID2/$tfile.moved" ||
13864                 error "$FID2/$tfile.moved is not in parent list"
13865
13866         # 6.2) linkea update on unlink
13867         rm -f $DIR/$tdir/d/foo2/link
13868         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
13869         # foo2/link should no longer be returned in parent list
13870         echo "$parent" | grep -F "$FID2/link" &&
13871                 error "$FID2/link should no longer be in parent list"
13872         true
13873
13874         rm -f $DIR/f
13875         restore_lustre_params < $save
13876         rm -f $save
13877 }
13878 run_test 154f "get parent fids by reading link ea"
13879
13880 test_154g()
13881 {
13882         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
13883         [[ $MDS1_VERSION -ge $(version_code 2.6.92) &&
13884            $CLIENT_VERSION -gt $(version_code 2.6.99) ]] ||
13885                 skip "Need MDS version at least 2.6.92"
13886
13887         mkdir -p $DIR/$tdir
13888         llapi_fid_test -d $DIR/$tdir
13889 }
13890 run_test 154g "various llapi FID tests"
13891
13892 test_155_small_load() {
13893     local temp=$TMP/$tfile
13894     local file=$DIR/$tfile
13895
13896     dd if=/dev/urandom of=$temp bs=6096 count=1 || \
13897         error "dd of=$temp bs=6096 count=1 failed"
13898     cp $temp $file
13899     cancel_lru_locks $OSC
13900     cmp $temp $file || error "$temp $file differ"
13901
13902     $TRUNCATE $temp 6000
13903     $TRUNCATE $file 6000
13904     cmp $temp $file || error "$temp $file differ (truncate1)"
13905
13906     echo "12345" >>$temp
13907     echo "12345" >>$file
13908     cmp $temp $file || error "$temp $file differ (append1)"
13909
13910     echo "12345" >>$temp
13911     echo "12345" >>$file
13912     cmp $temp $file || error "$temp $file differ (append2)"
13913
13914     rm -f $temp $file
13915     true
13916 }
13917
13918 test_155_big_load() {
13919         remote_ost_nodsh && skip "remote OST with nodsh"
13920
13921         local temp=$TMP/$tfile
13922         local file=$DIR/$tfile
13923
13924         free_min_max
13925         local cache_size=$(do_facet ost$((MAXI+1)) \
13926                 "awk '/cache/ {sum+=\\\$4} END {print sum}' /proc/cpuinfo")
13927         local large_file_size=$((cache_size * 2))
13928
13929         echo "OSS cache size: $cache_size KB"
13930         echo "Large file size: $large_file_size KB"
13931
13932         [ $MAXV -le $large_file_size ] &&
13933                 skip_env "max available OST size needs > $large_file_size KB"
13934
13935         $LFS setstripe $file -c 1 -i $MAXI || error "$LFS setstripe $file failed"
13936
13937         dd if=/dev/urandom of=$temp bs=$large_file_size count=1k ||
13938                 error "dd of=$temp bs=$large_file_size count=1k failed"
13939         cp $temp $file
13940         ls -lh $temp $file
13941         cancel_lru_locks osc
13942         cmp $temp $file || error "$temp $file differ"
13943
13944         rm -f $temp $file
13945         true
13946 }
13947
13948 save_writethrough() {
13949         local facets=$(get_facets OST)
13950
13951         save_lustre_params $facets "osd-*.*.writethrough_cache_enable" > $1
13952 }
13953
13954 test_155a() {
13955         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13956
13957         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
13958
13959         save_writethrough $p
13960
13961         set_cache read on
13962         set_cache writethrough on
13963         test_155_small_load
13964         restore_lustre_params < $p
13965         rm -f $p
13966 }
13967 run_test 155a "Verify small file correctness: read cache:on write_cache:on"
13968
13969 test_155b() {
13970         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13971
13972         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
13973
13974         save_writethrough $p
13975
13976         set_cache read on
13977         set_cache writethrough off
13978         test_155_small_load
13979         restore_lustre_params < $p
13980         rm -f $p
13981 }
13982 run_test 155b "Verify small file correctness: read cache:on write_cache:off"
13983
13984 test_155c() {
13985         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13986
13987         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
13988
13989         save_writethrough $p
13990
13991         set_cache read off
13992         set_cache writethrough on
13993         test_155_small_load
13994         restore_lustre_params < $p
13995         rm -f $p
13996 }
13997 run_test 155c "Verify small file correctness: read cache:off write_cache:on"
13998
13999 test_155d() {
14000         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14001
14002         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
14003
14004         save_writethrough $p
14005
14006         set_cache read off
14007         set_cache writethrough off
14008         test_155_small_load
14009         restore_lustre_params < $p
14010         rm -f $p
14011 }
14012 run_test 155d "Verify small file correctness: read cache:off write_cache:off"
14013
14014 test_155e() {
14015         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14016
14017         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
14018
14019         save_writethrough $p
14020
14021         set_cache read on
14022         set_cache writethrough on
14023         test_155_big_load
14024         restore_lustre_params < $p
14025         rm -f $p
14026 }
14027 run_test 155e "Verify big file correctness: read cache:on write_cache:on"
14028
14029 test_155f() {
14030         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14031
14032         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
14033
14034         save_writethrough $p
14035
14036         set_cache read on
14037         set_cache writethrough off
14038         test_155_big_load
14039         restore_lustre_params < $p
14040         rm -f $p
14041 }
14042 run_test 155f "Verify big file correctness: read cache:on write_cache:off"
14043
14044 test_155g() {
14045         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14046
14047         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
14048
14049         save_writethrough $p
14050
14051         set_cache read off
14052         set_cache writethrough on
14053         test_155_big_load
14054         restore_lustre_params < $p
14055         rm -f $p
14056 }
14057 run_test 155g "Verify big file correctness: read cache:off write_cache:on"
14058
14059 test_155h() {
14060         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14061
14062         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
14063
14064         save_writethrough $p
14065
14066         set_cache read off
14067         set_cache writethrough off
14068         test_155_big_load
14069         restore_lustre_params < $p
14070         rm -f $p
14071 }
14072 run_test 155h "Verify big file correctness: read cache:off write_cache:off"
14073
14074 test_156() {
14075         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14076         remote_ost_nodsh && skip "remote OST with nodsh"
14077         [ $OST1_VERSION -lt $(version_code 2.6.93) ] &&
14078                 skip "stats not implemented on old servers"
14079         [ "$ost1_FSTYPE" = "zfs" ] &&
14080                 skip "LU-1956/LU-2261: stats not implemented on OSD ZFS"
14081
14082         local CPAGES=3
14083         local BEFORE
14084         local AFTER
14085         local file="$DIR/$tfile"
14086         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
14087
14088         save_writethrough $p
14089         roc_hit_init
14090
14091         log "Turn on read and write cache"
14092         set_cache read on
14093         set_cache writethrough on
14094
14095         log "Write data and read it back."
14096         log "Read should be satisfied from the cache."
14097         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
14098         BEFORE=$(roc_hit)
14099         cancel_lru_locks osc
14100         cat $file >/dev/null
14101         AFTER=$(roc_hit)
14102         if ! let "AFTER - BEFORE == CPAGES"; then
14103                 error "NOT IN CACHE (2): before: $BEFORE, after: $AFTER"
14104         else
14105                 log "cache hits: before: $BEFORE, after: $AFTER"
14106         fi
14107
14108         log "Read again; it should be satisfied from the cache."
14109         BEFORE=$AFTER
14110         cancel_lru_locks osc
14111         cat $file >/dev/null
14112         AFTER=$(roc_hit)
14113         if ! let "AFTER - BEFORE == CPAGES"; then
14114                 error "NOT IN CACHE (3): before: $BEFORE, after: $AFTER"
14115         else
14116                 log "cache hits:: before: $BEFORE, after: $AFTER"
14117         fi
14118
14119         log "Turn off the read cache and turn on the write cache"
14120         set_cache read off
14121         set_cache writethrough on
14122
14123         log "Read again; it should be satisfied from the cache."
14124         BEFORE=$(roc_hit)
14125         cancel_lru_locks osc
14126         cat $file >/dev/null
14127         AFTER=$(roc_hit)
14128         if ! let "AFTER - BEFORE == CPAGES"; then
14129                 error "NOT IN CACHE (4): before: $BEFORE, after: $AFTER"
14130         else
14131                 log "cache hits:: before: $BEFORE, after: $AFTER"
14132         fi
14133
14134         if [ $OST1_VERSION -lt $(version_code 2.12.55) ]; then
14135                 # > 2.12.56 uses pagecache if cached
14136                 log "Read again; it should not be satisfied from the cache."
14137                 BEFORE=$AFTER
14138                 cancel_lru_locks osc
14139                 cat $file >/dev/null
14140                 AFTER=$(roc_hit)
14141                 if ! let "AFTER - BEFORE == 0"; then
14142                         error "IN CACHE (5): before: $BEFORE, after: $AFTER"
14143                 else
14144                         log "cache hits:: before: $BEFORE, after: $AFTER"
14145                 fi
14146         fi
14147
14148         log "Write data and read it back."
14149         log "Read should be satisfied from the cache."
14150         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
14151         BEFORE=$(roc_hit)
14152         cancel_lru_locks osc
14153         cat $file >/dev/null
14154         AFTER=$(roc_hit)
14155         if ! let "AFTER - BEFORE == CPAGES"; then
14156                 error "NOT IN CACHE (6): before: $BEFORE, after: $AFTER"
14157         else
14158                 log "cache hits:: before: $BEFORE, after: $AFTER"
14159         fi
14160
14161         if [ $OST1_VERSION -lt $(version_code 2.12.55) ]; then
14162                 # > 2.12.56 uses pagecache if cached
14163                 log "Read again; it should not be satisfied from the cache."
14164                 BEFORE=$AFTER
14165                 cancel_lru_locks osc
14166                 cat $file >/dev/null
14167                 AFTER=$(roc_hit)
14168                 if ! let "AFTER - BEFORE == 0"; then
14169                         error "IN CACHE (7): before: $BEFORE, after: $AFTER"
14170                 else
14171                         log "cache hits:: before: $BEFORE, after: $AFTER"
14172                 fi
14173         fi
14174
14175         log "Turn off read and write cache"
14176         set_cache read off
14177         set_cache writethrough off
14178
14179         log "Write data and read it back"
14180         log "It should not be satisfied from the cache."
14181         rm -f $file
14182         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
14183         cancel_lru_locks osc
14184         BEFORE=$(roc_hit)
14185         cat $file >/dev/null
14186         AFTER=$(roc_hit)
14187         if ! let "AFTER - BEFORE == 0"; then
14188                 error_ignore bz20762 "IN CACHE (8):before:$BEFORE,after:$AFTER"
14189         else
14190                 log "cache hits:: before: $BEFORE, after: $AFTER"
14191         fi
14192
14193         log "Turn on the read cache and turn off the write cache"
14194         set_cache read on
14195         set_cache writethrough off
14196
14197         log "Write data and read it back"
14198         log "It should not be satisfied from the cache."
14199         rm -f $file
14200         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
14201         BEFORE=$(roc_hit)
14202         cancel_lru_locks osc
14203         cat $file >/dev/null
14204         AFTER=$(roc_hit)
14205         if ! let "AFTER - BEFORE == 0"; then
14206                 error_ignore bz20762 "IN CACHE (9):before:$BEFORE,after:$AFTER"
14207         else
14208                 log "cache hits:: before: $BEFORE, after: $AFTER"
14209         fi
14210
14211         log "Read again; it should be satisfied from the cache."
14212         BEFORE=$(roc_hit)
14213         cancel_lru_locks osc
14214         cat $file >/dev/null
14215         AFTER=$(roc_hit)
14216         if ! let "AFTER - BEFORE == CPAGES"; then
14217                 error "NOT IN CACHE (1): before: $BEFORE, after: $AFTER"
14218         else
14219                 log "cache hits:: before: $BEFORE, after: $AFTER"
14220         fi
14221
14222         restore_lustre_params < $p
14223         rm -f $p $file
14224 }
14225 run_test 156 "Verification of tunables"
14226
14227 test_160a() {
14228         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14229         remote_mds_nodsh && skip "remote MDS with nodsh"
14230         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] ||
14231                 skip "Need MDS version at least 2.2.0"
14232
14233         changelog_register || error "changelog_register failed"
14234         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
14235         changelog_users $SINGLEMDS | grep -q $cl_user ||
14236                 error "User $cl_user not found in changelog_users"
14237
14238         # change something
14239         test_mkdir -p $DIR/$tdir/pics/2008/zachy
14240         changelog_clear 0 || error "changelog_clear failed"
14241         touch $DIR/$tdir/pics/2008/zachy/$tfile                 # open 1
14242         cp /etc/hosts $DIR/$tdir/pics/2008/zachy/pic1.jpg       # open 2
14243         mv $DIR/$tdir/pics/2008/zachy $DIR/$tdir/pics/zach
14244         ln $DIR/$tdir/pics/zach/pic1.jpg $DIR/$tdir/pics/2008/portland.jpg
14245         ln -s $DIR/$tdir/pics/2008/portland.jpg $DIR/$tdir/pics/desktop.jpg
14246         rm $DIR/$tdir/pics/desktop.jpg
14247
14248         changelog_dump | tail -10
14249
14250         echo "verifying changelog mask"
14251         changelog_chmask "-MKDIR"
14252         changelog_chmask "-CLOSE"
14253
14254         test_mkdir -p $DIR/$tdir/pics/zach/sofia                # not logged
14255         echo "zzzzzz" > $DIR/$tdir/pics/zach/file               # not logged
14256
14257         changelog_chmask "+MKDIR"
14258         changelog_chmask "+CLOSE"
14259
14260         test_mkdir -p $DIR/$tdir/pics/2008/sofia                # mkdir 1
14261         echo "zzzzzz" > $DIR/$tdir/pics/zach/file               # open 3
14262
14263         changelog_dump | tail -10
14264         MKDIRS=$(changelog_dump | grep -c "MKDIR")
14265         CLOSES=$(changelog_dump | grep -c "CLOSE")
14266         [ $MKDIRS -eq 1 ] || error "MKDIR changelog mask count $MKDIRS != 1"
14267         [ $CLOSES -eq 3 ] || error "CLOSE changelog mask count $CLOSES != 3"
14268
14269         # verify contents
14270         echo "verifying target fid"
14271         local fidc=$(changelog_extract_field "CREAT" "$tfile" "t=")
14272         local fidf=$($LFS path2fid $DIR/$tdir/pics/zach/$tfile)
14273         [ "$fidc" == "$fidf" ] ||
14274                 error "changelog '$tfile' fid $fidc != file fid $fidf"
14275         echo "verifying parent fid"
14276         # The FID returned from the Changelog may be the directory shard on
14277         # a different MDT, and not the FID returned by path2fid on the parent.
14278         # Instead of comparing FIDs, verify that fid2path(fidp) is correct,
14279         # since this is what will matter when recreating this file in the tree.
14280         local fidp=$(changelog_extract_field "CREAT" "$tfile" "p=")
14281         local pathp=$($LFS fid2path $MOUNT "$fidp")
14282         [ "${pathp%/}" == "$DIR/$tdir/pics/zach" ] ||
14283                 error "changelog fid2path($fidc) $pathp != $DIR/$tdir/pics/zach"
14284
14285         echo "getting records for $cl_user"
14286         changelog_users $SINGLEMDS
14287         local user_rec1=$(changelog_user_rec $SINGLEMDS $cl_user)
14288         local nclr=3
14289         __changelog_clear $SINGLEMDS $cl_user +$nclr ||
14290                 error "changelog_clear failed"
14291         local user_rec2=$(changelog_user_rec $SINGLEMDS $cl_user)
14292         echo "verifying user clear: $user_rec1 + $nclr == $user_rec2"
14293         [ $user_rec2 == $((user_rec1 + nclr)) ] ||
14294                 error "user index expect $user_rec1 + $nclr != $user_rec2"
14295
14296         local min0_rec=$(changelog_users $SINGLEMDS |
14297                 awk 'min == "" || $2 < min { min = $2 }; END { print min }')
14298         local first_rec=$($LFS changelog $(facet_svc $SINGLEMDS) |
14299                           awk '{ print $1; exit; }')
14300
14301         changelog_dump | tail -n 5
14302         echo "verifying user min purge: $min0_rec + 1 == $first_rec"
14303         [ $first_rec == $((min0_rec + 1)) ] ||
14304                 error "first index should be $min0_rec + 1 not $first_rec"
14305
14306         # LU-3446 changelog index reset on MDT restart
14307         local cur_rec1=$(changelog_users $SINGLEMDS |
14308                          awk '/^current.index:/ { print $NF }')
14309         changelog_clear 0 ||
14310                 error "clear all changelog records for $cl_user failed"
14311         stop $SINGLEMDS || error "Fail to stop $SINGLEMDS"
14312         start $SINGLEMDS $(mdsdevname ${SINGLEMDS//mds/}) $MDS_MOUNT_OPTS ||
14313                 error "Fail to start $SINGLEMDS"
14314         local cur_rec2=$(changelog_users $SINGLEMDS |
14315                          awk '/^current.index:/ { print $NF }')
14316         echo "verifying index survives MDT restart: $cur_rec1 == $cur_rec2"
14317         [ $cur_rec1 == $cur_rec2 ] ||
14318                 error "current index should be $cur_rec1 not $cur_rec2"
14319
14320         echo "verifying users from this test are deregistered"
14321         changelog_deregister || error "changelog_deregister failed"
14322         changelog_users $SINGLEMDS | grep -q $cl_user &&
14323                 error "User '$cl_user' still in changelog_users"
14324
14325         # lctl get_param -n mdd.*.changelog_users
14326         # current index: 144
14327         # ID    index (idle seconds)
14328         # cl3   144 (2)
14329         if ! changelog_users $SINGLEMDS | grep "^cl"; then
14330                 # this is the normal case where all users were deregistered
14331                 # make sure no new records are added when no users are present
14332                 local last_rec1=$(changelog_users $SINGLEMDS |
14333                                   awk '/^current.index:/ { print $NF }')
14334                 touch $DIR/$tdir/chloe
14335                 local last_rec2=$(changelog_users $SINGLEMDS |
14336                                   awk '/^current.index:/ { print $NF }')
14337                 echo "verify changelogs are off: $last_rec1 == $last_rec2"
14338                 [ $last_rec1 == $last_rec2 ] || error "changelogs not off"
14339         else
14340                 # any changelog users must be leftovers from a previous test
14341                 changelog_users $SINGLEMDS
14342                 echo "other changelog users; can't verify off"
14343         fi
14344 }
14345 run_test 160a "changelog sanity"
14346
14347 test_160b() { # LU-3587
14348         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14349         remote_mds_nodsh && skip "remote MDS with nodsh"
14350         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] ||
14351                 skip "Need MDS version at least 2.2.0"
14352
14353         changelog_register || error "changelog_register failed"
14354         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
14355         changelog_users $SINGLEMDS | grep -q $cl_user ||
14356                 error "User '$cl_user' not found in changelog_users"
14357
14358         local longname1=$(str_repeat a 255)
14359         local longname2=$(str_repeat b 255)
14360
14361         cd $DIR
14362         echo "creating very long named file"
14363         touch $longname1 || error "create of '$longname1' failed"
14364         echo "renaming very long named file"
14365         mv $longname1 $longname2
14366
14367         changelog_dump | grep RENME | tail -n 5
14368         rm -f $longname2
14369 }
14370 run_test 160b "Verify that very long rename doesn't crash in changelog"
14371
14372 test_160c() {
14373         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14374         remote_mds_nodsh && skip "remote MDS with nodsh"
14375
14376         [[ $MDS1_VERSION -gt $(version_code 2.5.57) ]] ||
14377                 [[ $MDS1_VERSION -gt $(version_code 2.5.1) &&
14378                    $MDS1_VERSION -lt $(version_code 2.5.50) ]] ||
14379                 skip "Need MDS version at least 2.5.58 or 2.5.2+"
14380
14381         local rc=0
14382
14383         # Registration step
14384         changelog_register || error "changelog_register failed"
14385
14386         rm -rf $DIR/$tdir
14387         mkdir -p $DIR/$tdir
14388         $MCREATE $DIR/$tdir/foo_160c
14389         changelog_chmask "-TRUNC"
14390         $TRUNCATE $DIR/$tdir/foo_160c 200
14391         changelog_chmask "+TRUNC"
14392         $TRUNCATE $DIR/$tdir/foo_160c 199
14393         changelog_dump | tail -n 5
14394         local truncs=$(changelog_dump | tail -n 5 | grep -c TRUNC)
14395         [ $truncs -eq 1 ] || error "TRUNC changelog mask count $truncs != 1"
14396 }
14397 run_test 160c "verify that changelog log catch the truncate event"
14398
14399 test_160d() {
14400         remote_mds_nodsh && skip "remote MDS with nodsh"
14401         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
14402         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14403         [[ $MDS1_VERSION -ge $(version_code 2.7.60) ]] ||
14404                 skip "Need MDS version at least 2.7.60"
14405
14406         # Registration step
14407         changelog_register || error "changelog_register failed"
14408
14409         mkdir -p $DIR/$tdir/migrate_dir
14410         changelog_clear 0 || error "changelog_clear failed"
14411
14412         $LFS migrate -m 1 $DIR/$tdir/migrate_dir || error "migrate fails"
14413         changelog_dump | tail -n 5
14414         local migrates=$(changelog_dump | grep -c "MIGRT")
14415         [ $migrates -eq 1 ] || error "MIGRATE changelog count $migrates != 1"
14416 }
14417 run_test 160d "verify that changelog log catch the migrate event"
14418
14419 test_160e() {
14420         remote_mds_nodsh && skip "remote MDS with nodsh"
14421
14422         # Create a user
14423         changelog_register || error "changelog_register failed"
14424
14425         # Delete a future user (expect fail)
14426         local MDT0=$(facet_svc $SINGLEMDS)
14427         do_facet $SINGLEMDS $LCTL --device $MDT0 changelog_deregister "cl77"
14428         local rc=$?
14429
14430         if [ $rc -eq 0 ]; then
14431                 error "Deleted non-existant user cl77"
14432         elif [ $rc -ne 2 ]; then
14433                 error "changelog_deregister failed with $rc, expect 2 (ENOENT)"
14434         fi
14435
14436         # Clear to a bad index (1 billion should be safe)
14437         $LFS changelog_clear $MDT0 "${CL_USERS[$SINGLEMDS]%% *}" 1000000000
14438         rc=$?
14439
14440         if [ $rc -eq 0 ]; then
14441                 error "Successfully cleared to invalid CL index"
14442         elif [ $rc -ne 22 ]; then
14443                 error "changelog_clear failed with $rc, expected 22 (EINVAL)"
14444         fi
14445 }
14446 run_test 160e "changelog negative testing (should return errors)"
14447
14448 test_160f() {
14449         remote_mds_nodsh && skip "remote MDS with nodsh" && return
14450         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
14451                 skip "Need MDS version at least 2.10.56"
14452
14453         local mdts=$(comma_list $(mdts_nodes))
14454
14455         # Create a user
14456         changelog_register || error "first changelog_register failed"
14457         changelog_register || error "second changelog_register failed"
14458         local cl_users
14459         declare -A cl_user1
14460         declare -A cl_user2
14461         local user_rec1
14462         local user_rec2
14463         local i
14464
14465         # generate some changelog records to accumulate on each MDT
14466         # use fnv1a because created files should be evenly distributed
14467         test_mkdir -c $MDSCOUNT -H fnv_1a_64 $DIR/$tdir ||
14468                 error "test_mkdir $tdir failed"
14469         log "$(date +%s): creating first files"
14470         createmany -m $DIR/$tdir/$tfile $((MDSCOUNT * 2)) ||
14471                 error "create $DIR/$tdir/$tfile failed"
14472
14473         # check changelogs have been generated
14474         local start=$SECONDS
14475         local idle_time=$((MDSCOUNT * 5 + 5))
14476         local nbcl=$(changelog_dump | wc -l)
14477         [[ $nbcl -eq 0 ]] && error "no changelogs found"
14478
14479         for param in "changelog_max_idle_time=$idle_time" \
14480                      "changelog_gc=1" \
14481                      "changelog_min_gc_interval=2" \
14482                      "changelog_min_free_cat_entries=3"; do
14483                 local MDT0=$(facet_svc $SINGLEMDS)
14484                 local var="${param%=*}"
14485                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
14486
14487                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
14488                 do_nodes $mdts $LCTL set_param mdd.*.$param
14489         done
14490
14491         # force cl_user2 to be idle (1st part), but also cancel the
14492         # cl_user1 records so that it is not evicted later in the test.
14493         local sleep1=$((idle_time / 2))
14494         echo "$(date +%s): sleep1 $sleep1/${idle_time}s"
14495         sleep $sleep1
14496
14497         # simulate changelog catalog almost full
14498         #define OBD_FAIL_CAT_FREE_RECORDS       0x1313
14499         do_nodes $mdts $LCTL set_param fail_loc=0x1313 fail_val=3
14500
14501         for i in $(seq $MDSCOUNT); do
14502                 cl_users=(${CL_USERS[mds$i]})
14503                 cl_user1[mds$i]="${cl_users[0]}"
14504                 cl_user2[mds$i]="${cl_users[1]}"
14505
14506                 [ -n "${cl_user1[mds$i]}" ] ||
14507                         error "mds$i: no user registered"
14508                 [ -n "${cl_user2[mds$i]}" ] ||
14509                         error "mds$i: only ${cl_user2[mds$i]} is registered"
14510
14511                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
14512                 [ -n "$user_rec1" ] ||
14513                         error "mds$i: User ${cl_user1[mds$i]} not registered"
14514                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
14515                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
14516                 [ -n "$user_rec2" ] ||
14517                         error "mds$i: User ${cl_user1[mds$i]} not registered"
14518                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
14519                      "$user_rec1 + 2 == $user_rec2"
14520                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
14521                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
14522                               "$user_rec1 + 2, but is $user_rec2"
14523                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
14524                 [ -n "$user_rec2" ] ||
14525                         error "mds$i: User ${cl_user2[mds$i]} not registered"
14526                 [ $user_rec1 == $user_rec2 ] ||
14527                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
14528                               "$user_rec1, but is $user_rec2"
14529         done
14530
14531         # force cl_user2 idle (2nd part) to just exceed changelog_max_idle_time
14532         local sleep2=$((idle_time - (SECONDS - start) + 1))
14533         echo "$(date +%s): sleep2 $sleep2/${idle_time}s"
14534         sleep $sleep2
14535
14536         # Generate one more changelog to trigger GC at fail_loc for cl_user2.
14537         # cl_user1 should be OK because it recently processed records.
14538         echo "$(date +%s): creating $((MDSCOUNT * 2)) files"
14539         createmany -m $DIR/$tdir/${tfile}b $((MDSCOUNT * 2)) ||
14540                 error "create $DIR/$tdir/${tfile}b failed"
14541
14542         # ensure gc thread is done
14543         for i in $(mdts_nodes); do
14544                 wait_update $i \
14545                         "ps -e -o comm= | grep chlg_gc_thread" "" 20 ||
14546                         error "$i: GC-thread not done"
14547         done
14548
14549         local first_rec
14550         for i in $(seq $MDSCOUNT); do
14551                 # check cl_user1 still registered
14552                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
14553                         error "mds$i: User ${cl_user1[mds$i]} not registered"
14554                 # check cl_user2 unregistered
14555                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
14556                         error "mds$i: User ${cl_user2[mds$i]} still registered"
14557
14558                 # check changelogs are present and starting at $user_rec1 + 1
14559                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
14560                 [ -n "$user_rec1" ] ||
14561                         error "mds$i: User ${cl_user1[mds$i]} not registered"
14562                 first_rec=$($LFS changelog $(facet_svc mds$i) |
14563                             awk '{ print $1; exit; }')
14564
14565                 echo "mds$i: verifying first index $user_rec1 + 1 == $first_rec"
14566                 [ $((user_rec1 + 1)) == $first_rec ] ||
14567                         error "mds$i: first index should be $user_rec1 + 1, " \
14568                               "but is $first_rec"
14569         done
14570 }
14571 run_test 160f "changelog garbage collect (timestamped users)"
14572
14573 test_160g() {
14574         remote_mds_nodsh && skip "remote MDS with nodsh"
14575         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
14576                 skip "Need MDS version at least 2.10.56"
14577
14578         local mdts=$(comma_list $(mdts_nodes))
14579
14580         #define OBD_FAIL_TIME_IN_CHLOG_USER     0x1314
14581         do_nodes $mdts $LCTL set_param fail_loc=0x1314
14582
14583         # Create a user
14584         changelog_register || error "first changelog_register failed"
14585         changelog_register || error "second changelog_register failed"
14586         local cl_users
14587         declare -A cl_user1
14588         declare -A cl_user2
14589         local user_rec1
14590         local user_rec2
14591         local i
14592
14593         # generate some changelog records to accumulate on each MDT
14594         # use fnv1a because created files should be evenly distributed
14595         test_mkdir -c $MDSCOUNT -H fnv_1a_64 $DIR/$tdir ||
14596                 error "mkdir $tdir failed"
14597         createmany -m $DIR/$tdir/$tfile $((MDSCOUNT * 2)) ||
14598                 error "create $DIR/$tdir/$tfile failed"
14599
14600         # check changelogs have been generated
14601         local nbcl=$(changelog_dump | wc -l)
14602         [[ $nbcl -eq 0 ]] && error "no changelogs found"
14603
14604         # reduce the max_idle_indexes value to make sure we exceed it
14605         max_ndx=$((nbcl / 2 - 1))
14606
14607         for param in "changelog_max_idle_indexes=$max_ndx" \
14608                      "changelog_gc=1" \
14609                      "changelog_min_gc_interval=2" \
14610                      "changelog_min_free_cat_entries=3"; do
14611                 local MDT0=$(facet_svc $SINGLEMDS)
14612                 local var="${param%=*}"
14613                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
14614
14615                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
14616                 do_nodes $mdts $LCTL set_param mdd.*.$param ||
14617                         error "unable to set mdd.*.$param"
14618         done
14619
14620         # simulate changelog catalog almost full
14621         #define OBD_FAIL_CAT_FREE_RECORDS       0x1313
14622         do_nodes $mdts $LCTL set_param fail_loc=0x1313 fail_val=3
14623
14624         for i in $(seq $MDSCOUNT); do
14625                 cl_users=(${CL_USERS[mds$i]})
14626                 cl_user1[mds$i]="${cl_users[0]}"
14627                 cl_user2[mds$i]="${cl_users[1]}"
14628
14629                 [ -n "${cl_user1[mds$i]}" ] ||
14630                         error "mds$i: no user registered"
14631                 [ -n "${cl_user2[mds$i]}" ] ||
14632                         error "mds$i: only ${cl_user1[mds$i]} is registered"
14633
14634                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
14635                 [ -n "$user_rec1" ] ||
14636                         error "mds$i: User ${cl_user1[mds$i]} not registered"
14637                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
14638                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
14639                 [ -n "$user_rec2" ] ||
14640                         error "mds$i: User ${cl_user1[mds$i]} not registered"
14641                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
14642                      "$user_rec1 + 2 == $user_rec2"
14643                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
14644                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
14645                               "$user_rec1 + 2, but is $user_rec2"
14646                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
14647                 [ -n "$user_rec2" ] ||
14648                         error "mds$i: User ${cl_user2[mds$i]} not registered"
14649                 [ $user_rec1 == $user_rec2 ] ||
14650                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
14651                               "$user_rec1, but is $user_rec2"
14652         done
14653
14654         # ensure we are past the previous changelog_min_gc_interval set above
14655         sleep 2
14656
14657         # generate one more changelog to trigger fail_loc
14658         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
14659                 error "create $DIR/$tdir/${tfile}bis failed"
14660
14661         # ensure gc thread is done
14662         for i in $(mdts_nodes); do
14663                 wait_update $i \
14664                         "ps -e -o comm= | grep chlg_gc_thread" "" 20 ||
14665                         error "$i: GC-thread not done"
14666         done
14667
14668         local first_rec
14669         for i in $(seq $MDSCOUNT); do
14670                 # check cl_user1 still registered
14671                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
14672                         error "mds$i: User ${cl_user1[mds$i]} not registered"
14673                 # check cl_user2 unregistered
14674                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
14675                         error "mds$i: User ${cl_user2[mds$i]} still registered"
14676
14677                 # check changelogs are present and starting at $user_rec1 + 1
14678                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
14679                 [ -n "$user_rec1" ] ||
14680                         error "mds$i: User ${cl_user1[mds$i]} not registered"
14681                 first_rec=$($LFS changelog $(facet_svc mds$i) |
14682                             awk '{ print $1; exit; }')
14683
14684                 echo "mds$i: verifying first index $user_rec1 + 1 == $first_rec"
14685                 [ $((user_rec1 + 1)) == $first_rec ] ||
14686                         error "mds$i: first index should be $user_rec1 + 1, " \
14687                               "but is $first_rec"
14688         done
14689 }
14690 run_test 160g "changelog garbage collect (old users)"
14691
14692 test_160h() {
14693         remote_mds_nodsh && skip "remote MDS with nodsh" && return
14694         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
14695                 skip "Need MDS version at least 2.10.56"
14696
14697         local mdts=$(comma_list $(mdts_nodes))
14698
14699         # Create a user
14700         changelog_register || error "first changelog_register failed"
14701         changelog_register || error "second changelog_register failed"
14702         local cl_users
14703         declare -A cl_user1
14704         declare -A cl_user2
14705         local user_rec1
14706         local user_rec2
14707         local i
14708
14709         # generate some changelog records to accumulate on each MDT
14710         # use fnv1a because created files should be evenly distributed
14711         test_mkdir -c $MDSCOUNT -H fnv_1a_64 $DIR/$tdir ||
14712                 error "test_mkdir $tdir failed"
14713         createmany -m $DIR/$tdir/$tfile $((MDSCOUNT * 2)) ||
14714                 error "create $DIR/$tdir/$tfile failed"
14715
14716         # check changelogs have been generated
14717         local nbcl=$(changelog_dump | wc -l)
14718         [[ $nbcl -eq 0 ]] && error "no changelogs found"
14719
14720         for param in "changelog_max_idle_time=10" \
14721                      "changelog_gc=1" \
14722                      "changelog_min_gc_interval=2"; do
14723                 local MDT0=$(facet_svc $SINGLEMDS)
14724                 local var="${param%=*}"
14725                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
14726
14727                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
14728                 do_nodes $mdts $LCTL set_param mdd.*.$param
14729         done
14730
14731         # force cl_user2 to be idle (1st part)
14732         sleep 9
14733
14734         for i in $(seq $MDSCOUNT); do
14735                 cl_users=(${CL_USERS[mds$i]})
14736                 cl_user1[mds$i]="${cl_users[0]}"
14737                 cl_user2[mds$i]="${cl_users[1]}"
14738
14739                 [ -n "${cl_user1[mds$i]}" ] ||
14740                         error "mds$i: no user registered"
14741                 [ -n "${cl_user2[mds$i]}" ] ||
14742                         error "mds$i: only ${cl_user2[mds$i]} is registered"
14743
14744                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
14745                 [ -n "$user_rec1" ] ||
14746                         error "mds$i: User ${cl_user1[mds$i]} not registered"
14747                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
14748                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
14749                 [ -n "$user_rec2" ] ||
14750                         error "mds$i: User ${cl_user1[mds$i]} not registered"
14751                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
14752                      "$user_rec1 + 2 == $user_rec2"
14753                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
14754                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
14755                               "$user_rec1 + 2, but is $user_rec2"
14756                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
14757                 [ -n "$user_rec2" ] ||
14758                         error "mds$i: User ${cl_user2[mds$i]} not registered"
14759                 [ $user_rec1 == $user_rec2 ] ||
14760                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
14761                               "$user_rec1, but is $user_rec2"
14762         done
14763
14764         # force cl_user2 to be idle (2nd part) and to reach
14765         # changelog_max_idle_time
14766         sleep 2
14767
14768         # force each GC-thread start and block then
14769         # one per MDT/MDD, set fail_val accordingly
14770         #define OBD_FAIL_FORCE_GC_THREAD 0x1316
14771         do_nodes $mdts $LCTL set_param fail_loc=0x1316
14772
14773         # generate more changelogs to trigger fail_loc
14774         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
14775                 error "create $DIR/$tdir/${tfile}bis failed"
14776
14777         # stop MDT to stop GC-thread, should be done in back-ground as it will
14778         # block waiting for the thread to be released and exit
14779         declare -A stop_pids
14780         for i in $(seq $MDSCOUNT); do
14781                 stop mds$i &
14782                 stop_pids[mds$i]=$!
14783         done
14784
14785         for i in $(mdts_nodes); do
14786                 local facet
14787                 local nb=0
14788                 local facets=$(facets_up_on_host $i)
14789
14790                 for facet in ${facets//,/ }; do
14791                         if [[ $facet == mds* ]]; then
14792                                 nb=$((nb + 1))
14793                         fi
14794                 done
14795                 # ensure each MDS's gc threads are still present and all in "R"
14796                 # state (OBD_FAIL_FORCE_GC_THREAD effect!)
14797                 [[ $(do_node $i pgrep chlg_gc_thread | wc -l) -eq $nb ]] ||
14798                         error "$i: expected $nb GC-thread"
14799                 wait_update $i \
14800                         "ps -C chlg_gc_thread -o state --no-headers | uniq" \
14801                         "R" 20 ||
14802                         error "$i: GC-thread not found in R-state"
14803                 # check umounts of each MDT on MDS have reached kthread_stop()
14804                 [[ $(do_node $i pgrep umount | wc -l) -eq $nb ]] ||
14805                         error "$i: expected $nb umount"
14806                 wait_update $i \
14807                         "ps -C umount -o state --no-headers | uniq" "D" 20 ||
14808                         error "$i: umount not found in D-state"
14809         done
14810
14811         # release all GC-threads
14812         do_nodes $mdts $LCTL set_param fail_loc=0
14813
14814         # wait for MDT stop to complete
14815         for i in $(seq $MDSCOUNT); do
14816                 wait ${stop_pids[mds$i]} || error "mds$i: stop failed"
14817         done
14818
14819         # XXX
14820         # may try to check if any orphan changelog records are present
14821         # via ldiskfs/zfs and llog_reader...
14822
14823         # re-start/mount MDTs
14824         for i in $(seq $MDSCOUNT); do
14825                 start mds$i $(mdsdevname $i) $MDS_MOUNT_OPTS ||
14826                         error "Fail to start mds$i"
14827         done
14828
14829         local first_rec
14830         for i in $(seq $MDSCOUNT); do
14831                 # check cl_user1 still registered
14832                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
14833                         error "mds$i: User ${cl_user1[mds$i]} not registered"
14834                 # check cl_user2 unregistered
14835                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
14836                         error "mds$i: User ${cl_user2[mds$i]} still registered"
14837
14838                 # check changelogs are present and starting at $user_rec1 + 1
14839                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
14840                 [ -n "$user_rec1" ] ||
14841                         error "mds$i: User ${cl_user1[mds$i]} not registered"
14842                 first_rec=$($LFS changelog $(facet_svc mds$i) |
14843                             awk '{ print $1; exit; }')
14844
14845                 echo "mds$i: verifying first index $user_rec1 + 1 == $first_rec"
14846                 [ $((user_rec1 + 1)) == $first_rec ] ||
14847                         error "mds$i: first index should be $user_rec1 + 1, " \
14848                               "but is $first_rec"
14849         done
14850 }
14851 run_test 160h "changelog gc thread stop upon umount, orphan records delete " \
14852               "during mount"
14853
14854 test_160i() {
14855
14856         local mdts=$(comma_list $(mdts_nodes))
14857
14858         changelog_register || error "first changelog_register failed"
14859
14860         # generate some changelog records to accumulate on each MDT
14861         # use fnv1a because created files should be evenly distributed
14862         test_mkdir -c $MDSCOUNT -H fnv_1a_64 $DIR/$tdir ||
14863                 error "mkdir $tdir failed"
14864         createmany -m $DIR/$tdir/$tfile $((MDSCOUNT * 2)) ||
14865                 error "create $DIR/$tdir/$tfile failed"
14866
14867         # check changelogs have been generated
14868         local nbcl=$(changelog_dump | wc -l)
14869         [[ $nbcl -eq 0 ]] && error "no changelogs found"
14870
14871         # simulate race between register and unregister
14872         # XXX as fail_loc is set per-MDS, with DNE configs the race
14873         # simulation will only occur for one MDT per MDS and for the
14874         # others the normal race scenario will take place
14875         #define CFS_FAIL_CHLOG_USER_REG_UNREG_RACE          0x1315
14876         do_nodes $mdts $LCTL set_param fail_loc=0x10001315
14877         do_nodes $mdts $LCTL set_param fail_val=1
14878
14879         # unregister 1st user
14880         changelog_deregister &
14881         local pid1=$!
14882         # wait some time for deregister work to reach race rdv
14883         sleep 2
14884         # register 2nd user
14885         changelog_register || error "2nd user register failed"
14886
14887         wait $pid1 || error "1st user deregister failed"
14888
14889         local i
14890         local last_rec
14891         declare -A LAST_REC
14892         for i in $(seq $MDSCOUNT); do
14893                 if changelog_users mds$i | grep "^cl"; then
14894                         # make sure new records are added with one user present
14895                         LAST_REC[mds$i]=$(changelog_users $SINGLEMDS |
14896                                           awk '/^current.index:/ { print $NF }')
14897                 else
14898                         error "mds$i has no user registered"
14899                 fi
14900         done
14901
14902         # generate more changelog records to accumulate on each MDT
14903         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
14904                 error "create $DIR/$tdir/${tfile}bis failed"
14905
14906         for i in $(seq $MDSCOUNT); do
14907                 last_rec=$(changelog_users $SINGLEMDS |
14908                            awk '/^current.index:/ { print $NF }')
14909                 echo "verify changelogs are on: $last_rec != ${LAST_REC[mds$i]}"
14910                 [ $last_rec != ${LAST_REC[mds$i]} ] ||
14911                         error "changelogs are off on mds$i"
14912         done
14913 }
14914 run_test 160i "changelog user register/unregister race"
14915
14916 test_160j() {
14917         remote_mds_nodsh && skip "remote MDS with nodsh"
14918         [[ $MDS1_VERSION -lt $(version_code 2.12.56) ]] &&
14919                 skip "Need MDS version at least 2.12.56"
14920
14921         mount_client $MOUNT2 || error "mount_client on $MOUNT2 failed"
14922         stack_trap "umount $MOUNT2" EXIT
14923
14924         changelog_register || error "first changelog_register failed"
14925         stack_trap "changelog_deregister" EXIT
14926
14927         # generate some changelog
14928         # use fnv1a because created files should be evenly distributed
14929         test_mkdir -c $MDSCOUNT -H fnv_1a_64 $DIR/$tdir ||
14930                 error "mkdir $tdir failed"
14931         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
14932                 error "create $DIR/$tdir/${tfile}bis failed"
14933
14934         # open the changelog device
14935         exec 3>/dev/changelog-$FSNAME-MDT0000
14936         stack_trap "exec 3>&-" EXIT
14937         exec 4</dev/changelog-$FSNAME-MDT0000
14938         stack_trap "exec 4<&-" EXIT
14939
14940         # umount the first lustre mount
14941         umount $MOUNT
14942         stack_trap "mount_client $MOUNT" EXIT
14943
14944         # read changelog
14945         cat <&4 >/dev/null || error "read changelog failed"
14946
14947         # clear changelog
14948         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
14949         changelog_users $SINGLEMDS | grep -q $cl_user ||
14950                 error "User $cl_user not found in changelog_users"
14951
14952         printf 'clear:'$cl_user':0' >&3
14953 }
14954 run_test 160j "client can be umounted  while its chanangelog is being used"
14955
14956 test_160k() {
14957         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14958         remote_mds_nodsh && skip "remote MDS with nodsh"
14959
14960         mkdir -p $DIR/$tdir/1/1
14961
14962         changelog_register || error "changelog_register failed"
14963         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
14964
14965         changelog_users $SINGLEMDS | grep -q $cl_user ||
14966                 error "User '$cl_user' not found in changelog_users"
14967 #define OBD_FAIL_MDS_CHANGELOG_REORDER 0x15d
14968         do_facet mds1 $LCTL set_param fail_loc=0x8000015d fail_val=3
14969         rmdir $DIR/$tdir/1/1 & sleep 1
14970         mkdir $DIR/$tdir/2
14971         touch $DIR/$tdir/2/2
14972         rm -rf $DIR/$tdir/2
14973
14974         wait
14975         sleep 4
14976
14977         changelog_dump | grep rmdir || error "rmdir not recorded"
14978
14979         rm -rf $DIR/$tdir
14980         changelog_deregister
14981 }
14982 run_test 160k "Verify that changelog records are not lost"
14983
14984 test_161a() {
14985         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14986
14987         test_mkdir -c1 $DIR/$tdir
14988         cp /etc/hosts $DIR/$tdir/$tfile
14989         test_mkdir -c1 $DIR/$tdir/foo1
14990         test_mkdir -c1 $DIR/$tdir/foo2
14991         ln $DIR/$tdir/$tfile $DIR/$tdir/foo1/sofia
14992         ln $DIR/$tdir/$tfile $DIR/$tdir/foo2/zachary
14993         ln $DIR/$tdir/$tfile $DIR/$tdir/foo1/luna
14994         ln $DIR/$tdir/$tfile $DIR/$tdir/foo2/thor
14995         local FID=$($LFS path2fid $DIR/$tdir/$tfile | tr -d '[]')
14996         if [ "$($LFS fid2path $DIR $FID | wc -l)" != "5" ]; then
14997                 $LFS fid2path $DIR $FID
14998                 error "bad link ea"
14999         fi
15000         # middle
15001         rm $DIR/$tdir/foo2/zachary
15002         # last
15003         rm $DIR/$tdir/foo2/thor
15004         # first
15005         rm $DIR/$tdir/$tfile
15006         # rename
15007         mv $DIR/$tdir/foo1/sofia $DIR/$tdir/foo2/maggie
15008         [ "$($LFS fid2path $FSNAME --link 1 $FID)" != "$tdir/foo2/maggie" ] &&
15009                 { $LFS fid2path $DIR $FID; error "bad link rename"; }
15010         rm $DIR/$tdir/foo2/maggie
15011
15012         # overflow the EA
15013         local longname=$tfile.avg_len_is_thirty_two_
15014         stack_trap "unlinkmany $DIR/$tdir/foo2/$longname 1000 || \
15015                 error_noexit 'failed to unlink many hardlinks'" EXIT
15016         createmany -l$DIR/$tdir/foo1/luna $DIR/$tdir/foo2/$longname 1000 ||
15017                 error "failed to hardlink many files"
15018         links=$($LFS fid2path $DIR $FID | wc -l)
15019         echo -n "${links}/1000 links in link EA"
15020         [[ $links -gt 60 ]] || error "expected at least 60 links in link EA"
15021 }
15022 run_test 161a "link ea sanity"
15023
15024 test_161b() {
15025         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15026         [ $MDSCOUNT -lt 2 ] && skip_env "skipping remote directory test"
15027
15028         local MDTIDX=1
15029         local remote_dir=$DIR/$tdir/remote_dir
15030
15031         mkdir -p $DIR/$tdir
15032         $LFS mkdir -i $MDTIDX $remote_dir ||
15033                 error "create remote directory failed"
15034
15035         cp /etc/hosts $remote_dir/$tfile
15036         mkdir -p $remote_dir/foo1
15037         mkdir -p $remote_dir/foo2
15038         ln $remote_dir/$tfile $remote_dir/foo1/sofia
15039         ln $remote_dir/$tfile $remote_dir/foo2/zachary
15040         ln $remote_dir/$tfile $remote_dir/foo1/luna
15041         ln $remote_dir/$tfile $remote_dir/foo2/thor
15042
15043         local FID=$($LFS path2fid $remote_dir/$tfile | tr -d '[' |
15044                      tr -d ']')
15045         if [ "$($LFS fid2path $DIR $FID | wc -l)" != "5" ]; then
15046                 $LFS fid2path $DIR $FID
15047                 error "bad link ea"
15048         fi
15049         # middle
15050         rm $remote_dir/foo2/zachary
15051         # last
15052         rm $remote_dir/foo2/thor
15053         # first
15054         rm $remote_dir/$tfile
15055         # rename
15056         mv $remote_dir/foo1/sofia $remote_dir/foo2/maggie
15057         local link_path=$($LFS fid2path $FSNAME --link 1 $FID)
15058         if [ "$DIR/$link_path" != "$remote_dir/foo2/maggie" ]; then
15059                 $LFS fid2path $DIR $FID
15060                 error "bad link rename"
15061         fi
15062         rm $remote_dir/foo2/maggie
15063
15064         # overflow the EA
15065         local longname=filename_avg_len_is_thirty_two_
15066         createmany -l$remote_dir/foo1/luna $remote_dir/foo2/$longname 1000 ||
15067                 error "failed to hardlink many files"
15068         links=$($LFS fid2path $DIR $FID | wc -l)
15069         echo -n "${links}/1000 links in link EA"
15070         [[ ${links} -gt 60 ]] ||
15071                 error "expected at least 60 links in link EA"
15072         unlinkmany $remote_dir/foo2/$longname 1000 ||
15073         error "failed to unlink many hardlinks"
15074 }
15075 run_test 161b "link ea sanity under remote directory"
15076
15077 test_161c() {
15078         remote_mds_nodsh && skip "remote MDS with nodsh"
15079         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15080         [[ $MDS1_VERSION -lt $(version_code 2.1.5) ]] &&
15081                 skip "Need MDS version at least 2.1.5"
15082
15083         # define CLF_RENAME_LAST 0x0001
15084         # rename overwrite a target having nlink = 1 (changelog flag 0x1)
15085         changelog_register || error "changelog_register failed"
15086
15087         rm -rf $DIR/$tdir
15088         test_mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir
15089         touch $DIR/$tdir/foo_161c
15090         touch $DIR/$tdir/bar_161c
15091         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/bar_161c
15092         changelog_dump | grep RENME | tail -n 5
15093         local flags=$(changelog_dump | grep "RENME.*bar_161c" | cut -f5 -d' ')
15094         changelog_clear 0 || error "changelog_clear failed"
15095         if [ x$flags != "x0x1" ]; then
15096                 error "flag $flags is not 0x1"
15097         fi
15098
15099         echo "rename overwrite target with nlink = 1, changelog flags=$flags"
15100         # rename overwrite a target having nlink > 1 (changelog flag 0x0)
15101         touch $DIR/$tdir/foo_161c
15102         touch $DIR/$tdir/bar_161c
15103         ln $DIR/$tdir/bar_161c $DIR/$tdir/foobar_161c
15104         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/bar_161c
15105         changelog_dump | grep RENME | tail -n 5
15106         flags=$(changelog_dump | grep "RENME.*bar_161c" | cut -f5 -d' ')
15107         changelog_clear 0 || error "changelog_clear failed"
15108         if [ x$flags != "x0x0" ]; then
15109                 error "flag $flags is not 0x0"
15110         fi
15111         echo "rename overwrite a target having nlink > 1," \
15112                 "changelog record has flags of $flags"
15113
15114         # rename doesn't overwrite a target (changelog flag 0x0)
15115         touch $DIR/$tdir/foo_161c
15116         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/foo2_161c
15117         changelog_dump | grep RENME | tail -n 5
15118         flags=$(changelog_dump | grep RENME | tail -1 | cut -f5 -d' ')
15119         changelog_clear 0 || error "changelog_clear failed"
15120         if [ x$flags != "x0x0" ]; then
15121                 error "flag $flags is not 0x0"
15122         fi
15123         echo "rename doesn't overwrite a target," \
15124                 "changelog record has flags of $flags"
15125
15126         # define CLF_UNLINK_LAST 0x0001
15127         # unlink a file having nlink = 1 (changelog flag 0x1)
15128         rm -f $DIR/$tdir/foo2_161c
15129         changelog_dump | grep UNLNK | tail -n 5
15130         flags=$(changelog_dump | grep UNLNK | tail -1 | cut -f5 -d' ')
15131         changelog_clear 0 || error "changelog_clear failed"
15132         if [ x$flags != "x0x1" ]; then
15133                 error "flag $flags is not 0x1"
15134         fi
15135         echo "unlink a file having nlink = 1," \
15136                 "changelog record has flags of $flags"
15137
15138         # unlink a file having nlink > 1 (changelog flag 0x0)
15139         ln -f $DIR/$tdir/bar_161c $DIR/$tdir/foobar_161c
15140         rm -f $DIR/$tdir/foobar_161c
15141         changelog_dump | grep UNLNK | tail -n 5
15142         flags=$(changelog_dump | grep UNLNK | tail -1 | cut -f5 -d' ')
15143         changelog_clear 0 || error "changelog_clear failed"
15144         if [ x$flags != "x0x0" ]; then
15145                 error "flag $flags is not 0x0"
15146         fi
15147         echo "unlink a file having nlink > 1, changelog record flags '$flags'"
15148 }
15149 run_test 161c "check CL_RENME[UNLINK] changelog record flags"
15150
15151 test_161d() {
15152         remote_mds_nodsh && skip "remote MDS with nodsh"
15153         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
15154
15155         local pid
15156         local fid
15157
15158         changelog_register || error "changelog_register failed"
15159
15160         # work in a standalone dir to avoid locking on $DIR/$MOUNT to
15161         # interfer with $MOUNT/.lustre/fid/ access
15162         mkdir $DIR/$tdir
15163         [[ $? -eq 0 ]] || error "mkdir failed"
15164
15165         #define OBD_FAIL_LLITE_CREATE_NODE_PAUSE 0x140c | OBD_FAIL_ONCE
15166         $LCTL set_param fail_loc=0x8000140c
15167         # 5s pause
15168         $LCTL set_param fail_val=5
15169
15170         # create file
15171         echo foofoo > $DIR/$tdir/$tfile &
15172         pid=$!
15173
15174         # wait for create to be delayed
15175         sleep 2
15176
15177         ps -p $pid
15178         [[ $? -eq 0 ]] || error "create should be blocked"
15179
15180         local tempfile="$(mktemp --tmpdir $tfile.XXXXXX)"
15181         stack_trap "rm -f $tempfile"
15182         fid=$(changelog_extract_field "CREAT" "$tfile" "t=")
15183         cat $MOUNT/.lustre/fid/$fid 2>/dev/null >$tempfile || error "cat failed"
15184         # some delay may occur during ChangeLog publishing and file read just
15185         # above, that could allow file write to happen finally
15186         [[ -s $tempfile ]] && echo "file should be empty"
15187
15188         $LCTL set_param fail_loc=0
15189
15190         wait $pid
15191         [[ $? -eq 0 ]] || error "create failed"
15192 }
15193 run_test 161d "create with concurrent .lustre/fid access"
15194
15195 check_path() {
15196         local expected="$1"
15197         shift
15198         local fid="$2"
15199
15200         local path
15201         path=$($LFS fid2path "$@")
15202         local rc=$?
15203
15204         if [ $rc -ne 0 ]; then
15205                 error "path looked up of '$expected' failed: rc=$rc"
15206         elif [ "$path" != "$expected" ]; then
15207                 error "path looked up '$path' instead of '$expected'"
15208         else
15209                 echo "FID '$fid' resolves to path '$path' as expected"
15210         fi
15211 }
15212
15213 test_162a() { # was test_162
15214         test_mkdir -p -c1 $DIR/$tdir/d2
15215         touch $DIR/$tdir/d2/$tfile
15216         touch $DIR/$tdir/d2/x1
15217         touch $DIR/$tdir/d2/x2
15218         test_mkdir -p -c1 $DIR/$tdir/d2/a/b/c
15219         test_mkdir -p -c1 $DIR/$tdir/d2/p/q/r
15220         # regular file
15221         local fid=$($LFS path2fid $DIR/$tdir/d2/$tfile | tr -d '[]')
15222         check_path "$tdir/d2/$tfile" $FSNAME "$fid" --link 0
15223
15224         # softlink
15225         ln -s $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/p/q/r/slink
15226         fid=$($LFS path2fid $DIR/$tdir/d2/p/q/r/slink | tr -d '[]')
15227         check_path "$tdir/d2/p/q/r/slink" $FSNAME "$fid" --link 0
15228
15229         # softlink to wrong file
15230         ln -s /this/is/garbage $DIR/$tdir/d2/p/q/r/slink.wrong
15231         fid=$($LFS path2fid $DIR/$tdir/d2/p/q/r/slink.wrong | tr -d '[]')
15232         check_path "$tdir/d2/p/q/r/slink.wrong" $FSNAME "$fid" --link 0
15233
15234         # hardlink
15235         ln $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/p/q/r/hlink
15236         mv $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/a/b/c/new_file
15237         fid=$($LFS path2fid $DIR/$tdir/d2/a/b/c/new_file | tr -d '[]')
15238         # fid2path dir/fsname should both work
15239         check_path "$tdir/d2/a/b/c/new_file" $FSNAME "$fid" --link 1
15240         check_path "$DIR/$tdir/d2/p/q/r/hlink" $DIR "$fid" --link 0
15241
15242         # hardlink count: check that there are 2 links
15243         local nlinks=$($LFS fid2path $DIR "$fid" | wc -l)
15244         [ $nlinks -eq 2 ] || error "expect 2 links, found $nlinks"
15245
15246         # hardlink indexing: remove the first link
15247         rm $DIR/$tdir/d2/p/q/r/hlink
15248         check_path "$tdir/d2/a/b/c/new_file" $FSNAME $fid --link 0
15249 }
15250 run_test 162a "path lookup sanity"
15251
15252 test_162b() {
15253         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15254         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
15255
15256         mkdir $DIR/$tdir
15257         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
15258                                 error "create striped dir failed"
15259
15260         local FID=$($LFS getdirstripe $DIR/$tdir/striped_dir |
15261                                         tail -n 1 | awk '{print $2}')
15262         stat $MOUNT/.lustre/fid/$FID && error "sub_stripe can be accessed"
15263
15264         touch $DIR/$tdir/striped_dir/f{0..4} || error "touch f0..4 failed"
15265         mkdir $DIR/$tdir/striped_dir/d{0..4} || error "mkdir d0..4 failed"
15266
15267         # regular file
15268         for ((i=0;i<5;i++)); do
15269                 FID=$($LFS path2fid $DIR/$tdir/striped_dir/f$i | tr -d '[]') ||
15270                         error "get fid for f$i failed"
15271                 check_path "$tdir/striped_dir/f$i" $FSNAME $FID --link 0
15272
15273                 FID=$($LFS path2fid $DIR/$tdir/striped_dir/d$i | tr -d '[]') ||
15274                         error "get fid for d$i failed"
15275                 check_path "$tdir/striped_dir/d$i" $FSNAME $FID --link 0
15276         done
15277
15278         return 0
15279 }
15280 run_test 162b "striped directory path lookup sanity"
15281
15282 # LU-4239: Verify fid2path works with paths 100 or more directories deep
15283 test_162c() {
15284         [[ $MDS1_VERSION -lt $(version_code 2.7.51) ]] &&
15285                 skip "Need MDS version at least 2.7.51"
15286
15287         local lpath=$tdir.local
15288         local rpath=$tdir.remote
15289
15290         test_mkdir $DIR/$lpath
15291         test_mkdir $DIR/$rpath
15292
15293         for ((i = 0; i <= 101; i++)); do
15294                 lpath="$lpath/$i"
15295                 mkdir $DIR/$lpath
15296                 FID=$($LFS path2fid $DIR/$lpath | tr -d '[]') ||
15297                         error "get fid for local directory $DIR/$lpath failed"
15298                 check_path "$DIR/$lpath" $MOUNT $FID --link 0
15299
15300                 rpath="$rpath/$i"
15301                 test_mkdir $DIR/$rpath
15302                 FID=$($LFS path2fid $DIR/$rpath | tr -d '[]') ||
15303                         error "get fid for remote directory $DIR/$rpath failed"
15304                 check_path "$DIR/$rpath" $MOUNT $FID --link 0
15305         done
15306
15307         return 0
15308 }
15309 run_test 162c "fid2path works with paths 100 or more directories deep"
15310
15311 oalr_event_count() {
15312         local event="${1}"
15313         local trace="${2}"
15314
15315         awk -v name="${FSNAME}-OST0000" \
15316             -v event="${event}" \
15317             '$1 == "TRACE" && $2 == event && $3 == name' \
15318             "${trace}" |
15319         wc -l
15320 }
15321
15322 oalr_expect_event_count() {
15323         local event="${1}"
15324         local trace="${2}"
15325         local expect="${3}"
15326         local count
15327
15328         count=$(oalr_event_count "${event}" "${trace}")
15329         if ((count == expect)); then
15330                 return 0
15331         fi
15332
15333         error_noexit "${event} event count was '${count}', expected ${expect}"
15334         cat "${trace}" >&2
15335         exit 1
15336 }
15337
15338 cleanup_165() {
15339         do_facet ost1 killall --quiet -KILL ofd_access_log_reader || true
15340         stop ost1
15341         start ost1 "$(ostdevname 1)" $OST_MOUNT_OPTS
15342 }
15343
15344 setup_165() {
15345         sync # Flush previous IOs so we can count log entries.
15346         do_facet ost1 $LCTL set_param "obdfilter.${FSNAME}-OST0000.access_log_size=4096"
15347         stack_trap cleanup_165 EXIT
15348 }
15349
15350 test_165a() {
15351         local trace="/tmp/${tfile}.trace"
15352         local rc
15353         local count
15354
15355         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
15356         setup_165
15357         sleep 5
15358
15359         do_facet ost1 ofd_access_log_reader --list
15360         stop ost1
15361
15362         do_facet ost1 killall -TERM ofd_access_log_reader
15363         wait
15364         rc=$?
15365
15366         if ((rc != 0)); then
15367                 error "ofd_access_log_reader exited with rc = '${rc}'"
15368         fi
15369
15370         # Parse trace file for discovery events:
15371         oalr_expect_event_count alr_log_add "${trace}" 1
15372         oalr_expect_event_count alr_log_eof "${trace}" 1
15373         oalr_expect_event_count alr_log_free "${trace}" 1
15374 }
15375 run_test 165a "ofd access log discovery"
15376
15377 test_165b() {
15378         local trace="/tmp/${tfile}.trace"
15379         local file="${DIR}/${tfile}"
15380         local pfid1
15381         local pfid2
15382         local -a entry
15383         local rc
15384         local count
15385         local size
15386         local flags
15387
15388         setup_165
15389
15390         lfs setstripe -c 1 -i 0 "${file}"
15391         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c || error "cannot create '${file}'"
15392         do_facet ost1 ofd_access_log_reader --list
15393
15394         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
15395         sleep 5
15396         do_facet ost1 killall -TERM ofd_access_log_reader
15397         wait
15398         rc=$?
15399
15400         if ((rc != 0)); then
15401                 error "ofd_access_log_reader exited with rc = '${rc}'"
15402         fi
15403
15404         oalr_expect_event_count alr_log_entry "${trace}" 1
15405
15406         pfid1=$($LFS path2fid "${file}")
15407
15408         # 1     2             3   4    5     6   7    8    9     10
15409         # TRACE alr_log_entry OST PFID BEGIN END TIME SIZE COUNT FLAGS
15410         entry=( - $(awk -v pfid="${pfid}" '$1 == "TRACE" && $2 == "alr_log_entry"' "${trace}" ) )
15411
15412         echo "entry = '${entry[*]}'" >&2
15413
15414         pfid2=${entry[4]}
15415         if [[ "${pfid1}" != "${pfid2}" ]]; then
15416                 error "entry '${entry[*]}' has invalid PFID '${pfid2}', expected ${pfid1}"
15417         fi
15418
15419         size=${entry[8]}
15420         if ((size != 1048576)); then
15421                 error "entry '${entry[*]}' has invalid io size '${size}', expected 1048576"
15422         fi
15423
15424         flags=${entry[10]}
15425         if [[ "${flags}" != "w" ]]; then
15426                 error "entry '${entry[*]}' has invalid io flags '${flags}', expected 'w'"
15427         fi
15428
15429         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
15430         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r524288c || error "cannot read '${file}'"
15431         sleep 5
15432         do_facet ost1 killall -TERM ofd_access_log_reader
15433         wait
15434         rc=$?
15435
15436         if ((rc != 0)); then
15437                 error "ofd_access_log_reader exited with rc = '${rc}'"
15438         fi
15439
15440         oalr_expect_event_count alr_log_entry "${trace}" 1
15441
15442         entry=( - $(awk -v pfid="${pfid}" '$1 == "TRACE" && $2 == "alr_log_entry"' "${trace}" ) )
15443         echo "entry = '${entry[*]}'" >&2
15444
15445         pfid2=${entry[4]}
15446         if [[ "${pfid1}" != "${pfid2}" ]]; then
15447                 error "entry '${entry[*]}' has invalid PFID '${pfid2}', expected ${pfid1}"
15448         fi
15449
15450         size=${entry[8]}
15451         if ((size != 524288)); then
15452                 error "entry '${entry[*]}' has invalid io size '${size}', 524288"
15453         fi
15454
15455         flags=${entry[10]}
15456         if [[ "${flags}" != "r" ]]; then
15457                 error "entry '${entry[*]}' has invalid io flags '${flags}', expected 'r'"
15458         fi
15459 }
15460 run_test 165b "ofd access log entries are produced and consumed"
15461
15462 test_165c() {
15463         local file="${DIR}/${tdir}/${tfile}"
15464         test_mkdir "${DIR}/${tdir}"
15465
15466         setup_165
15467
15468         lfs setstripe -c 1 -i 0 "${DIR}/${tdir}"
15469
15470         # 4096 / 64 = 64. Create twice as many entries.
15471         for ((i = 0; i < 128; i++)); do
15472                 $MULTIOP "${file}-${i}" oO_CREAT:O_WRONLY:w512c || error "cannot create file"
15473         done
15474
15475         sync
15476         do_facet ost1 ofd_access_log_reader --list
15477         unlinkmany  "${file}-%d" 128
15478 }
15479 run_test 165c "full ofd access logs do not block IOs"
15480
15481 oal_peek_entry_count() {
15482         do_facet ost1 ofd_access_log_reader --list | awk '$1 == "_entry_count:" { print $2; }'
15483 }
15484
15485 oal_expect_entry_count() {
15486         local entry_count=$(oal_peek_entry_count)
15487         local expect="$1"
15488
15489         if ((entry_count == expect)); then
15490                 return 0
15491         fi
15492
15493         error_noexit "bad entry count, got ${entry_count}, expected ${expect}"
15494         do_facet ost1 ofd_access_log_reader --list >&2
15495         exit 1
15496 }
15497
15498 test_165d() {
15499         local trace="/tmp/${tfile}.trace"
15500         local file="${DIR}/${tdir}/${tfile}"
15501         local param="obdfilter.${FSNAME}-OST0000.access_log_mask"
15502         local entry_count
15503         test_mkdir "${DIR}/${tdir}"
15504
15505         setup_165
15506         lfs setstripe -c 1 -i 0 "${file}"
15507
15508         do_facet ost1 lctl set_param "${param}=rw"
15509         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c || error "cannot create '${file}'"
15510         oal_expect_entry_count 1
15511
15512         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c || error "cannot read '${file}'"
15513         oal_expect_entry_count 2
15514
15515         do_facet ost1 lctl set_param "${param}=r"
15516         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c || error "cannot create '${file}'"
15517         oal_expect_entry_count 2
15518
15519         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c || error "cannot read '${file}'"
15520         oal_expect_entry_count 3
15521
15522         do_facet ost1 lctl set_param "${param}=w"
15523         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c || error "cannot create '${file}'"
15524         oal_expect_entry_count 4
15525
15526         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c || error "cannot read '${file}'"
15527         oal_expect_entry_count 4
15528
15529         do_facet ost1 lctl set_param "${param}=0"
15530         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c || error "cannot create '${file}'"
15531         oal_expect_entry_count 4
15532
15533         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c || error "cannot read '${file}'"
15534         oal_expect_entry_count 4
15535 }
15536 run_test 165d "ofd_access_log mask works"
15537
15538 test_169() {
15539         # do directio so as not to populate the page cache
15540         log "creating a 10 Mb file"
15541         $MULTIOP $DIR/$tfile oO_CREAT:O_DIRECT:O_RDWR:w$((10*1048576))c || error "multiop failed while creating a file"
15542         log "starting reads"
15543         dd if=$DIR/$tfile of=/dev/null bs=4096 &
15544         log "truncating the file"
15545         $MULTIOP $DIR/$tfile oO_TRUNC:c || error "multiop failed while truncating the file"
15546         log "killing dd"
15547         kill %+ || true # reads might have finished
15548         echo "wait until dd is finished"
15549         wait
15550         log "removing the temporary file"
15551         rm -rf $DIR/$tfile || error "tmp file removal failed"
15552 }
15553 run_test 169 "parallel read and truncate should not deadlock"
15554
15555 test_170() {
15556         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15557
15558         $LCTL clear     # bug 18514
15559         $LCTL debug_daemon start $TMP/${tfile}_log_good
15560         touch $DIR/$tfile
15561         $LCTL debug_daemon stop
15562         sed -e "s/^...../a/g" $TMP/${tfile}_log_good > $TMP/${tfile}_log_bad ||
15563                 error "sed failed to read log_good"
15564
15565         $LCTL debug_daemon start $TMP/${tfile}_log_good
15566         rm -rf $DIR/$tfile
15567         $LCTL debug_daemon stop
15568
15569         $LCTL df $TMP/${tfile}_log_bad > $TMP/${tfile}_log_bad.out 2>&1 ||
15570                error "lctl df log_bad failed"
15571
15572         local bad_line=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $9}')
15573         local good_line1=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $5}')
15574
15575         $LCTL df $TMP/${tfile}_log_good > $TMP/${tfile}_log_good.out 2>&1
15576         local good_line2=$(tail -n 1 $TMP/${tfile}_log_good.out | awk '{print $5}')
15577
15578         [ "$bad_line" ] && [ "$good_line1" ] && [ "$good_line2" ] ||
15579                 error "bad_line good_line1 good_line2 are empty"
15580
15581         cat $TMP/${tfile}_log_good >> $TMP/${tfile}_logs_corrupt
15582         cat $TMP/${tfile}_log_bad >> $TMP/${tfile}_logs_corrupt
15583         cat $TMP/${tfile}_log_good >> $TMP/${tfile}_logs_corrupt
15584
15585         $LCTL df $TMP/${tfile}_logs_corrupt > $TMP/${tfile}_log_bad.out 2>&1
15586         local bad_line_new=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $9}')
15587         local good_line_new=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $5}')
15588
15589         [ "$bad_line_new" ] && [ "$good_line_new" ] ||
15590                 error "bad_line_new good_line_new are empty"
15591
15592         local expected_good=$((good_line1 + good_line2*2))
15593
15594         rm -f $TMP/${tfile}*
15595         # LU-231, short malformed line may not be counted into bad lines
15596         if [ $bad_line -ne $bad_line_new ] &&
15597                    [ $bad_line -ne $((bad_line_new - 1)) ]; then
15598                 error "expected $bad_line bad lines, but got $bad_line_new"
15599                 return 1
15600         fi
15601
15602         if [ $expected_good -ne $good_line_new ]; then
15603                 error "expected $expected_good good lines, but got $good_line_new"
15604                 return 2
15605         fi
15606         true
15607 }
15608 run_test 170 "test lctl df to handle corrupted log ====================="
15609
15610 test_171() { # bug20592
15611         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15612
15613         #define OBD_FAIL_PTLRPC_DUMP_LOG         0x50e
15614         $LCTL set_param fail_loc=0x50e
15615         $LCTL set_param fail_val=3000
15616         multiop_bg_pause $DIR/$tfile O_s || true
15617         local MULTIPID=$!
15618         kill -USR1 $MULTIPID
15619         # cause log dump
15620         sleep 3
15621         wait $MULTIPID
15622         if dmesg | grep "recursive fault"; then
15623                 error "caught a recursive fault"
15624         fi
15625         $LCTL set_param fail_loc=0
15626         true
15627 }
15628 run_test 171 "test libcfs_debug_dumplog_thread stuck in do_exit() ======"
15629
15630 # it would be good to share it with obdfilter-survey/iokit-libecho code
15631 setup_obdecho_osc () {
15632         local rc=0
15633         local ost_nid=$1
15634         local obdfilter_name=$2
15635         echo "Creating new osc for $obdfilter_name on $ost_nid"
15636         # make sure we can find loopback nid
15637         $LCTL add_uuid $ost_nid $ost_nid >/dev/null 2>&1
15638
15639         [ $rc -eq 0 ] && { $LCTL attach osc ${obdfilter_name}_osc     \
15640                            ${obdfilter_name}_osc_UUID || rc=2; }
15641         [ $rc -eq 0 ] && { $LCTL --device ${obdfilter_name}_osc setup \
15642                            ${obdfilter_name}_UUID  $ost_nid || rc=3; }
15643         return $rc
15644 }
15645
15646 cleanup_obdecho_osc () {
15647         local obdfilter_name=$1
15648         $LCTL --device ${obdfilter_name}_osc cleanup >/dev/null
15649         $LCTL --device ${obdfilter_name}_osc detach  >/dev/null
15650         return 0
15651 }
15652
15653 obdecho_test() {
15654         local OBD=$1
15655         local node=$2
15656         local pages=${3:-64}
15657         local rc=0
15658         local id
15659
15660         local count=10
15661         local obd_size=$(get_obd_size $node $OBD)
15662         local page_size=$(get_page_size $node)
15663         if [[ -n "$obd_size" ]]; then
15664                 local new_count=$((obd_size / (pages * page_size / 1024)))
15665                 [[ $new_count -ge $count ]] || count=$new_count
15666         fi
15667
15668         do_facet $node "$LCTL attach echo_client ec ec_uuid" || rc=1
15669         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec setup $OBD" ||
15670                            rc=2; }
15671         if [ $rc -eq 0 ]; then
15672             id=$(do_facet $node "$LCTL --device ec create 1"  | awk '/object id/ {print $6}')
15673             [ ${PIPESTATUS[0]} -eq 0 -a -n "$id" ] || rc=3
15674         fi
15675         echo "New object id is $id"
15676         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec getattr $id" ||
15677                            rc=4; }
15678         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec "                 \
15679                            "test_brw $count w v $pages $id" || rc=4; }
15680         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec destroy $id 1" ||
15681                            rc=4; }
15682         [ $rc -eq 0 ] || [ $rc -gt 2 ] &&
15683                 { do_facet $node "$LCTL --device ec cleanup" || rc=5; }
15684         [ $rc -eq 0 ] || [ $rc -gt 1 ] &&
15685                 { do_facet $node "$LCTL --device ec detach" || rc=6; }
15686         [ $rc -ne 0 ] && echo "obecho_create_test failed: $rc"
15687         return $rc
15688 }
15689
15690 test_180a() {
15691         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15692
15693         if ! module_loaded obdecho; then
15694                 load_module obdecho/obdecho &&
15695                         stack_trap "rmmod obdecho" EXIT ||
15696                         error "unable to load obdecho on client"
15697         fi
15698
15699         local osc=$($LCTL dl | grep -v mdt | awk '$3 == "osc" {print $4; exit}')
15700         local host=$($LCTL get_param -n osc.$osc.import |
15701                      awk '/current_connection:/ { print $2 }' )
15702         local target=$($LCTL get_param -n osc.$osc.import |
15703                        awk '/target:/ { print $2 }' )
15704         target=${target%_UUID}
15705
15706         if [ -n "$target" ]; then
15707                 setup_obdecho_osc $host $target &&
15708                         stack_trap "cleanup_obdecho_osc $target" EXIT ||
15709                         { error "obdecho setup failed with $?"; return; }
15710
15711                 obdecho_test ${target}_osc client ||
15712                         error "obdecho_test failed on ${target}_osc"
15713         else
15714                 $LCTL get_param osc.$osc.import
15715                 error "there is no osc.$osc.import target"
15716         fi
15717 }
15718 run_test 180a "test obdecho on osc"
15719
15720 test_180b() {
15721         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15722         remote_ost_nodsh && skip "remote OST with nodsh"
15723
15724         do_rpc_nodes $(facet_active_host ost1) load_module obdecho/obdecho &&
15725                 stack_trap "do_facet ost1 rmmod obdecho" EXIT ||
15726                 error "failed to load module obdecho"
15727
15728         local target=$(do_facet ost1 $LCTL dl |
15729                        awk '/obdfilter/ { print $4; exit; }')
15730
15731         if [ -n "$target" ]; then
15732                 obdecho_test $target ost1 || error "obdecho_test failed with $?"
15733         else
15734                 do_facet ost1 $LCTL dl
15735                 error "there is no obdfilter target on ost1"
15736         fi
15737 }
15738 run_test 180b "test obdecho directly on obdfilter"
15739
15740 test_180c() { # LU-2598
15741         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15742         remote_ost_nodsh && skip "remote OST with nodsh"
15743         [[ $MDS1_VERSION -lt $(version_code 2.4.0) ]] &&
15744                 skip "Need MDS version at least 2.4.0"
15745
15746         do_rpc_nodes $(facet_active_host ost1) load_module obdecho/obdecho &&
15747                 stack_trap "do_facet ost1 rmmod obdecho" EXIT ||
15748                 error "failed to load module obdecho"
15749
15750         local target=$(do_facet ost1 $LCTL dl |
15751                        awk '/obdfilter/ { print $4; exit; }')
15752
15753         if [ -n "$target" ]; then
15754                 local pages=16384 # 64MB bulk I/O RPC size
15755
15756                 obdecho_test "$target" ost1 "$pages" ||
15757                         error "obdecho_test with pages=$pages failed with $?"
15758         else
15759                 do_facet ost1 $LCTL dl
15760                 error "there is no obdfilter target on ost1"
15761         fi
15762 }
15763 run_test 180c "test huge bulk I/O size on obdfilter, don't LASSERT"
15764
15765 test_181() { # bug 22177
15766         test_mkdir $DIR/$tdir
15767         # create enough files to index the directory
15768         createmany -o $DIR/$tdir/foobar 4000
15769         # print attributes for debug purpose
15770         lsattr -d .
15771         # open dir
15772         multiop_bg_pause $DIR/$tdir D_Sc || return 1
15773         MULTIPID=$!
15774         # remove the files & current working dir
15775         unlinkmany $DIR/$tdir/foobar 4000
15776         rmdir $DIR/$tdir
15777         kill -USR1 $MULTIPID
15778         wait $MULTIPID
15779         stat $DIR/$tdir && error "open-unlinked dir was not removed!"
15780         return 0
15781 }
15782 run_test 181 "Test open-unlinked dir ========================"
15783
15784 test_182() {
15785         local fcount=1000
15786         local tcount=10
15787
15788         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
15789
15790         $LCTL set_param mdc.*.rpc_stats=clear
15791
15792         for (( i = 0; i < $tcount; i++ )) ; do
15793                 mkdir $DIR/$tdir/$i
15794         done
15795
15796         for (( i = 0; i < $tcount; i++ )) ; do
15797                 createmany -o $DIR/$tdir/$i/f- $fcount &
15798         done
15799         wait
15800
15801         for (( i = 0; i < $tcount; i++ )) ; do
15802                 unlinkmany $DIR/$tdir/$i/f- $fcount &
15803         done
15804         wait
15805
15806         $LCTL get_param mdc.*.rpc_stats
15807
15808         rm -rf $DIR/$tdir
15809 }
15810 run_test 182 "Test parallel modify metadata operations ================"
15811
15812 test_183() { # LU-2275
15813         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15814         remote_mds_nodsh && skip "remote MDS with nodsh"
15815         [[ $MDS1_VERSION -lt $(version_code 2.3.56) ]] &&
15816                 skip "Need MDS version at least 2.3.56"
15817
15818         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
15819         echo aaa > $DIR/$tdir/$tfile
15820
15821 #define OBD_FAIL_MDS_NEGATIVE_POSITIVE  0x148
15822         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x148
15823
15824         ls -l $DIR/$tdir && error "ls succeeded, should have failed"
15825         cat $DIR/$tdir/$tfile && error "cat succeeded, should have failed"
15826
15827         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
15828
15829         # Flush negative dentry cache
15830         touch $DIR/$tdir/$tfile
15831
15832         # We are not checking for any leaked references here, they'll
15833         # become evident next time we do cleanup with module unload.
15834         rm -rf $DIR/$tdir
15835 }
15836 run_test 183 "No crash or request leak in case of strange dispositions ========"
15837
15838 # test suite 184 is for LU-2016, LU-2017
15839 test_184a() {
15840         check_swap_layouts_support
15841
15842         dir0=$DIR/$tdir/$testnum
15843         test_mkdir -p -c1 $dir0
15844         ref1=/etc/passwd
15845         ref2=/etc/group
15846         file1=$dir0/f1
15847         file2=$dir0/f2
15848         $LFS setstripe -c1 $file1
15849         cp $ref1 $file1
15850         $LFS setstripe -c2 $file2
15851         cp $ref2 $file2
15852         gen1=$($LFS getstripe -g $file1)
15853         gen2=$($LFS getstripe -g $file2)
15854
15855         $LFS swap_layouts $file1 $file2 || error "swap of file layout failed"
15856         gen=$($LFS getstripe -g $file1)
15857         [[ $gen1 != $gen ]] ||
15858                 "Layout generation on $file1 does not change"
15859         gen=$($LFS getstripe -g $file2)
15860         [[ $gen2 != $gen ]] ||
15861                 "Layout generation on $file2 does not change"
15862
15863         cmp $ref1 $file2 || error "content compare failed ($ref1 != $file2)"
15864         cmp $ref2 $file1 || error "content compare failed ($ref2 != $file1)"
15865
15866         lfsck_verify_pfid $file1 $file2 || error "PFID are not transferred"
15867 }
15868 run_test 184a "Basic layout swap"
15869
15870 test_184b() {
15871         check_swap_layouts_support
15872
15873         dir0=$DIR/$tdir/$testnum
15874         mkdir -p $dir0 || error "creating dir $dir0"
15875         file1=$dir0/f1
15876         file2=$dir0/f2
15877         file3=$dir0/f3
15878         dir1=$dir0/d1
15879         dir2=$dir0/d2
15880         mkdir $dir1 $dir2
15881         $LFS setstripe -c1 $file1
15882         $LFS setstripe -c2 $file2
15883         $LFS setstripe -c1 $file3
15884         chown $RUNAS_ID $file3
15885         gen1=$($LFS getstripe -g $file1)
15886         gen2=$($LFS getstripe -g $file2)
15887
15888         $LFS swap_layouts $dir1 $dir2 &&
15889                 error "swap of directories layouts should fail"
15890         $LFS swap_layouts $dir1 $file1 &&
15891                 error "swap of directory and file layouts should fail"
15892         $RUNAS $LFS swap_layouts $file1 $file2 &&
15893                 error "swap of file we cannot write should fail"
15894         $LFS swap_layouts $file1 $file3 &&
15895                 error "swap of file with different owner should fail"
15896         /bin/true # to clear error code
15897 }
15898 run_test 184b "Forbidden layout swap (will generate errors)"
15899
15900 test_184c() {
15901         local cmpn_arg=$(cmp -n 2>&1 | grep "invalid option")
15902         [ -n "$cmpn_arg" ] && skip_env "cmp does not support -n"
15903         check_swap_layouts_support
15904         check_swap_layout_no_dom $DIR
15905
15906         local dir0=$DIR/$tdir/$testnum
15907         mkdir -p $dir0 || error "creating dir $dir0"
15908
15909         local ref1=$dir0/ref1
15910         local ref2=$dir0/ref2
15911         local file1=$dir0/file1
15912         local file2=$dir0/file2
15913         # create a file large enough for the concurrent test
15914         dd if=/dev/urandom of=$ref1 bs=1M count=$((RANDOM % 50 + 20))
15915         dd if=/dev/urandom of=$ref2 bs=1M count=$((RANDOM % 50 + 20))
15916         echo "ref file size: ref1($(stat -c %s $ref1))," \
15917              "ref2($(stat -c %s $ref2))"
15918
15919         cp $ref2 $file2
15920         dd if=$ref1 of=$file1 bs=16k &
15921         local DD_PID=$!
15922
15923         # Make sure dd starts to copy file
15924         while [ ! -f $file1 ]; do sleep 0.1; done
15925
15926         $LFS swap_layouts $file1 $file2
15927         local rc=$?
15928         wait $DD_PID
15929         [[ $? == 0 ]] || error "concurrent write on $file1 failed"
15930         [[ $rc == 0 ]] || error "swap of $file1 and $file2 failed"
15931
15932         # how many bytes copied before swapping layout
15933         local copied=$(stat -c %s $file2)
15934         local remaining=$(stat -c %s $ref1)
15935         remaining=$((remaining - copied))
15936         echo "Copied $copied bytes before swapping layout..."
15937
15938         cmp -n $copied $file1 $ref2 | grep differ &&
15939                 error "Content mismatch [0, $copied) of ref2 and file1"
15940         cmp -n $copied $file2 $ref1 ||
15941                 error "Content mismatch [0, $copied) of ref1 and file2"
15942         cmp -i $copied:$copied -n $remaining $file1 $ref1 ||
15943                 error "Content mismatch [$copied, EOF) of ref1 and file1"
15944
15945         # clean up
15946         rm -f $ref1 $ref2 $file1 $file2
15947 }
15948 run_test 184c "Concurrent write and layout swap"
15949
15950 test_184d() {
15951         check_swap_layouts_support
15952         check_swap_layout_no_dom $DIR
15953         [ -z "$(which getfattr 2>/dev/null)" ] &&
15954                 skip_env "no getfattr command"
15955
15956         local file1=$DIR/$tdir/$tfile-1
15957         local file2=$DIR/$tdir/$tfile-2
15958         local file3=$DIR/$tdir/$tfile-3
15959         local lovea1
15960         local lovea2
15961
15962         mkdir -p $DIR/$tdir
15963         touch $file1 || error "create $file1 failed"
15964         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file2 ||
15965                 error "create $file2 failed"
15966         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file3 ||
15967                 error "create $file3 failed"
15968         lovea1=$(get_layout_param $file1)
15969
15970         $LFS swap_layouts $file2 $file3 ||
15971                 error "swap $file2 $file3 layouts failed"
15972         $LFS swap_layouts $file1 $file2 ||
15973                 error "swap $file1 $file2 layouts failed"
15974
15975         lovea2=$(get_layout_param $file2)
15976         echo "$lovea1"
15977         echo "$lovea2"
15978         [ "$lovea1" == "$lovea2" ] || error "lovea $lovea1 != $lovea2"
15979
15980         lovea1=$(getfattr -n trusted.lov $file1 | grep ^trusted)
15981         [[ -z "$lovea1" ]] || error "$file1 shouldn't have lovea"
15982 }
15983 run_test 184d "allow stripeless layouts swap"
15984
15985 test_184e() {
15986         [[ $MDS1_VERSION -ge $(version_code 2.6.94) ]] ||
15987                 skip "Need MDS version at least 2.6.94"
15988         check_swap_layouts_support
15989         check_swap_layout_no_dom $DIR
15990         [ -z "$(which getfattr 2>/dev/null)" ] &&
15991                 skip_env "no getfattr command"
15992
15993         local file1=$DIR/$tdir/$tfile-1
15994         local file2=$DIR/$tdir/$tfile-2
15995         local file3=$DIR/$tdir/$tfile-3
15996         local lovea
15997
15998         mkdir -p $DIR/$tdir
15999         touch $file1 || error "create $file1 failed"
16000         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file2 ||
16001                 error "create $file2 failed"
16002         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file3 ||
16003                 error "create $file3 failed"
16004
16005         $LFS swap_layouts $file1 $file2 ||
16006                 error "swap $file1 $file2 layouts failed"
16007
16008         lovea=$(getfattr -n trusted.lov $file1 | grep ^trusted)
16009         [[ -z "$lovea" ]] || error "$file1 shouldn't have lovea"
16010
16011         echo 123 > $file1 || error "Should be able to write into $file1"
16012
16013         $LFS swap_layouts $file1 $file3 ||
16014                 error "swap $file1 $file3 layouts failed"
16015
16016         echo 123 > $file1 || error "Should be able to write into $file1"
16017
16018         rm -rf $file1 $file2 $file3
16019 }
16020 run_test 184e "Recreate layout after stripeless layout swaps"
16021
16022 test_184f() {
16023         # Create a file with name longer than sizeof(struct stat) ==
16024         # 144 to see if we can get chars from the file name to appear
16025         # in the returned striping. Note that 'f' == 0x66.
16026         local file=$(for ((i = 0; i < 200; i++)); do echo -n f; done)
16027
16028         mkdir -p $DIR/$tdir
16029         mcreate $DIR/$tdir/$file
16030         if lfs find --stripe-count 0x6666 $DIR/$tdir | grep $file; then
16031                 error "IOC_MDC_GETFILEINFO returned garbage striping"
16032         fi
16033 }
16034 run_test 184f "IOC_MDC_GETFILEINFO for files with long names but no striping"
16035
16036 test_185() { # LU-2441
16037         # LU-3553 - no volatile file support in old servers
16038         [[ $MDS1_VERSION -ge $(version_code 2.3.60) ]] ||
16039                 skip "Need MDS version at least 2.3.60"
16040
16041         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
16042         touch $DIR/$tdir/spoo
16043         local mtime1=$(stat -c "%Y" $DIR/$tdir)
16044         local fid=$($MULTIOP $DIR/$tdir VFw4096c) ||
16045                 error "cannot create/write a volatile file"
16046         [ "$FILESET" == "" ] &&
16047         $CHECKSTAT -t file $MOUNT/.lustre/fid/$fid 2>/dev/null &&
16048                 error "FID is still valid after close"
16049
16050         multiop_bg_pause $DIR/$tdir vVw4096_c
16051         local multi_pid=$!
16052
16053         local OLD_IFS=$IFS
16054         IFS=":"
16055         local fidv=($fid)
16056         IFS=$OLD_IFS
16057         # assume that the next FID for this client is sequential, since stdout
16058         # is unfortunately eaten by multiop_bg_pause
16059         local n=$((${fidv[1]} + 1))
16060         local next_fid="${fidv[0]}:$(printf "0x%x" $n):${fidv[2]}"
16061         if [ "$FILESET" == "" ]; then
16062                 $CHECKSTAT -t file $MOUNT/.lustre/fid/$next_fid ||
16063                         error "FID is missing before close"
16064         fi
16065         kill -USR1 $multi_pid
16066         # 1 second delay, so if mtime change we will see it
16067         sleep 1
16068         local mtime2=$(stat -c "%Y" $DIR/$tdir)
16069         [[ $mtime1 == $mtime2 ]] || error "mtime has changed"
16070 }
16071 run_test 185 "Volatile file support"
16072
16073 function create_check_volatile() {
16074         local idx=$1
16075         local tgt
16076
16077         $MULTIOP $MOUNT/.lustre/fid V${idx}Fw4096_c >&/tmp/${tfile}.fid &
16078         local PID=$!
16079         sleep 1
16080         local FID=$(cat /tmp/${tfile}.fid)
16081         [ "$FID" == "" ] && error "can't get FID for volatile"
16082         $CHECKSTAT -t file $MOUNT/.lustre/fid/$FID || error "can't stat $FID"
16083         tgt=$($LFS getstripe -m $MOUNT/.lustre/fid/$FID)
16084         [ "$tgt" != "$idx" ] && error "wrong MDS $tgt, expected $idx"
16085         kill -USR1 $PID
16086         wait
16087         sleep 1
16088         cancel_lru_locks mdc # flush opencache
16089         $CHECKSTAT -t file $MOUNT/.lustre/fid/$FID && error "can stat $FID"
16090         return 0
16091 }
16092
16093 test_185a(){
16094         # LU-12516 - volatile creation via .lustre
16095         [[ $MDS1_VERSION -ge $(version_code 2.12.55) ]] ||
16096                 skip "Need MDS version at least 2.3.55"
16097
16098         create_check_volatile 0
16099         [ $MDSCOUNT -lt 2 ] && return 0
16100
16101         # DNE case
16102         create_check_volatile 1
16103
16104         return 0
16105 }
16106 run_test 185a "Volatile file creation in .lustre/fid/"
16107
16108 test_187a() {
16109         remote_mds_nodsh && skip "remote MDS with nodsh"
16110         [ $MDS1_VERSION -lt $(version_code 2.3.0) ] &&
16111                 skip "Need MDS version at least 2.3.0"
16112
16113         local dir0=$DIR/$tdir/$testnum
16114         mkdir -p $dir0 || error "creating dir $dir0"
16115
16116         local file=$dir0/file1
16117         dd if=/dev/urandom of=$file count=10 bs=1M conv=fsync
16118         local dv1=$($LFS data_version $file)
16119         dd if=/dev/urandom of=$file seek=10 count=1 bs=1M conv=fsync
16120         local dv2=$($LFS data_version $file)
16121         [[ $dv1 != $dv2 ]] ||
16122                 error "data version did not change on write $dv1 == $dv2"
16123
16124         # clean up
16125         rm -f $file1
16126 }
16127 run_test 187a "Test data version change"
16128
16129 test_187b() {
16130         remote_mds_nodsh && skip "remote MDS with nodsh"
16131         [ $MDS1_VERSION -lt $(version_code 2.3.0) ] &&
16132                 skip "Need MDS version at least 2.3.0"
16133
16134         local dir0=$DIR/$tdir/$testnum
16135         mkdir -p $dir0 || error "creating dir $dir0"
16136
16137         declare -a DV=$($MULTIOP $dir0 Vw1000xYw1000xY | cut -f3 -d" ")
16138         [[ ${DV[0]} != ${DV[1]} ]] ||
16139                 error "data version did not change on write"\
16140                       " ${DV[0]} == ${DV[1]}"
16141
16142         # clean up
16143         rm -f $file1
16144 }
16145 run_test 187b "Test data version change on volatile file"
16146
16147 test_200() {
16148         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16149         remote_mgs_nodsh && skip "remote MGS with nodsh"
16150         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
16151
16152         local POOL=${POOL:-cea1}
16153         local POOL_ROOT=${POOL_ROOT:-$DIR/d200.pools}
16154         local POOL_DIR_NAME=${POOL_DIR_NAME:-dir_tst}
16155         # Pool OST targets
16156         local first_ost=0
16157         local last_ost=$(($OSTCOUNT - 1))
16158         local ost_step=2
16159         local ost_list=$(seq $first_ost $ost_step $last_ost)
16160         local ost_range="$first_ost $last_ost $ost_step"
16161         local test_path=$POOL_ROOT/$POOL_DIR_NAME
16162         local file_dir=$POOL_ROOT/file_tst
16163         local subdir=$test_path/subdir
16164         local rc=0
16165
16166         while : ; do
16167                 # former test_200a test_200b
16168                 pool_add $POOL                          || { rc=$? ; break; }
16169                 pool_add_targets  $POOL $ost_range      || { rc=$? ; break; }
16170                 # former test_200c test_200d
16171                 mkdir -p $test_path
16172                 pool_set_dir      $POOL $test_path      || { rc=$? ; break; }
16173                 pool_check_dir    $POOL $test_path      || { rc=$? ; break; }
16174                 mkdir -p $subdir
16175                 pool_check_dir    $POOL $subdir         || { rc=$? ; break; }
16176                 pool_dir_rel_path $POOL $POOL_DIR_NAME $POOL_ROOT \
16177                                                         || { rc=$? ; break; }
16178                 # former test_200e test_200f
16179                 local files=$((OSTCOUNT*3))
16180                 pool_alloc_files  $POOL $test_path $files "$ost_list" \
16181                                                         || { rc=$? ; break; }
16182                 pool_create_files $POOL $file_dir $files "$ost_list" \
16183                                                         || { rc=$? ; break; }
16184                 # former test_200g test_200h
16185                 pool_lfs_df $POOL                       || { rc=$? ; break; }
16186                 pool_file_rel_path $POOL $test_path     || { rc=$? ; break; }
16187
16188                 # former test_201a test_201b test_201c
16189                 pool_remove_first_target $POOL          || { rc=$? ; break; }
16190
16191                 local f=$test_path/$tfile
16192                 pool_remove_all_targets $POOL $f        || { rc=$? ; break; }
16193                 pool_remove $POOL $f                    || { rc=$? ; break; }
16194                 break
16195         done
16196
16197         destroy_test_pools
16198
16199         return $rc
16200 }
16201 run_test 200 "OST pools"
16202
16203 # usage: default_attr <count | size | offset>
16204 default_attr() {
16205         $LCTL get_param -n lov.$FSNAME-clilov-\*.stripe${1}
16206 }
16207
16208 # usage: check_default_stripe_attr
16209 check_default_stripe_attr() {
16210         ACTUAL=$($LFS getstripe $* $DIR/$tdir)
16211         case $1 in
16212         --stripe-count|-c)
16213                 [ -n "$2" ] && EXPECTED=0 || EXPECTED=$(default_attr count);;
16214         --stripe-size|-S)
16215                 [ -n "$2" ] && EXPECTED=0 || EXPECTED=$(default_attr size);;
16216         --stripe-index|-i)
16217                 EXPECTED=-1;;
16218         *)
16219                 error "unknown getstripe attr '$1'"
16220         esac
16221
16222         [ $ACTUAL == $EXPECTED ] ||
16223                 error "$DIR/$tdir has $1 '$ACTUAL', not '$EXPECTED'"
16224 }
16225
16226 test_204a() {
16227         test_mkdir $DIR/$tdir
16228         $LFS setstripe --stripe-count 0 --stripe-size 0 --stripe-index -1 $DIR/$tdir
16229
16230         check_default_stripe_attr --stripe-count
16231         check_default_stripe_attr --stripe-size
16232         check_default_stripe_attr --stripe-index
16233 }
16234 run_test 204a "Print default stripe attributes"
16235
16236 test_204b() {
16237         test_mkdir $DIR/$tdir
16238         $LFS setstripe --stripe-count 1 $DIR/$tdir
16239
16240         check_default_stripe_attr --stripe-size
16241         check_default_stripe_attr --stripe-index
16242 }
16243 run_test 204b "Print default stripe size and offset"
16244
16245 test_204c() {
16246         test_mkdir $DIR/$tdir
16247         $LFS setstripe --stripe-size 65536 $DIR/$tdir
16248
16249         check_default_stripe_attr --stripe-count
16250         check_default_stripe_attr --stripe-index
16251 }
16252 run_test 204c "Print default stripe count and offset"
16253
16254 test_204d() {
16255         test_mkdir $DIR/$tdir
16256         $LFS setstripe --stripe-index 0 $DIR/$tdir
16257
16258         check_default_stripe_attr --stripe-count
16259         check_default_stripe_attr --stripe-size
16260 }
16261 run_test 204d "Print default stripe count and size"
16262
16263 test_204e() {
16264         test_mkdir $DIR/$tdir
16265         $LFS setstripe -d $DIR/$tdir
16266
16267         check_default_stripe_attr --stripe-count --raw
16268         check_default_stripe_attr --stripe-size --raw
16269         check_default_stripe_attr --stripe-index --raw
16270 }
16271 run_test 204e "Print raw stripe attributes"
16272
16273 test_204f() {
16274         test_mkdir $DIR/$tdir
16275         $LFS setstripe --stripe-count 1 $DIR/$tdir
16276
16277         check_default_stripe_attr --stripe-size --raw
16278         check_default_stripe_attr --stripe-index --raw
16279 }
16280 run_test 204f "Print raw stripe size and offset"
16281
16282 test_204g() {
16283         test_mkdir $DIR/$tdir
16284         $LFS setstripe --stripe-size 65536 $DIR/$tdir
16285
16286         check_default_stripe_attr --stripe-count --raw
16287         check_default_stripe_attr --stripe-index --raw
16288 }
16289 run_test 204g "Print raw stripe count and offset"
16290
16291 test_204h() {
16292         test_mkdir $DIR/$tdir
16293         $LFS setstripe --stripe-index 0 $DIR/$tdir
16294
16295         check_default_stripe_attr --stripe-count --raw
16296         check_default_stripe_attr --stripe-size --raw
16297 }
16298 run_test 204h "Print raw stripe count and size"
16299
16300 # Figure out which job scheduler is being used, if any,
16301 # or use a fake one
16302 if [ -n "$SLURM_JOB_ID" ]; then # SLURM
16303         JOBENV=SLURM_JOB_ID
16304 elif [ -n "$LSB_JOBID" ]; then # Load Sharing Facility
16305         JOBENV=LSB_JOBID
16306 elif [ -n "$PBS_JOBID" ]; then # PBS/Maui/Moab
16307         JOBENV=PBS_JOBID
16308 elif [ -n "$LOADL_STEPID" ]; then # LoadLeveller
16309         JOBENV=LOADL_STEP_ID
16310 elif [ -n "$JOB_ID" ]; then # Sun Grid Engine
16311         JOBENV=JOB_ID
16312 else
16313         $LCTL list_param jobid_name > /dev/null 2>&1
16314         if [ $? -eq 0 ]; then
16315                 JOBENV=nodelocal
16316         else
16317                 JOBENV=FAKE_JOBID
16318         fi
16319 fi
16320 LUSTRE_JOBID_SIZE=31 # plus NUL terminator
16321
16322 verify_jobstats() {
16323         local cmd=($1)
16324         shift
16325         local facets="$@"
16326
16327 # we don't really need to clear the stats for this test to work, since each
16328 # command has a unique jobid, but it makes debugging easier if needed.
16329 #       for facet in $facets; do
16330 #               local dev=$(convert_facet2label $facet)
16331 #               # clear old jobstats
16332 #               do_facet $facet lctl set_param *.$dev.job_stats="clear"
16333 #       done
16334
16335         # use a new JobID for each test, or we might see an old one
16336         [ "$JOBENV" = "FAKE_JOBID" ] &&
16337                 FAKE_JOBID=id.$testnum.$(basename ${cmd[0]}).$RANDOM
16338
16339         JOBVAL=${!JOBENV:0:$LUSTRE_JOBID_SIZE}
16340
16341         [ "$JOBENV" = "nodelocal" ] && {
16342                 FAKE_JOBID=id.$testnum.%e.$RANDOM
16343                 $LCTL set_param jobid_name=$FAKE_JOBID
16344                 JOBVAL=${FAKE_JOBID/\%e/$(basename ${cmd[0]})}
16345         }
16346
16347         log "Test: ${cmd[*]}"
16348         log "Using JobID environment $($LCTL get_param -n jobid_var)=$JOBVAL"
16349
16350         if [ $JOBENV = "FAKE_JOBID" ]; then
16351                 FAKE_JOBID=$JOBVAL ${cmd[*]}
16352         else
16353                 ${cmd[*]}
16354         fi
16355
16356         # all files are created on OST0000
16357         for facet in $facets; do
16358                 local stats="*.$(convert_facet2label $facet).job_stats"
16359
16360                 # strip out libtool wrappers for in-tree executables
16361                 if [ $(do_facet $facet lctl get_param $stats |
16362                        sed -e 's/\.lt-/./' | grep -c $JOBVAL) -ne 1 ]; then
16363                         do_facet $facet lctl get_param $stats
16364                         error "No jobstats for $JOBVAL found on $facet::$stats"
16365                 fi
16366         done
16367 }
16368
16369 jobstats_set() {
16370         local new_jobenv=$1
16371
16372         set_persistent_param_and_check client "jobid_var" \
16373                 "$FSNAME.sys.jobid_var" $new_jobenv
16374 }
16375
16376 test_205a() { # Job stats
16377         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16378         [[ $MDS1_VERSION -ge $(version_code 2.7.1) ]] ||
16379                 skip "Need MDS version with at least 2.7.1"
16380         remote_mgs_nodsh && skip "remote MGS with nodsh"
16381         remote_mds_nodsh && skip "remote MDS with nodsh"
16382         remote_ost_nodsh && skip "remote OST with nodsh"
16383         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep jobstats)" ] &&
16384                 skip "Server doesn't support jobstats"
16385         [[ $JOBID_VAR = disable ]] && skip_env "jobstats is disabled"
16386
16387         local old_jobenv=$($LCTL get_param -n jobid_var)
16388         [ $old_jobenv != $JOBENV ] && jobstats_set $JOBENV
16389
16390         if [[ $PERM_CMD == *"set_param -P"* ]]; then
16391                 stack_trap "do_facet mgs $PERM_CMD jobid_var=$old_jobenv" EXIT
16392         else
16393                 stack_trap "do_facet mgs $PERM_CMD \
16394                         $FSNAME.sys.jobid_var=$old_jobenv" EXIT
16395         fi
16396         changelog_register
16397
16398         local old_interval=$(do_facet $SINGLEMDS lctl get_param -n \
16399                                 mdt.*.job_cleanup_interval | head -n 1)
16400         local new_interval=5
16401         do_facet $SINGLEMDS \
16402                 $LCTL set_param mdt.*.job_cleanup_interval=$new_interval
16403         stack_trap "do_facet $SINGLEMDS \
16404                 $LCTL set_param mdt.*.job_cleanup_interval=$old_interval" EXIT
16405         local start=$SECONDS
16406
16407         local cmd
16408         # mkdir
16409         cmd="mkdir $DIR/$tdir"
16410         verify_jobstats "$cmd" "$SINGLEMDS"
16411         # rmdir
16412         cmd="rmdir $DIR/$tdir"
16413         verify_jobstats "$cmd" "$SINGLEMDS"
16414         # mkdir on secondary MDT
16415         if [ $MDSCOUNT -gt 1 ]; then
16416                 cmd="lfs mkdir -i 1 $DIR/$tdir.remote"
16417                 verify_jobstats "$cmd" "mds2"
16418         fi
16419         # mknod
16420         cmd="mknod $DIR/$tfile c 1 3"
16421         verify_jobstats "$cmd" "$SINGLEMDS"
16422         # unlink
16423         cmd="rm -f $DIR/$tfile"
16424         verify_jobstats "$cmd" "$SINGLEMDS"
16425         # create all files on OST0000 so verify_jobstats can find OST stats
16426         # open & close
16427         cmd="$LFS setstripe -i 0 -c 1 $DIR/$tfile"
16428         verify_jobstats "$cmd" "$SINGLEMDS"
16429         # setattr
16430         cmd="touch $DIR/$tfile"
16431         verify_jobstats "$cmd" "$SINGLEMDS ost1"
16432         # write
16433         cmd="dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=sync"
16434         verify_jobstats "$cmd" "ost1"
16435         # read
16436         cancel_lru_locks osc
16437         cmd="dd if=$DIR/$tfile of=/dev/null bs=1M count=1 iflag=direct"
16438         verify_jobstats "$cmd" "ost1"
16439         # truncate
16440         cmd="$TRUNCATE $DIR/$tfile 0"
16441         verify_jobstats "$cmd" "$SINGLEMDS ost1"
16442         # rename
16443         cmd="mv -f $DIR/$tfile $DIR/$tdir.rename"
16444         verify_jobstats "$cmd" "$SINGLEMDS"
16445         # jobstats expiry - sleep until old stats should be expired
16446         local left=$((new_interval + 5 - (SECONDS - start)))
16447         [ $left -ge 0 ] && wait_update_facet $SINGLEMDS \
16448                 "lctl get_param *.*.job_stats | grep -c 'job_id.*mkdir'" \
16449                         "0" $left
16450         cmd="mkdir $DIR/$tdir.expire"
16451         verify_jobstats "$cmd" "$SINGLEMDS"
16452         [ $(do_facet $SINGLEMDS lctl get_param *.*.job_stats |
16453             grep -c "job_id.*mkdir") -gt 1 ] && error "old jobstats not expired"
16454
16455         # Ensure that jobid are present in changelog (if supported by MDS)
16456         if [ $MDS1_VERSION -ge $(version_code 2.6.52) ];then
16457                 changelog_dump | tail -10
16458                 jobids=$(changelog_dump | tail -9 | grep -c "j=")
16459                 [ $jobids -eq 9 ] ||
16460                         error "Wrong changelog jobid count $jobids != 9"
16461
16462                 # LU-5862
16463                 JOBENV="disable"
16464                 jobstats_set $JOBENV
16465                 touch $DIR/$tfile
16466                 changelog_dump | grep $tfile
16467                 jobids=$(changelog_dump | grep $tfile | tail -1 | grep -c "j=")
16468                 [ $jobids -eq 0 ] ||
16469                         error "Unexpected jobids when jobid_var=$JOBENV"
16470         fi
16471
16472         lctl set_param jobid_var=USER jobid_name="S.%j.%e.%u.%h.E"
16473         JOBENV="JOBCOMPLEX"
16474         JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname).E"
16475
16476         verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
16477 }
16478 run_test 205a "Verify job stats"
16479
16480 # LU-13117, LU-13597
16481 test_205b() {
16482         job_stats="mdt.*.job_stats"
16483         $LCTL set_param $job_stats=clear
16484         $LCTL set_param jobid_var=USER jobid_name="%e.%u"
16485         env -i USERTESTJOBSTATS=foolish touch $DIR/$tfile.1
16486         do_facet $SINGLEMDS $LCTL get_param $job_stats |
16487                 grep "job_id:.*foolish" &&
16488                         error "Unexpected jobid found"
16489         do_facet $SINGLEMDS $LCTL get_param $job_stats |
16490                 grep "open:.*min.*max.*sum" ||
16491                         error "wrong job_stats format found"
16492 }
16493 run_test 205b "Verify job stats jobid and output format"
16494
16495 # LU-13733
16496 test_205c() {
16497         $LCTL set_param llite.*.stats=0
16498         dd if=/dev/zero of=$DIR/$tfile.1 bs=4k count=1
16499         $LCTL get_param llite.*.stats
16500         $LCTL get_param llite.*.stats | grep \
16501                 "write_bytes *1 samples \[bytes\] 4096 4096 4096 16777216" ||
16502                         error "wrong client stats format found"
16503 }
16504 run_test 205c "Verify client stats format"
16505
16506 # LU-1480, LU-1773 and LU-1657
16507 test_206() {
16508         mkdir -p $DIR/$tdir
16509         $LFS setstripe -c -1 $DIR/$tdir
16510 #define OBD_FAIL_LOV_INIT 0x1403
16511         $LCTL set_param fail_loc=0xa0001403
16512         $LCTL set_param fail_val=1
16513         touch $DIR/$tdir/$tfile || true
16514 }
16515 run_test 206 "fail lov_init_raid0() doesn't lbug"
16516
16517 test_207a() {
16518         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((RANDOM%10+1))
16519         local fsz=`stat -c %s $DIR/$tfile`
16520         cancel_lru_locks mdc
16521
16522         # do not return layout in getattr intent
16523 #define OBD_FAIL_MDS_NO_LL_GETATTR 0x170
16524         $LCTL set_param fail_loc=0x170
16525         local sz=`stat -c %s $DIR/$tfile`
16526
16527         [ $fsz -eq $sz ] || error "file size expected $fsz, actual $sz"
16528
16529         rm -rf $DIR/$tfile
16530 }
16531 run_test 207a "can refresh layout at glimpse"
16532
16533 test_207b() {
16534         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((RANDOM%10+1))
16535         local cksum=`md5sum $DIR/$tfile`
16536         local fsz=`stat -c %s $DIR/$tfile`
16537         cancel_lru_locks mdc
16538         cancel_lru_locks osc
16539
16540         # do not return layout in getattr intent
16541 #define OBD_FAIL_MDS_NO_LL_OPEN 0x171
16542         $LCTL set_param fail_loc=0x171
16543
16544         # it will refresh layout after the file is opened but before read issues
16545         echo checksum is "$cksum"
16546         echo "$cksum" |md5sum -c --quiet || error "file differs"
16547
16548         rm -rf $DIR/$tfile
16549 }
16550 run_test 207b "can refresh layout at open"
16551
16552 test_208() {
16553         # FIXME: in this test suite, only RD lease is used. This is okay
16554         # for now as only exclusive open is supported. After generic lease
16555         # is done, this test suite should be revised. - Jinshan
16556
16557         remote_mds_nodsh && skip "remote MDS with nodsh"
16558         [[ $MDS1_VERSION -ge $(version_code 2.4.52) ]] ||
16559                 skip "Need MDS version at least 2.4.52"
16560
16561         echo "==== test 1: verify get lease work"
16562         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:eRE+eU || error "get lease error"
16563
16564         echo "==== test 2: verify lease can be broken by upcoming open"
16565         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E-eUc &
16566         local PID=$!
16567         sleep 1
16568
16569         $MULTIOP $DIR/$tfile oO_RDONLY:c
16570         kill -USR1 $PID && wait $PID || error "break lease error"
16571
16572         echo "==== test 3: verify lease can't be granted if an open already exists"
16573         $MULTIOP $DIR/$tfile oO_RDONLY:_c &
16574         local PID=$!
16575         sleep 1
16576
16577         $MULTIOP $DIR/$tfile oO_RDONLY:eReUc && error "apply lease should fail"
16578         kill -USR1 $PID && wait $PID || error "open file error"
16579
16580         echo "==== test 4: lease can sustain over recovery"
16581         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E+eUc &
16582         PID=$!
16583         sleep 1
16584
16585         fail mds1
16586
16587         kill -USR1 $PID && wait $PID || error "lease broken over recovery"
16588
16589         echo "==== test 5: lease broken can't be regained by replay"
16590         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E-eUc &
16591         PID=$!
16592         sleep 1
16593
16594         # open file to break lease and then recovery
16595         $MULTIOP $DIR/$tfile oO_RDWR:c || error "open file error"
16596         fail mds1
16597
16598         kill -USR1 $PID && wait $PID || error "lease not broken over recovery"
16599
16600         rm -f $DIR/$tfile
16601 }
16602 run_test 208 "Exclusive open"
16603
16604 test_209() {
16605         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep disp_stripe)" ] &&
16606                 skip_env "must have disp_stripe"
16607
16608         touch $DIR/$tfile
16609         sync; sleep 5; sync;
16610
16611         echo 3 > /proc/sys/vm/drop_caches
16612         [ -f /sys/kernel/slab/ptlrpc_cache/shrink ] &&
16613                 echo 1 > /sys/kernel/slab/ptlrpc_cache/shrink
16614         req_before=$(awk '/ptlrpc_cache / { print $2 }' /proc/slabinfo)
16615
16616         # open/close 500 times
16617         for i in $(seq 500); do
16618                 cat $DIR/$tfile
16619         done
16620
16621         echo 3 > /proc/sys/vm/drop_caches
16622         [ -f /sys/kernel/slab/ptlrpc_cache/shrink ] &&
16623                 echo 1 > /sys/kernel/slab/ptlrpc_cache/shrink
16624         req_after=$(awk '/ptlrpc_cache / { print $2 }' /proc/slabinfo)
16625
16626         echo "before: $req_before, after: $req_after"
16627         [ $((req_after - req_before)) -ge 300 ] &&
16628                 error "open/close requests are not freed"
16629         return 0
16630 }
16631 run_test 209 "read-only open/close requests should be freed promptly"
16632
16633 test_210() {
16634         local pid
16635
16636         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:eW_E+eUc &
16637         pid=$!
16638         sleep 1
16639
16640         $LFS getstripe $DIR/$tfile
16641         kill -USR1 $pid
16642         wait $pid || error "multiop failed"
16643
16644         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E+eUc &
16645         pid=$!
16646         sleep 1
16647
16648         $LFS getstripe $DIR/$tfile
16649         kill -USR1 $pid
16650         wait $pid || error "multiop failed"
16651 }
16652 run_test 210 "lfs getstripe does not break leases"
16653
16654 test_212() {
16655         size=`date +%s`
16656         size=$((size % 8192 + 1))
16657         dd if=/dev/urandom of=$DIR/f212 bs=1k count=$size
16658         sendfile $DIR/f212 $DIR/f212.xyz || error "sendfile wrong"
16659         rm -f $DIR/f212 $DIR/f212.xyz
16660 }
16661 run_test 212 "Sendfile test ============================================"
16662
16663 test_213() {
16664         dd if=/dev/zero of=$DIR/$tfile bs=4k count=4
16665         cancel_lru_locks osc
16666         lctl set_param fail_loc=0x8000040f
16667         # generate a read lock
16668         cat $DIR/$tfile > /dev/null
16669         # write to the file, it will try to cancel the above read lock.
16670         cat /etc/hosts >> $DIR/$tfile
16671 }
16672 run_test 213 "OSC lock completion and cancel race don't crash - bug 18829"
16673
16674 test_214() { # for bug 20133
16675         mkdir -p $DIR/$tdir/d214c || error "mkdir $DIR/$tdir/d214c failed"
16676         for (( i=0; i < 340; i++ )) ; do
16677                 touch $DIR/$tdir/d214c/a$i
16678         done
16679
16680         ls -l $DIR/$tdir || error "ls -l $DIR/d214p failed"
16681         mv $DIR/$tdir/d214c $DIR/ || error "mv $DIR/d214p/d214c $DIR/ failed"
16682         ls $DIR/d214c || error "ls $DIR/d214c failed"
16683         rm -rf $DIR/$tdir || error "rm -rf $DIR/d214* failed"
16684         rm -rf $DIR/d214* || error "rm -rf $DIR/d214* failed"
16685 }
16686 run_test 214 "hash-indexed directory test - bug 20133"
16687
16688 # having "abc" as 1st arg, creates $TMP/lnet_abc.out and $TMP/lnet_abc.sys
16689 create_lnet_proc_files() {
16690         lctl get_param -n $1 >$TMP/lnet_$1.sys || error "cannot read lnet.$1"
16691 }
16692
16693 # counterpart of create_lnet_proc_files
16694 remove_lnet_proc_files() {
16695         rm -f $TMP/lnet_$1.sys
16696 }
16697
16698 # uses 1st arg as trailing part of filename, 2nd arg as description for reports,
16699 # 3rd arg as regexp for body
16700 check_lnet_proc_stats() {
16701         local l=$(cat "$TMP/lnet_$1" |wc -l)
16702         [ $l = 1 ] || (cat "$TMP/lnet_$1" && error "$2 is not of 1 line: $l")
16703
16704         grep -E "$3" "$TMP/lnet_$1" || (cat "$TMP/lnet_$1" && error "$2 misformatted")
16705 }
16706
16707 # uses 1st arg as trailing part of filename, 2nd arg as description for reports,
16708 # 3rd arg as regexp for body, 4th arg as regexp for 1st line, 5th arg is
16709 # optional and can be regexp for 2nd line (lnet.routes case)
16710 check_lnet_proc_entry() {
16711         local blp=2          # blp stands for 'position of 1st line of body'
16712         [ -z "$5" ] || blp=3 # lnet.routes case
16713
16714         local l=$(cat "$TMP/lnet_$1" |wc -l)
16715         # subtracting one from $blp because the body can be empty
16716         [ "$l" -ge "$(($blp - 1))" ] || (cat "$TMP/lnet_$1" && error "$2 is too short: $l")
16717
16718         sed -n '1 p' "$TMP/lnet_$1" |grep -E "$4" >/dev/null ||
16719                 (cat "$TMP/lnet_$1" && error "1st line of $2 misformatted")
16720
16721         [ "$5" = "" ] || sed -n '2 p' "$TMP/lnet_$1" |grep -E "$5" >/dev/null ||
16722                 (cat "$TMP/lnet_$1" && error "2nd line of $2 misformatted")
16723
16724         # bail out if any unexpected line happened
16725         sed -n "$blp p" "$TMP/lnet_$1" | grep -Ev "$3"
16726         [ "$?" != 0 ] || error "$2 misformatted"
16727 }
16728
16729 test_215() { # for bugs 18102, 21079, 21517
16730         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16731
16732         local N='(0|[1-9][0-9]*)'       # non-negative numeric
16733         local P='[1-9][0-9]*'           # positive numeric
16734         local I='(0|-?[1-9][0-9]*|NA)'  # any numeric (0 | >0 | <0) or NA if no value
16735         local NET='[a-z][a-z0-9]*'      # LNET net like o2ib2
16736         local ADDR='[0-9.]+'            # LNET addr like 10.0.0.1
16737         local NID="$ADDR@$NET"          # LNET nid like 10.0.0.1@o2ib2
16738
16739         local L1 # regexp for 1st line
16740         local L2 # regexp for 2nd line (optional)
16741         local BR # regexp for the rest (body)
16742
16743         # lnet.stats should look as 11 space-separated non-negative numerics
16744         BR="^$N $N $N $N $N $N $N $N $N $N $N$"
16745         create_lnet_proc_files "stats"
16746         check_lnet_proc_stats "stats.sys" "lnet.stats" "$BR"
16747         remove_lnet_proc_files "stats"
16748
16749         # lnet.routes should look like this:
16750         # Routing disabled/enabled
16751         # net hops priority state router
16752         # where net is a string like tcp0, hops > 0, priority >= 0,
16753         # state is up/down,
16754         # router is a string like 192.168.1.1@tcp2
16755         L1="^Routing (disabled|enabled)$"
16756         L2="^net +hops +priority +state +router$"
16757         BR="^$NET +$N +(0|1) +(up|down) +$NID$"
16758         create_lnet_proc_files "routes"
16759         check_lnet_proc_entry "routes.sys" "lnet.routes" "$BR" "$L1" "$L2"
16760         remove_lnet_proc_files "routes"
16761
16762         # lnet.routers should look like this:
16763         # ref rtr_ref alive_cnt state last_ping ping_sent deadline down_ni router
16764         # where ref > 0, rtr_ref > 0, alive_cnt >= 0, state is up/down,
16765         # last_ping >= 0, ping_sent is boolean (0/1), deadline and down_ni are
16766         # numeric (0 or >0 or <0), router is a string like 192.168.1.1@tcp2
16767         L1="^ref +rtr_ref +alive +router$"
16768         BR="^$P +$P +(up|down) +$NID$"
16769         create_lnet_proc_files "routers"
16770         check_lnet_proc_entry "routers.sys" "lnet.routers" "$BR" "$L1"
16771         remove_lnet_proc_files "routers"
16772
16773         # lnet.peers should look like this:
16774         # nid refs state last max rtr min tx min queue
16775         # where nid is a string like 192.168.1.1@tcp2, refs > 0,
16776         # state is up/down/NA, max >= 0. last, rtr, min, tx, min are
16777         # numeric (0 or >0 or <0), queue >= 0.
16778         L1="^nid +refs +state +last +max +rtr +min +tx +min +queue$"
16779         BR="^$NID +$P +(up|down|NA) +$I +$N +$I +$I +$I +$I +$N$"
16780         create_lnet_proc_files "peers"
16781         check_lnet_proc_entry "peers.sys" "lnet.peers" "$BR" "$L1"
16782         remove_lnet_proc_files "peers"
16783
16784         # lnet.buffers  should look like this:
16785         # pages count credits min
16786         # where pages >=0, count >=0, credits and min are numeric (0 or >0 or <0)
16787         L1="^pages +count +credits +min$"
16788         BR="^ +$N +$N +$I +$I$"
16789         create_lnet_proc_files "buffers"
16790         check_lnet_proc_entry "buffers.sys" "lnet.buffers" "$BR" "$L1"
16791         remove_lnet_proc_files "buffers"
16792
16793         # lnet.nis should look like this:
16794         # nid status alive refs peer rtr max tx min
16795         # where nid is a string like 192.168.1.1@tcp2, status is up/down,
16796         # alive is numeric (0 or >0 or <0), refs >= 0, peer >= 0,
16797         # rtr >= 0, max >=0, tx and min are numeric (0 or >0 or <0).
16798         L1="^nid +status +alive +refs +peer +rtr +max +tx +min$"
16799         BR="^$NID +(up|down) +$I +$N +$N +$N +$N +$I +$I$"
16800         create_lnet_proc_files "nis"
16801         check_lnet_proc_entry "nis.sys" "lnet.nis" "$BR" "$L1"
16802         remove_lnet_proc_files "nis"
16803
16804         # can we successfully write to lnet.stats?
16805         lctl set_param -n stats=0 || error "cannot write to lnet.stats"
16806 }
16807 run_test 215 "lnet exists and has proper content - bugs 18102, 21079, 21517"
16808
16809 test_216() { # bug 20317
16810         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16811         remote_ost_nodsh && skip "remote OST with nodsh"
16812
16813         local node
16814         local facets=$(get_facets OST)
16815         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
16816
16817         save_lustre_params client "osc.*.contention_seconds" > $p
16818         save_lustre_params $facets \
16819                 "ldlm.namespaces.filter-*.max_nolock_bytes" >> $p
16820         save_lustre_params $facets \
16821                 "ldlm.namespaces.filter-*.contended_locks" >> $p
16822         save_lustre_params $facets \
16823                 "ldlm.namespaces.filter-*.contention_seconds" >> $p
16824         clear_stats osc.*.osc_stats
16825
16826         # agressive lockless i/o settings
16827         do_nodes $(comma_list $(osts_nodes)) \
16828                 "lctl set_param -n ldlm.namespaces.*.max_nolock_bytes=2000000 \
16829                         ldlm.namespaces.filter-*.contended_locks=0 \
16830                         ldlm.namespaces.filter-*.contention_seconds=60"
16831         lctl set_param -n osc.*.contention_seconds=60
16832
16833         $DIRECTIO write $DIR/$tfile 0 10 4096
16834         $CHECKSTAT -s 40960 $DIR/$tfile
16835
16836         # disable lockless i/o
16837         do_nodes $(comma_list $(osts_nodes)) \
16838                 "lctl set_param -n ldlm.namespaces.filter-*.max_nolock_bytes=0 \
16839                         ldlm.namespaces.filter-*.contended_locks=32 \
16840                         ldlm.namespaces.filter-*.contention_seconds=0"
16841         lctl set_param -n osc.*.contention_seconds=0
16842         clear_stats osc.*.osc_stats
16843
16844         dd if=/dev/zero of=$DIR/$tfile count=0
16845         $CHECKSTAT -s 0 $DIR/$tfile
16846
16847         restore_lustre_params <$p
16848         rm -f $p
16849         rm $DIR/$tfile
16850 }
16851 run_test 216 "check lockless direct write updates file size and kms correctly"
16852
16853 test_217() { # bug 22430
16854         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16855
16856         local node
16857         local nid
16858
16859         for node in $(nodes_list); do
16860                 nid=$(host_nids_address $node $NETTYPE)
16861                 if [[ $nid = *-* ]] ; then
16862                         echo "lctl ping $(h2nettype $nid)"
16863                         lctl ping $(h2nettype $nid)
16864                 else
16865                         echo "skipping $node (no hyphen detected)"
16866                 fi
16867         done
16868 }
16869 run_test 217 "check lctl ping for hostnames with hiphen ('-')"
16870
16871 test_218() {
16872        # do directio so as not to populate the page cache
16873        log "creating a 10 Mb file"
16874        $MULTIOP $DIR/$tfile oO_CREAT:O_DIRECT:O_RDWR:w$((10*1048576))c || error "multiop failed while creating a file"
16875        log "starting reads"
16876        dd if=$DIR/$tfile of=/dev/null bs=4096 &
16877        log "truncating the file"
16878        $MULTIOP $DIR/$tfile oO_TRUNC:c || error "multiop failed while truncating the file"
16879        log "killing dd"
16880        kill %+ || true # reads might have finished
16881        echo "wait until dd is finished"
16882        wait
16883        log "removing the temporary file"
16884        rm -rf $DIR/$tfile || error "tmp file removal failed"
16885 }
16886 run_test 218 "parallel read and truncate should not deadlock"
16887
16888 test_219() {
16889         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16890
16891         # write one partial page
16892         dd if=/dev/zero of=$DIR/$tfile bs=1024 count=1
16893         # set no grant so vvp_io_commit_write will do sync write
16894         $LCTL set_param fail_loc=0x411
16895         # write a full page at the end of file
16896         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 seek=1 conv=notrunc
16897
16898         $LCTL set_param fail_loc=0
16899         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 seek=3
16900         $LCTL set_param fail_loc=0x411
16901         dd if=/dev/zero of=$DIR/$tfile bs=1024 count=1 seek=2 conv=notrunc
16902
16903         # LU-4201
16904         dd if=/dev/zero of=$DIR/$tfile-2 bs=1024 count=1
16905         $CHECKSTAT -s 1024 $DIR/$tfile-2 || error "checkstat wrong size"
16906 }
16907 run_test 219 "LU-394: Write partial won't cause uncontiguous pages vec at LND"
16908
16909 test_220() { #LU-325
16910         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16911         remote_ost_nodsh && skip "remote OST with nodsh"
16912         remote_mds_nodsh && skip "remote MDS with nodsh"
16913         remote_mgs_nodsh && skip "remote MGS with nodsh"
16914
16915         local OSTIDX=0
16916
16917         # create on MDT0000 so the last_id and next_id are correct
16918         mkdir $DIR/$tdir
16919         local OST=$($LFS df $DIR | awk '/OST:'$OSTIDX'/ { print $1 }')
16920         OST=${OST%_UUID}
16921
16922         # on the mdt's osc
16923         local mdtosc_proc1=$(get_mdtosc_proc_path $SINGLEMDS $OST)
16924         local last_id=$(do_facet $SINGLEMDS lctl get_param -n \
16925                         osp.$mdtosc_proc1.prealloc_last_id)
16926         local next_id=$(do_facet $SINGLEMDS lctl get_param -n \
16927                         osp.$mdtosc_proc1.prealloc_next_id)
16928
16929         $LFS df -i
16930
16931         do_facet ost$((OSTIDX + 1)) lctl set_param fail_val=-1
16932         #define OBD_FAIL_OST_ENOINO              0x229
16933         do_facet ost$((OSTIDX + 1)) lctl set_param fail_loc=0x229
16934         create_pool $FSNAME.$TESTNAME || return 1
16935         do_facet mgs $LCTL pool_add $FSNAME.$TESTNAME $OST || return 2
16936
16937         $LFS setstripe $DIR/$tdir -i $OSTIDX -c 1 -p $FSNAME.$TESTNAME
16938
16939         MDSOBJS=$((last_id - next_id))
16940         echo "preallocated objects on MDS is $MDSOBJS" "($last_id - $next_id)"
16941
16942         blocks=$($LFS df $MOUNT | awk '($1 == '$OSTIDX') { print $4 }')
16943         echo "OST still has $count kbytes free"
16944
16945         echo "create $MDSOBJS files @next_id..."
16946         createmany -o $DIR/$tdir/f $MDSOBJS || return 3
16947
16948         local last_id2=$(do_facet mds${MDSIDX} lctl get_param -n \
16949                         osp.$mdtosc_proc1.prealloc_last_id)
16950         local next_id2=$(do_facet mds${MDSIDX} lctl get_param -n \
16951                         osp.$mdtosc_proc1.prealloc_next_id)
16952
16953         echo "after creation, last_id=$last_id2, next_id=$next_id2"
16954         $LFS df -i
16955
16956         echo "cleanup..."
16957
16958         do_facet ost$((OSTIDX + 1)) lctl set_param fail_val=0
16959         do_facet ost$((OSTIDX + 1)) lctl set_param fail_loc=0
16960
16961         do_facet mgs $LCTL pool_remove $FSNAME.$TESTNAME $OST ||
16962                 error "$LCTL pool_remove $FSNAME.$TESTNAME $OST failed"
16963         do_facet mgs $LCTL pool_destroy $FSNAME.$TESTNAME ||
16964                 error "$LCTL pool_destroy $FSNAME.$TESTNAME failed"
16965         echo "unlink $MDSOBJS files @$next_id..."
16966         unlinkmany $DIR/$tdir/f $MDSOBJS || error "unlinkmany failed"
16967 }
16968 run_test 220 "preallocated MDS objects still used if ENOSPC from OST"
16969
16970 test_221() {
16971         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16972
16973         dd if=`which date` of=$MOUNT/date oflag=sync
16974         chmod +x $MOUNT/date
16975
16976         #define OBD_FAIL_LLITE_FAULT_TRUNC_RACE  0x1401
16977         $LCTL set_param fail_loc=0x80001401
16978
16979         $MOUNT/date > /dev/null
16980         rm -f $MOUNT/date
16981 }
16982 run_test 221 "make sure fault and truncate race to not cause OOM"
16983
16984 test_222a () {
16985         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16986
16987         rm -rf $DIR/$tdir
16988         test_mkdir $DIR/$tdir
16989         $LFS setstripe -c 1 -i 0 $DIR/$tdir
16990         createmany -o $DIR/$tdir/$tfile 10
16991         cancel_lru_locks mdc
16992         cancel_lru_locks osc
16993         #define OBD_FAIL_LDLM_AGL_DELAY           0x31a
16994         $LCTL set_param fail_loc=0x31a
16995         ls -l $DIR/$tdir > /dev/null || error "AGL for ls failed"
16996         $LCTL set_param fail_loc=0
16997         rm -r $DIR/$tdir
16998 }
16999 run_test 222a "AGL for ls should not trigger CLIO lock failure"
17000
17001 test_222b () {
17002         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17003
17004         rm -rf $DIR/$tdir
17005         test_mkdir $DIR/$tdir
17006         $LFS setstripe -c 1 -i 0 $DIR/$tdir
17007         createmany -o $DIR/$tdir/$tfile 10
17008         cancel_lru_locks mdc
17009         cancel_lru_locks osc
17010         #define OBD_FAIL_LDLM_AGL_DELAY           0x31a
17011         $LCTL set_param fail_loc=0x31a
17012         rm -r $DIR/$tdir || error "AGL for rmdir failed"
17013         $LCTL set_param fail_loc=0
17014 }
17015 run_test 222b "AGL for rmdir should not trigger CLIO lock failure"
17016
17017 test_223 () {
17018         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17019
17020         rm -rf $DIR/$tdir
17021         test_mkdir $DIR/$tdir
17022         $LFS setstripe -c 1 -i 0 $DIR/$tdir
17023         createmany -o $DIR/$tdir/$tfile 10
17024         cancel_lru_locks mdc
17025         cancel_lru_locks osc
17026         #define OBD_FAIL_LDLM_AGL_NOLOCK          0x31b
17027         $LCTL set_param fail_loc=0x31b
17028         ls -l $DIR/$tdir > /dev/null || error "reenqueue failed"
17029         $LCTL set_param fail_loc=0
17030         rm -r $DIR/$tdir
17031 }
17032 run_test 223 "osc reenqueue if without AGL lock granted ======================="
17033
17034 test_224a() { # LU-1039, MRP-303
17035         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17036
17037         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB   0x508
17038         $LCTL set_param fail_loc=0x508
17039         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 conv=fsync
17040         $LCTL set_param fail_loc=0
17041         df $DIR
17042 }
17043 run_test 224a "Don't panic on bulk IO failure"
17044
17045 test_224b() { # LU-1039, MRP-303
17046         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17047
17048         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1
17049         cancel_lru_locks osc
17050         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB2   0x515
17051         $LCTL set_param fail_loc=0x515
17052         dd of=/dev/null if=$DIR/$tfile bs=4096 count=1
17053         $LCTL set_param fail_loc=0
17054         df $DIR
17055 }
17056 run_test 224b "Don't panic on bulk IO failure"
17057
17058 test_224c() { # LU-6441
17059         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17060         remote_mds_nodsh && skip "remote MDS with nodsh"
17061
17062         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
17063         save_writethrough $p
17064         set_cache writethrough on
17065
17066         local pages_per_rpc=$($LCTL get_param osc.*.max_pages_per_rpc)
17067         local at_max=$($LCTL get_param -n at_max)
17068         local timeout=$($LCTL get_param -n timeout)
17069         local test_at="at_max"
17070         local param_at="$FSNAME.sys.at_max"
17071         local test_timeout="timeout"
17072         local param_timeout="$FSNAME.sys.timeout"
17073
17074         $LCTL set_param -n osc.*.max_pages_per_rpc=1024
17075
17076         set_persistent_param_and_check client "$test_at" "$param_at" 0
17077         set_persistent_param_and_check client "$test_timeout" "$param_timeout" 5
17078
17079         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB3 0x520
17080         do_facet ost1 "$LCTL set_param fail_loc=0x520"
17081         $LFS setstripe -c 1 -i 0 $DIR/$tfile
17082         dd if=/dev/zero of=$DIR/$tfile bs=8MB count=1
17083         sync
17084         do_facet ost1 "$LCTL set_param fail_loc=0"
17085
17086         set_persistent_param_and_check client "$test_at" "$param_at" $at_max
17087         set_persistent_param_and_check client "$test_timeout" "$param_timeout" \
17088                 $timeout
17089
17090         $LCTL set_param -n $pages_per_rpc
17091         restore_lustre_params < $p
17092         rm -f $p
17093 }
17094 run_test 224c "Don't hang if one of md lost during large bulk RPC"
17095
17096 MDSSURVEY=${MDSSURVEY:-$(which mds-survey 2>/dev/null || true)}
17097 test_225a () {
17098         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17099         if [ -z ${MDSSURVEY} ]; then
17100                 skip_env "mds-survey not found"
17101         fi
17102         [ $MDS1_VERSION -ge $(version_code 2.2.51) ] ||
17103                 skip "Need MDS version at least 2.2.51"
17104
17105         local mds=$(facet_host $SINGLEMDS)
17106         local target=$(do_nodes $mds 'lctl dl' |
17107                        awk '{ if ($2 == "UP" && $3 == "mdt") { print $4 }}')
17108
17109         local cmd1="file_count=1000 thrhi=4"
17110         local cmd2="dir_count=2 layer=mdd stripe_count=0"
17111         local cmd3="rslt_loc=${TMP} targets=\"$mds:$target\" $MDSSURVEY"
17112         local cmd="$cmd1 $cmd2 $cmd3"
17113
17114         rm -f ${TMP}/mds_survey*
17115         echo + $cmd
17116         eval $cmd || error "mds-survey with zero-stripe failed"
17117         cat ${TMP}/mds_survey*
17118         rm -f ${TMP}/mds_survey*
17119 }
17120 run_test 225a "Metadata survey sanity with zero-stripe"
17121
17122 test_225b () {
17123         if [ -z ${MDSSURVEY} ]; then
17124                 skip_env "mds-survey not found"
17125         fi
17126         [ $MDS1_VERSION -ge $(version_code 2.2.51) ] ||
17127                 skip "Need MDS version at least 2.2.51"
17128         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17129         remote_mds_nodsh && skip "remote MDS with nodsh"
17130         if [ $($LCTL dl | grep -c osc) -eq 0 ]; then
17131                 skip_env "Need to mount OST to test"
17132         fi
17133
17134         local mds=$(facet_host $SINGLEMDS)
17135         local target=$(do_nodes $mds 'lctl dl' |
17136                        awk '{ if ($2 == "UP" && $3 == "mdt") { print $4 }}')
17137
17138         local cmd1="file_count=1000 thrhi=4"
17139         local cmd2="dir_count=2 layer=mdd stripe_count=1"
17140         local cmd3="rslt_loc=${TMP} targets=\"$mds:$target\" $MDSSURVEY"
17141         local cmd="$cmd1 $cmd2 $cmd3"
17142
17143         rm -f ${TMP}/mds_survey*
17144         echo + $cmd
17145         eval $cmd || error "mds-survey with stripe_count failed"
17146         cat ${TMP}/mds_survey*
17147         rm -f ${TMP}/mds_survey*
17148 }
17149 run_test 225b "Metadata survey sanity with stripe_count = 1"
17150
17151 mcreate_path2fid () {
17152         local mode=$1
17153         local major=$2
17154         local minor=$3
17155         local name=$4
17156         local desc=$5
17157         local path=$DIR/$tdir/$name
17158         local fid
17159         local rc
17160         local fid_path
17161
17162         $MCREATE --mode=$1 --major=$2 --minor=$3 $path ||
17163                 error "cannot create $desc"
17164
17165         fid=$($LFS path2fid $path | tr -d '[' | tr -d ']')
17166         rc=$?
17167         [ $rc -ne 0 ] && error "cannot get fid of a $desc"
17168
17169         fid_path=$($LFS fid2path $MOUNT $fid)
17170         rc=$?
17171         [ $rc -ne 0 ] && error "cannot get path of $desc by $DIR $path $fid"
17172
17173         [ "$path" == "$fid_path" ] ||
17174                 error "fid2path returned $fid_path, expected $path"
17175
17176         echo "pass with $path and $fid"
17177 }
17178
17179 test_226a () {
17180         rm -rf $DIR/$tdir
17181         mkdir -p $DIR/$tdir
17182
17183         mcreate_path2fid 0010666 0 0 fifo "FIFO"
17184         mcreate_path2fid 0020666 1 3 null "character special file (null)"
17185         mcreate_path2fid 0020666 1 255 none "character special file (no device)"
17186         mcreate_path2fid 0040666 0 0 dir "directory"
17187         mcreate_path2fid 0060666 7 0 loop0 "block special file (loop)"
17188         mcreate_path2fid 0100666 0 0 file "regular file"
17189         mcreate_path2fid 0120666 0 0 link "symbolic link"
17190         mcreate_path2fid 0140666 0 0 sock "socket"
17191 }
17192 run_test 226a "call path2fid and fid2path on files of all type"
17193
17194 test_226b () {
17195         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
17196
17197         local MDTIDX=1
17198
17199         rm -rf $DIR/$tdir
17200         mkdir -p $DIR/$tdir
17201         $LFS setdirstripe -i $MDTIDX $DIR/$tdir/remote_dir ||
17202                 error "create remote directory failed"
17203         mcreate_path2fid 0010666 0 0 "remote_dir/fifo" "FIFO"
17204         mcreate_path2fid 0020666 1 3 "remote_dir/null" \
17205                                 "character special file (null)"
17206         mcreate_path2fid 0020666 1 255 "remote_dir/none" \
17207                                 "character special file (no device)"
17208         mcreate_path2fid 0040666 0 0 "remote_dir/dir" "directory"
17209         mcreate_path2fid 0060666 7 0 "remote_dir/loop0" \
17210                                 "block special file (loop)"
17211         mcreate_path2fid 0100666 0 0 "remote_dir/file" "regular file"
17212         mcreate_path2fid 0120666 0 0 "remote_dir/link" "symbolic link"
17213         mcreate_path2fid 0140666 0 0 "remote_dir/sock" "socket"
17214 }
17215 run_test 226b "call path2fid and fid2path on files of all type under remote dir"
17216
17217 # LU-1299 Executing or running ldd on a truncated executable does not
17218 # cause an out-of-memory condition.
17219 test_227() {
17220         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17221         [ -z "$(which ldd)" ] && skip_env "should have ldd tool"
17222
17223         dd if=$(which date) of=$MOUNT/date bs=1k count=1
17224         chmod +x $MOUNT/date
17225
17226         $MOUNT/date > /dev/null
17227         ldd $MOUNT/date > /dev/null
17228         rm -f $MOUNT/date
17229 }
17230 run_test 227 "running truncated executable does not cause OOM"
17231
17232 # LU-1512 try to reuse idle OI blocks
17233 test_228a() {
17234         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17235         remote_mds_nodsh && skip "remote MDS with nodsh"
17236         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
17237
17238         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
17239         local myDIR=$DIR/$tdir
17240
17241         mkdir -p $myDIR
17242         #define OBD_FAIL_SEQ_EXHAUST             0x1002
17243         $LCTL set_param fail_loc=0x80001002
17244         createmany -o $myDIR/t- 10000
17245         $LCTL set_param fail_loc=0
17246         # The guard is current the largest FID holder
17247         touch $myDIR/guard
17248         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
17249                     tr -d '[')
17250         local IDX=$(($SEQ % 64))
17251
17252         do_facet $SINGLEMDS sync
17253         # Make sure journal flushed.
17254         sleep 6
17255         local blk1=$(do_facet $SINGLEMDS \
17256                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
17257                      grep Blockcount | awk '{print $4}')
17258
17259         # Remove old files, some OI blocks will become idle.
17260         unlinkmany $myDIR/t- 10000
17261         # Create new files, idle OI blocks should be reused.
17262         createmany -o $myDIR/t- 2000
17263         do_facet $SINGLEMDS sync
17264         # Make sure journal flushed.
17265         sleep 6
17266         local blk2=$(do_facet $SINGLEMDS \
17267                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
17268                      grep Blockcount | awk '{print $4}')
17269
17270         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
17271 }
17272 run_test 228a "try to reuse idle OI blocks"
17273
17274 test_228b() {
17275         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17276         remote_mds_nodsh && skip "remote MDS with nodsh"
17277         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
17278
17279         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
17280         local myDIR=$DIR/$tdir
17281
17282         mkdir -p $myDIR
17283         #define OBD_FAIL_SEQ_EXHAUST             0x1002
17284         $LCTL set_param fail_loc=0x80001002
17285         createmany -o $myDIR/t- 10000
17286         $LCTL set_param fail_loc=0
17287         # The guard is current the largest FID holder
17288         touch $myDIR/guard
17289         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
17290                     tr -d '[')
17291         local IDX=$(($SEQ % 64))
17292
17293         do_facet $SINGLEMDS sync
17294         # Make sure journal flushed.
17295         sleep 6
17296         local blk1=$(do_facet $SINGLEMDS \
17297                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
17298                      grep Blockcount | awk '{print $4}')
17299
17300         # Remove old files, some OI blocks will become idle.
17301         unlinkmany $myDIR/t- 10000
17302
17303         # stop the MDT
17304         stop $SINGLEMDS || error "Fail to stop MDT."
17305         # remount the MDT
17306         start $SINGLEMDS $MDT_DEV $MDS_MOUNT_OPTS || error "Fail to start MDT."
17307
17308         df $MOUNT || error "Fail to df."
17309         # Create new files, idle OI blocks should be reused.
17310         createmany -o $myDIR/t- 2000
17311         do_facet $SINGLEMDS sync
17312         # Make sure journal flushed.
17313         sleep 6
17314         local blk2=$(do_facet $SINGLEMDS \
17315                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
17316                      grep Blockcount | awk '{print $4}')
17317
17318         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
17319 }
17320 run_test 228b "idle OI blocks can be reused after MDT restart"
17321
17322 #LU-1881
17323 test_228c() {
17324         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17325         remote_mds_nodsh && skip "remote MDS with nodsh"
17326         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
17327
17328         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
17329         local myDIR=$DIR/$tdir
17330
17331         mkdir -p $myDIR
17332         #define OBD_FAIL_SEQ_EXHAUST             0x1002
17333         $LCTL set_param fail_loc=0x80001002
17334         # 20000 files can guarantee there are index nodes in the OI file
17335         createmany -o $myDIR/t- 20000
17336         $LCTL set_param fail_loc=0
17337         # The guard is current the largest FID holder
17338         touch $myDIR/guard
17339         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
17340                     tr -d '[')
17341         local IDX=$(($SEQ % 64))
17342
17343         do_facet $SINGLEMDS sync
17344         # Make sure journal flushed.
17345         sleep 6
17346         local blk1=$(do_facet $SINGLEMDS \
17347                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
17348                      grep Blockcount | awk '{print $4}')
17349
17350         # Remove old files, some OI blocks will become idle.
17351         unlinkmany $myDIR/t- 20000
17352         rm -f $myDIR/guard
17353         # The OI file should become empty now
17354
17355         # Create new files, idle OI blocks should be reused.
17356         createmany -o $myDIR/t- 2000
17357         do_facet $SINGLEMDS sync
17358         # Make sure journal flushed.
17359         sleep 6
17360         local blk2=$(do_facet $SINGLEMDS \
17361                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
17362                      grep Blockcount | awk '{print $4}')
17363
17364         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
17365 }
17366 run_test 228c "NOT shrink the last entry in OI index node to recycle idle leaf"
17367
17368 test_229() { # LU-2482, LU-3448
17369         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17370         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
17371         [ $MDS1_VERSION -lt $(version_code 2.4.53) ] &&
17372                 skip "No HSM $(lustre_build_version $SINGLEMDS) MDS < 2.4.53"
17373
17374         rm -f $DIR/$tfile
17375
17376         # Create a file with a released layout and stripe count 2.
17377         $MULTIOP $DIR/$tfile H2c ||
17378                 error "failed to create file with released layout"
17379
17380         $LFS getstripe -v $DIR/$tfile
17381
17382         local pattern=$($LFS getstripe -L $DIR/$tfile)
17383         [ X"$pattern" = X"released" ] || error "pattern error ($pattern)"
17384
17385         local stripe_count=$($LFS getstripe -c $DIR/$tfile) ||
17386                 error "getstripe"
17387         [ $stripe_count -eq 2 ] || error "stripe count not 2 ($stripe_count)"
17388         stat $DIR/$tfile || error "failed to stat released file"
17389
17390         chown $RUNAS_ID $DIR/$tfile ||
17391                 error "chown $RUNAS_ID $DIR/$tfile failed"
17392
17393         chgrp $RUNAS_ID $DIR/$tfile ||
17394                 error "chgrp $RUNAS_ID $DIR/$tfile failed"
17395
17396         touch $DIR/$tfile || error "touch $DIR/$tfile failed"
17397         rm $DIR/$tfile || error "failed to remove released file"
17398 }
17399 run_test 229 "getstripe/stat/rm/attr changes work on released files"
17400
17401 test_230a() {
17402         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17403         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
17404         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
17405                 skip "Need MDS version at least 2.11.52"
17406
17407         local MDTIDX=1
17408
17409         test_mkdir $DIR/$tdir
17410         test_mkdir -i0 -c1 $DIR/$tdir/test_230_local
17411         local mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230_local)
17412         [ $mdt_idx -ne 0 ] &&
17413                 error "create local directory on wrong MDT $mdt_idx"
17414
17415         $LFS mkdir -i $MDTIDX $DIR/$tdir/test_230 ||
17416                         error "create remote directory failed"
17417         local mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230)
17418         [ $mdt_idx -ne $MDTIDX ] &&
17419                 error "create remote directory on wrong MDT $mdt_idx"
17420
17421         createmany -o $DIR/$tdir/test_230/t- 10 ||
17422                 error "create files on remote directory failed"
17423         mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230/t-0)
17424         [ $mdt_idx -ne $MDTIDX ] && error "create files on wrong MDT $mdt_idx"
17425         rm -r $DIR/$tdir || error "unlink remote directory failed"
17426 }
17427 run_test 230a "Create remote directory and files under the remote directory"
17428
17429 test_230b() {
17430         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17431         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
17432         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
17433                 skip "Need MDS version at least 2.11.52"
17434
17435         local MDTIDX=1
17436         local mdt_index
17437         local i
17438         local file
17439         local pid
17440         local stripe_count
17441         local migrate_dir=$DIR/$tdir/migrate_dir
17442         local other_dir=$DIR/$tdir/other_dir
17443
17444         test_mkdir $DIR/$tdir
17445         test_mkdir -i0 -c1 $migrate_dir
17446         test_mkdir -i0 -c1 $other_dir
17447         for ((i=0; i<10; i++)); do
17448                 mkdir -p $migrate_dir/dir_${i}
17449                 createmany -o $migrate_dir/dir_${i}/f 10 ||
17450                         error "create files under remote dir failed $i"
17451         done
17452
17453         cp /etc/passwd $migrate_dir/$tfile
17454         cp /etc/passwd $other_dir/$tfile
17455         chattr +SAD $migrate_dir
17456         chattr +SAD $migrate_dir/$tfile
17457
17458         local old_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
17459         local old_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
17460         local old_dir_mode=$(stat -c%f $migrate_dir)
17461         local old_file_mode=$(stat -c%f $migrate_dir/$tfile)
17462
17463         mkdir -p $migrate_dir/dir_default_stripe2
17464         $LFS setstripe -c 2 $migrate_dir/dir_default_stripe2
17465         $LFS setstripe -c 2 $migrate_dir/${tfile}_stripe2
17466
17467         mkdir -p $other_dir
17468         ln $migrate_dir/$tfile $other_dir/luna
17469         ln $migrate_dir/$tfile $migrate_dir/sofia
17470         ln $other_dir/$tfile $migrate_dir/david
17471         ln -s $migrate_dir/$tfile $other_dir/zachary
17472         ln -s $migrate_dir/$tfile $migrate_dir/${tfile}_ln
17473         ln -s $other_dir/$tfile $migrate_dir/${tfile}_ln_other
17474
17475         local len
17476         local lnktgt
17477
17478         # inline symlink
17479         for len in 58 59 60; do
17480                 lnktgt=$(str_repeat 'l' $len)
17481                 touch $migrate_dir/$lnktgt
17482                 ln -s $lnktgt $migrate_dir/${len}char_ln
17483         done
17484
17485         # PATH_MAX
17486         for len in 4094 4095; do
17487                 lnktgt=$(str_repeat 'l' $len)
17488                 ln -s $lnktgt $migrate_dir/${len}char_ln
17489         done
17490
17491         # NAME_MAX
17492         for len in 254 255; do
17493                 touch $migrate_dir/$(str_repeat 'l' $len)
17494         done
17495
17496         $LFS migrate -m $MDTIDX $migrate_dir ||
17497                 error "fails on migrating remote dir to MDT1"
17498
17499         echo "migratate to MDT1, then checking.."
17500         for ((i = 0; i < 10; i++)); do
17501                 for file in $(find $migrate_dir/dir_${i}); do
17502                         mdt_index=$($LFS getstripe -m $file)
17503                         # broken symlink getstripe will fail
17504                         [ $mdt_index -ne $MDTIDX ] && stat -L $file &&
17505                                 error "$file is not on MDT${MDTIDX}"
17506                 done
17507         done
17508
17509         # the multiple link file should still in MDT0
17510         mdt_index=$($LFS getstripe -m $migrate_dir/$tfile)
17511         [ $mdt_index == 0 ] ||
17512                 error "$file is not on MDT${MDTIDX}"
17513
17514         local new_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
17515         [ "$old_dir_flag" = "$new_dir_flag" ] ||
17516                 error " expect $old_dir_flag get $new_dir_flag"
17517
17518         local new_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
17519         [ "$old_file_flag" = "$new_file_flag" ] ||
17520                 error " expect $old_file_flag get $new_file_flag"
17521
17522         local new_dir_mode=$(stat -c%f $migrate_dir)
17523         [ "$old_dir_mode" = "$new_dir_mode" ] ||
17524                 error "expect mode $old_dir_mode get $new_dir_mode"
17525
17526         local new_file_mode=$(stat -c%f $migrate_dir/$tfile)
17527         [ "$old_file_mode" = "$new_file_mode" ] ||
17528                 error "expect mode $old_file_mode get $new_file_mode"
17529
17530         diff /etc/passwd $migrate_dir/$tfile ||
17531                 error "$tfile different after migration"
17532
17533         diff /etc/passwd $other_dir/luna ||
17534                 error "luna different after migration"
17535
17536         diff /etc/passwd $migrate_dir/sofia ||
17537                 error "sofia different after migration"
17538
17539         diff /etc/passwd $migrate_dir/david ||
17540                 error "david different after migration"
17541
17542         diff /etc/passwd $other_dir/zachary ||
17543                 error "zachary different after migration"
17544
17545         diff /etc/passwd $migrate_dir/${tfile}_ln ||
17546                 error "${tfile}_ln different after migration"
17547
17548         diff /etc/passwd $migrate_dir/${tfile}_ln_other ||
17549                 error "${tfile}_ln_other different after migration"
17550
17551         stripe_count=$($LFS getstripe -c $migrate_dir/dir_default_stripe2)
17552         [ $stripe_count = 2 ] ||
17553                 error "dir strpe_count $d != 2 after migration."
17554
17555         stripe_count=$($LFS getstripe -c $migrate_dir/${tfile}_stripe2)
17556         [ $stripe_count = 2 ] ||
17557                 error "file strpe_count $d != 2 after migration."
17558
17559         #migrate back to MDT0
17560         MDTIDX=0
17561
17562         $LFS migrate -m $MDTIDX $migrate_dir ||
17563                 error "fails on migrating remote dir to MDT0"
17564
17565         echo "migrate back to MDT0, checking.."
17566         for file in $(find $migrate_dir); do
17567                 mdt_index=$($LFS getstripe -m $file)
17568                 [ $mdt_index -ne $MDTIDX ] && stat -L $file &&
17569                         error "$file is not on MDT${MDTIDX}"
17570         done
17571
17572         local new_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
17573         [ "$old_dir_flag" = "$new_dir_flag" ] ||
17574                 error " expect $old_dir_flag get $new_dir_flag"
17575
17576         local new_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
17577         [ "$old_file_flag" = "$new_file_flag" ] ||
17578                 error " expect $old_file_flag get $new_file_flag"
17579
17580         local new_dir_mode=$(stat -c%f $migrate_dir)
17581         [ "$old_dir_mode" = "$new_dir_mode" ] ||
17582                 error "expect mode $old_dir_mode get $new_dir_mode"
17583
17584         local new_file_mode=$(stat -c%f $migrate_dir/$tfile)
17585         [ "$old_file_mode" = "$new_file_mode" ] ||
17586                 error "expect mode $old_file_mode get $new_file_mode"
17587
17588         diff /etc/passwd ${migrate_dir}/$tfile ||
17589                 error "$tfile different after migration"
17590
17591         diff /etc/passwd ${other_dir}/luna ||
17592                 error "luna different after migration"
17593
17594         diff /etc/passwd ${migrate_dir}/sofia ||
17595                 error "sofia different after migration"
17596
17597         diff /etc/passwd ${other_dir}/zachary ||
17598                 error "zachary different after migration"
17599
17600         diff /etc/passwd $migrate_dir/${tfile}_ln ||
17601                 error "${tfile}_ln different after migration"
17602
17603         diff /etc/passwd $migrate_dir/${tfile}_ln_other ||
17604                 error "${tfile}_ln_other different after migration"
17605
17606         stripe_count=$($LFS getstripe -c ${migrate_dir}/dir_default_stripe2)
17607         [ $stripe_count = 2 ] ||
17608                 error "dir strpe_count $d != 2 after migration."
17609
17610         stripe_count=$($LFS getstripe -c ${migrate_dir}/${tfile}_stripe2)
17611         [ $stripe_count = 2 ] ||
17612                 error "file strpe_count $d != 2 after migration."
17613
17614         rm -rf $DIR/$tdir || error "rm dir failed after migration"
17615 }
17616 run_test 230b "migrate directory"
17617
17618 test_230c() {
17619         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17620         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
17621         remote_mds_nodsh && skip "remote MDS with nodsh"
17622         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
17623                 skip "Need MDS version at least 2.11.52"
17624
17625         local MDTIDX=1
17626         local total=3
17627         local mdt_index
17628         local file
17629         local migrate_dir=$DIR/$tdir/migrate_dir
17630
17631         #If migrating directory fails in the middle, all entries of
17632         #the directory is still accessiable.
17633         test_mkdir $DIR/$tdir
17634         test_mkdir -i0 -c1 $migrate_dir
17635         test_mkdir -i1 -c1 $DIR/$tdir/remote_dir
17636         stat $migrate_dir
17637         createmany -o $migrate_dir/f $total ||
17638                 error "create files under ${migrate_dir} failed"
17639
17640         # fail after migrating top dir, and this will fail only once, so the
17641         # first sub file migration will fail (currently f3), others succeed.
17642         #OBD_FAIL_MIGRATE_ENTRIES       0x1801
17643         do_facet mds1 lctl set_param fail_loc=0x1801
17644         local t=$(ls $migrate_dir | wc -l)
17645         $LFS migrate --mdt-index $MDTIDX $migrate_dir &&
17646                 error "migrate should fail"
17647         local u=$(ls $migrate_dir | wc -l)
17648         [ "$u" == "$t" ] || error "$u != $t during migration"
17649
17650         # add new dir/file should succeed
17651         mkdir $migrate_dir/dir ||
17652                 error "mkdir failed under migrating directory"
17653         touch $migrate_dir/file ||
17654                 error "create file failed under migrating directory"
17655
17656         # add file with existing name should fail
17657         for file in $migrate_dir/f*; do
17658                 stat $file > /dev/null || error "stat $file failed"
17659                 $OPENFILE -f O_CREAT:O_EXCL $file &&
17660                         error "open(O_CREAT|O_EXCL) $file should fail"
17661                 $MULTIOP $file m && error "create $file should fail"
17662                 touch $DIR/$tdir/remote_dir/$tfile ||
17663                         error "touch $tfile failed"
17664                 ln $DIR/$tdir/remote_dir/$tfile $file &&
17665                         error "link $file should fail"
17666                 mdt_index=$($LFS getstripe -m $file)
17667                 if [ $mdt_index == 0 ]; then
17668                         # file failed to migrate is not allowed to rename to
17669                         mv $DIR/$tdir/remote_dir/$tfile $file &&
17670                                 error "rename to $file should fail"
17671                 else
17672                         mv $DIR/$tdir/remote_dir/$tfile $file ||
17673                                 error "rename to $file failed"
17674                 fi
17675                 echo hello >> $file || error "write $file failed"
17676         done
17677
17678         # resume migration with different options should fail
17679         $LFS migrate -m 0 $migrate_dir &&
17680                 error "migrate -m 0 $migrate_dir should fail"
17681
17682         $LFS migrate -m $MDTIDX -c 2 $migrate_dir &&
17683                 error "migrate -c 2 $migrate_dir should fail"
17684
17685         # resume migration should succeed
17686         $LFS migrate -m $MDTIDX $migrate_dir ||
17687                 error "migrate $migrate_dir failed"
17688
17689         echo "Finish migration, then checking.."
17690         for file in $(find $migrate_dir); do
17691                 mdt_index=$($LFS getstripe -m $file)
17692                 [ $mdt_index == $MDTIDX ] ||
17693                         error "$file is not on MDT${MDTIDX}"
17694         done
17695
17696         rm -rf $DIR/$tdir || error "rm dir failed after migration"
17697 }
17698 run_test 230c "check directory accessiblity if migration failed"
17699
17700 test_230d() {
17701         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17702         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
17703         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
17704                 skip "Need MDS version at least 2.11.52"
17705         # LU-11235
17706         [ "$mds1_FSTYPE" == "zfs" ] && skip "skip ZFS backend"
17707
17708         local migrate_dir=$DIR/$tdir/migrate_dir
17709         local old_index
17710         local new_index
17711         local old_count
17712         local new_count
17713         local new_hash
17714         local mdt_index
17715         local i
17716         local j
17717
17718         old_index=$((RANDOM % MDSCOUNT))
17719         old_count=$((MDSCOUNT - old_index))
17720         new_index=$((RANDOM % MDSCOUNT))
17721         new_count=$((MDSCOUNT - new_index))
17722         new_hash=1 # for all_char
17723
17724         [ $old_count -gt 1 ] && old_count=$((old_count - RANDOM % old_count))
17725         [ $new_count -gt 1 ] && new_count=$((new_count - RANDOM % new_count))
17726
17727         test_mkdir $DIR/$tdir
17728         test_mkdir -i $old_index -c $old_count $migrate_dir
17729
17730         for ((i=0; i<100; i++)); do
17731                 test_mkdir -i0 -c1 $migrate_dir/dir_${i}
17732                 createmany -o $migrate_dir/dir_${i}/f 100 ||
17733                         error "create files under remote dir failed $i"
17734         done
17735
17736         echo -n "Migrate from MDT$old_index "
17737         [ $old_count -gt 1 ] && echo -n "... MDT$((old_index + old_count - 1)) "
17738         echo -n "to MDT$new_index"
17739         [ $new_count -gt 1 ] && echo -n " ... MDT$((new_index + new_count - 1))"
17740         echo
17741
17742         echo "$LFS migrate -m$new_index -c$new_count -H $new_hash $migrate_dir"
17743         $LFS migrate -m $new_index -c $new_count -H $new_hash $migrate_dir ||
17744                 error "migrate remote dir error"
17745
17746         echo "Finish migration, then checking.."
17747         for file in $(find $migrate_dir); do
17748                 mdt_index=$($LFS getstripe -m $file)
17749                 if [ $mdt_index -lt $new_index ] ||
17750                    [ $mdt_index -gt $((new_index + new_count - 1)) ]; then
17751                         error "$file is on MDT$mdt_index"
17752                 fi
17753         done
17754
17755         rm -rf $DIR/$tdir || error "rm dir failed after migration"
17756 }
17757 run_test 230d "check migrate big directory"
17758
17759 test_230e() {
17760         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17761         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
17762         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
17763                 skip "Need MDS version at least 2.11.52"
17764
17765         local i
17766         local j
17767         local a_fid
17768         local b_fid
17769
17770         mkdir -p $DIR/$tdir
17771         mkdir $DIR/$tdir/migrate_dir
17772         mkdir $DIR/$tdir/other_dir
17773         touch $DIR/$tdir/migrate_dir/a
17774         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/b
17775         ls $DIR/$tdir/other_dir
17776
17777         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
17778                 error "migrate dir fails"
17779
17780         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir)
17781         [ $mdt_index == 1 ] || error "migrate_dir is not on MDT1"
17782
17783         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
17784         [ $mdt_index == 0 ] || error "a is not on MDT0"
17785
17786         $LFS migrate -m 1 $DIR/$tdir/other_dir ||
17787                 error "migrate dir fails"
17788
17789         mdt_index=$($LFS getstripe -m $DIR/$tdir/other_dir)
17790         [ $mdt_index == 1 ] || error "other_dir is not on MDT1"
17791
17792         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
17793         [ $mdt_index == 1 ] || error "a is not on MDT1"
17794
17795         mdt_index=$($LFS getstripe -m $DIR/$tdir/other_dir/b)
17796         [ $mdt_index == 1 ] || error "b is not on MDT1"
17797
17798         a_fid=$($LFS path2fid $DIR/$tdir/migrate_dir/a)
17799         b_fid=$($LFS path2fid $DIR/$tdir/other_dir/b)
17800
17801         [ "$a_fid" = "$b_fid" ] || error "different fid after migration"
17802
17803         rm -rf $DIR/$tdir || error "rm dir failed after migration"
17804 }
17805 run_test 230e "migrate mulitple local link files"
17806
17807 test_230f() {
17808         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17809         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
17810         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
17811                 skip "Need MDS version at least 2.11.52"
17812
17813         local a_fid
17814         local ln_fid
17815
17816         mkdir -p $DIR/$tdir
17817         mkdir $DIR/$tdir/migrate_dir
17818         $LFS mkdir -i1 $DIR/$tdir/other_dir
17819         touch $DIR/$tdir/migrate_dir/a
17820         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/ln1
17821         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/ln2
17822         ls $DIR/$tdir/other_dir
17823
17824         # a should be migrated to MDT1, since no other links on MDT0
17825         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
17826                 error "#1 migrate dir fails"
17827         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir)
17828         [ $mdt_index == 1 ] || error "migrate_dir is not on MDT1"
17829         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
17830         [ $mdt_index == 1 ] || error "a is not on MDT1"
17831
17832         # a should stay on MDT1, because it is a mulitple link file
17833         $LFS migrate -m 0 $DIR/$tdir/migrate_dir ||
17834                 error "#2 migrate dir fails"
17835         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
17836         [ $mdt_index == 1 ] || error "a is not on MDT1"
17837
17838         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
17839                 error "#3 migrate dir fails"
17840
17841         a_fid=$($LFS path2fid $DIR/$tdir/migrate_dir/a)
17842         ln_fid=$($LFS path2fid $DIR/$tdir/other_dir/ln1)
17843         [ "$a_fid" = "$ln_fid" ] || error "different fid after migrate to MDT1"
17844
17845         rm -rf $DIR/$tdir/other_dir/ln1 || error "unlink ln1 fails"
17846         rm -rf $DIR/$tdir/other_dir/ln2 || error "unlink ln2 fails"
17847
17848         # a should be migrated to MDT0, since no other links on MDT1
17849         $LFS migrate -m 0 $DIR/$tdir/migrate_dir ||
17850                 error "#4 migrate dir fails"
17851         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
17852         [ $mdt_index == 0 ] || error "a is not on MDT0"
17853
17854         rm -rf $DIR/$tdir || error "rm dir failed after migration"
17855 }
17856 run_test 230f "migrate mulitple remote link files"
17857
17858 test_230g() {
17859         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17860         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
17861         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
17862                 skip "Need MDS version at least 2.11.52"
17863
17864         mkdir -p $DIR/$tdir/migrate_dir
17865
17866         $LFS migrate -m 1000 $DIR/$tdir/migrate_dir &&
17867                 error "migrating dir to non-exist MDT succeeds"
17868         true
17869 }
17870 run_test 230g "migrate dir to non-exist MDT"
17871
17872 test_230h() {
17873         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17874         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
17875         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
17876                 skip "Need MDS version at least 2.11.52"
17877
17878         local mdt_index
17879
17880         mkdir -p $DIR/$tdir/migrate_dir
17881
17882         $LFS migrate -m1 $DIR &&
17883                 error "migrating mountpoint1 should fail"
17884
17885         $LFS migrate -m1 $DIR/$tdir/.. &&
17886                 error "migrating mountpoint2 should fail"
17887
17888         # same as mv
17889         $LFS migrate -m1 $DIR/$tdir/migrate_dir/.. &&
17890                 error "migrating $tdir/migrate_dir/.. should fail"
17891
17892         true
17893 }
17894 run_test 230h "migrate .. and root"
17895
17896 test_230i() {
17897         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17898         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
17899         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
17900                 skip "Need MDS version at least 2.11.52"
17901
17902         mkdir -p $DIR/$tdir/migrate_dir
17903
17904         $LFS migrate -m 1 $DIR/$tdir/migrate_dir/ ||
17905                 error "migration fails with a tailing slash"
17906
17907         $LFS migrate -m 0 $DIR/$tdir/migrate_dir// ||
17908                 error "migration fails with two tailing slashes"
17909 }
17910 run_test 230i "lfs migrate -m tolerates trailing slashes"
17911
17912 test_230j() {
17913         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
17914         [ $MDS1_VERSION -lt $(version_code 2.13.52) ] &&
17915                 skip "Need MDS version at least 2.11.52"
17916
17917         $LFS mkdir -m 0 -c 1 $DIR/$tdir || error "mkdir $tdir failed"
17918         $LFS setstripe -E 1M -L mdt $DIR/$tdir/$tfile ||
17919                 error "create $tfile failed"
17920         cat /etc/passwd > $DIR/$tdir/$tfile
17921
17922         $LFS migrate -m 1 $DIR/$tdir || error "migrate failed"
17923
17924         cmp /etc/passwd $DIR/$tdir/$tfile ||
17925                 error "DoM file mismatch after migration"
17926 }
17927 run_test 230j "DoM file data not changed after dir migration"
17928
17929 test_230k() {
17930         [ $MDSCOUNT -lt 4 ] && skip "needs >= 4 MDTs"
17931         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
17932                 skip "Need MDS version at least 2.11.56"
17933
17934         local total=20
17935         local files_on_starting_mdt=0
17936
17937         $LFS mkdir -i -1 -c 2 $DIR/$tdir || error "mkdir failed"
17938         $LFS getdirstripe $DIR/$tdir
17939         for i in $(seq $total); do
17940                 echo $((i*i - i)) > $DIR/$tdir/$tfile.$i || error "write failed"
17941                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 0 ]] &&
17942                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
17943         done
17944
17945         echo "$files_on_starting_mdt files on MDT0"
17946
17947         $LFS migrate -m 1,3 $DIR/$tdir || error "migrate -m 1,3 failed"
17948         $LFS getdirstripe $DIR/$tdir
17949
17950         files_on_starting_mdt=0
17951         for i in $(seq $total); do
17952                 $(echo $((i*i - i)) | cmp $DIR/$tdir/$tfile.$i -) ||
17953                         error "file $tfile.$i mismatch after migration"
17954                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 1 ]] &&
17955                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
17956         done
17957
17958         echo "$files_on_starting_mdt files on MDT1 after migration"
17959         [[ $files_on_starting_mdt -eq $total ]] && error "all files on MDT1"
17960
17961         $LFS migrate -m 0 -c 2 $DIR/$tdir || error "migrate -m 0 -c 2 failed"
17962         $LFS getdirstripe $DIR/$tdir
17963
17964         files_on_starting_mdt=0
17965         for i in $(seq $total); do
17966                 $(echo $((i*i - i)) | cmp $DIR/$tdir/$tfile.$i -) ||
17967                         error "file $tfile.$i mismatch after 2nd migration"
17968                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 0 ]] &&
17969                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
17970         done
17971
17972         echo "$files_on_starting_mdt files on MDT0 after 2nd migration"
17973         [[ $files_on_starting_mdt -eq $total ]] && error "all files on MDT0"
17974
17975         true
17976 }
17977 run_test 230k "file data not changed after dir migration"
17978
17979 test_230l() {
17980         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
17981         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
17982                 skip "Need MDS version at least 2.11.56"
17983
17984         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "mkdir failed"
17985         createmany -o $DIR/$tdir/f___________________________________ 1000 ||
17986                 error "create files under remote dir failed $i"
17987         $LFS migrate -m 1 $DIR/$tdir || error "migrate failed"
17988 }
17989 run_test 230l "readdir between MDTs won't crash"
17990
17991 test_230m() {
17992         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
17993         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
17994                 skip "Need MDS version at least 2.11.56"
17995
17996         local MDTIDX=1
17997         local mig_dir=$DIR/$tdir/migrate_dir
17998         local longstr="aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
17999         local shortstr="b"
18000         local val
18001
18002         echo "Creating files and dirs with xattrs"
18003         test_mkdir $DIR/$tdir
18004         test_mkdir -i0 -c1 $mig_dir
18005         mkdir $mig_dir/dir
18006         setfattr -n user.attr1 -v $longstr $mig_dir/dir ||
18007                 error "cannot set xattr attr1 on dir"
18008         setfattr -n user.attr2 -v $shortstr $mig_dir/dir ||
18009                 error "cannot set xattr attr2 on dir"
18010         touch $mig_dir/dir/f0
18011         setfattr -n user.attr1 -v $longstr $mig_dir/dir/f0 ||
18012                 error "cannot set xattr attr1 on file"
18013         setfattr -n user.attr2 -v $shortstr $mig_dir/dir/f0 ||
18014                 error "cannot set xattr attr2 on file"
18015         sync ; sync ; echo 3 > /proc/sys/vm/drop_caches
18016         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir 2>/dev/null)
18017         [ "$val" = $longstr ] || error "xattr attr1 not set properly on dir"
18018         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir 2>/dev/null)
18019         [ "$val" = $shortstr ] || error "xattr attr2 not set properly on dir"
18020         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir/f0 2>/dev/null)
18021         [ "$val" = $longstr ] || error "xattr attr1 not set properly on file"
18022         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir/f0 2>/dev/null)
18023         [ "$val" = $shortstr ] || error "xattr attr2 not set properly on file"
18024
18025         echo "Migrating to MDT1"
18026         $LFS migrate -m $MDTIDX $mig_dir ||
18027                 error "fails on migrating dir to MDT1"
18028
18029         sync ; sync ; echo 3 > /proc/sys/vm/drop_caches
18030         echo "Checking xattrs"
18031         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir 2>/dev/null)
18032         [ "$val" = $longstr ] ||
18033                 error "expecting xattr1 $longstr on dir, found $val"
18034         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir 2>/dev/null)
18035         [ "$val" = $shortstr ] ||
18036                 error "expecting xattr2 $shortstr on dir, found $val"
18037         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir/f0 2>/dev/null)
18038         [ "$val" = $longstr ] ||
18039                 error "expecting xattr1 $longstr on file, found $val"
18040         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir/f0 2>/dev/null)
18041         [ "$val" = $shortstr ] ||
18042                 error "expecting xattr2 $shortstr on file, found $val"
18043 }
18044 run_test 230m "xattrs not changed after dir migration"
18045
18046 test_230n() {
18047         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
18048         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
18049                 skip "Need MDS version at least 2.13.53"
18050
18051         $LFS mkdir -i 0 $DIR/$tdir || error "mkdir $tdir failed"
18052         cat /etc/hosts > $DIR/$tdir/$tfile
18053         $LFS mirror extend -N1 $DIR/$tdir/$tfile || error "Mirroring failed"
18054         $LFS migrate -m 1 $DIR/$tdir || error "Migration failed"
18055
18056         cmp /etc/hosts $DIR/$tdir/$tfile ||
18057                 error "File data mismatch after migration"
18058 }
18059 run_test 230n "Dir migration with mirrored file"
18060
18061 test_230o() {
18062         [ $MDSCOUNT -ge 2 ] || skip "needs >= 2 MDTs"
18063         [ $MDS1_VERSION -ge $(version_code 2.13.52) ] ||
18064                 skip "Need MDS version at least 2.13.52"
18065
18066         local mdts=$(comma_list $(mdts_nodes))
18067         local timeout=100
18068
18069         local restripe_status
18070         local delta
18071         local i
18072         local j
18073
18074         [[ $(facet_fstype mds1) == zfs ]] && timeout=300
18075
18076         # in case "crush" hash type is not set
18077         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
18078
18079         restripe_status=$(do_facet mds1 $LCTL get_param -n \
18080                            mdt.*MDT0000.enable_dir_restripe)
18081         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=1"
18082         stack_trap "do_nodes $mdts $LCTL set_param \
18083                     mdt.*.enable_dir_restripe=$restripe_status"
18084
18085         mkdir $DIR/$tdir
18086         createmany -m $DIR/$tdir/f 100 ||
18087                 error "create files under remote dir failed $i"
18088         createmany -d $DIR/$tdir/d 100 ||
18089                 error "create dirs under remote dir failed $i"
18090
18091         for i in $(seq 2 $MDSCOUNT); do
18092                 do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear > /dev/null"
18093                 $LFS setdirstripe -c $i $DIR/$tdir ||
18094                         error "split -c $i $tdir failed"
18095                 wait_update $HOSTNAME \
18096                         "$LFS getdirstripe -H $DIR/$tdir" "crush" $timeout ||
18097                         error "dir split not finished"
18098                 delta=$(do_nodes $mdts "lctl get_param -n mdt.*MDT*.md_stats" |
18099                         awk '/migrate/ {sum += $2} END { print sum }')
18100                 echo "$delta files migrated when dir split from $((i - 1)) to $i stripes"
18101                 # delta is around total_files/stripe_count
18102                 [ $delta -lt $((200 /(i - 1))) ] ||
18103                         error "$delta files migrated"
18104         done
18105 }
18106 run_test 230o "dir split"
18107
18108 test_230p() {
18109         [ $MDSCOUNT -ge 2 ] || skip "needs >= 2 MDTs"
18110         [ $MDS1_VERSION -ge $(version_code 2.13.52) ] ||
18111                 skip "Need MDS version at least 2.13.52"
18112
18113         local mdts=$(comma_list $(mdts_nodes))
18114         local timeout=100
18115
18116         local restripe_status
18117         local delta
18118         local i
18119         local j
18120
18121         [[ $(facet_fstype mds1) == zfs ]] && timeout=300
18122
18123         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
18124
18125         restripe_status=$(do_facet mds1 $LCTL get_param -n \
18126                            mdt.*MDT0000.enable_dir_restripe)
18127         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=1"
18128         stack_trap "do_nodes $mdts $LCTL set_param \
18129                     mdt.*.enable_dir_restripe=$restripe_status"
18130
18131         test_mkdir -c $MDSCOUNT -H crush $DIR/$tdir
18132         createmany -m $DIR/$tdir/f 100 ||
18133                 error "create files under remote dir failed $i"
18134         createmany -d $DIR/$tdir/d 100 ||
18135                 error "create dirs under remote dir failed $i"
18136
18137         for i in $(seq $((MDSCOUNT - 1)) -1 1); do
18138                 local mdt_hash="crush"
18139
18140                 do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear > /dev/null"
18141                 $LFS setdirstripe -c $i $DIR/$tdir ||
18142                         error "split -c $i $tdir failed"
18143                 [ $i -eq 1 ] && mdt_hash="none"
18144                 wait_update $HOSTNAME \
18145                         "$LFS getdirstripe -H $DIR/$tdir" $mdt_hash $timeout ||
18146                         error "dir merge not finished"
18147                 delta=$(do_nodes $mdts "lctl get_param -n mdt.*MDT*.md_stats" |
18148                         awk '/migrate/ {sum += $2} END { print sum }')
18149                 echo "$delta files migrated when dir merge from $((i + 1)) to $i stripes"
18150                 # delta is around total_files/stripe_count
18151                 [ $delta -lt $((200 / i)) ] ||
18152                         error "$delta files migrated"
18153         done
18154 }
18155 run_test 230p "dir merge"
18156
18157 test_230q() {
18158         [ $MDSCOUNT -ge 2 ] || skip "needs >= 2 MDTs"
18159         [ $MDS1_VERSION -ge $(version_code 2.13.52) ] ||
18160                 skip "Need MDS version at least 2.13.52"
18161
18162         local mdts=$(comma_list $(mdts_nodes))
18163         local saved_threshold=$(do_facet mds1 \
18164                         $LCTL get_param -n mdt.*-MDT0000.dir_split_count)
18165         local saved_delta=$(do_facet mds1 \
18166                         $LCTL get_param -n mdt.*-MDT0000.dir_split_delta)
18167         local threshold=100
18168         local delta=2
18169         local total=0
18170         local stripe_count=0
18171         local stripe_index
18172         local nr_files
18173
18174         stack_trap "do_nodes $mdts $LCTL set_param \
18175                     mdt.*.dir_split_count=$saved_threshold"
18176         stack_trap "do_nodes $mdts $LCTL set_param \
18177                     mdt.*.dir_split_delta=$saved_delta"
18178         stack_trap "do_nodes $mdts $LCTL set_param mdt.*.dir_restripe_nsonly=1"
18179         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_auto_split=1"
18180         do_nodes $mdts "$LCTL set_param mdt.*.dir_split_count=$threshold"
18181         do_nodes $mdts "$LCTL set_param mdt.*.dir_split_delta=$delta"
18182         do_nodes $mdts "$LCTL set_param mdt.*.dir_restripe_nsonly=0"
18183         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
18184
18185         $LFS mkdir -i -1 -c 1 $DIR/$tdir || error "mkdir $tdir failed"
18186         stripe_index=$($LFS getdirstripe -i $DIR/$tdir)
18187
18188         while [ $stripe_count -lt $MDSCOUNT ]; do
18189                 createmany -m $DIR/$tdir/f $total $((threshold * 3 / 2)) ||
18190                         error "create sub files failed"
18191                 stat $DIR/$tdir > /dev/null
18192                 total=$((total + threshold * 3 / 2))
18193                 stripe_count=$((stripe_count + delta))
18194                 [ $stripe_count -gt $MDSCOUNT ] && stripe_count=$MDSCOUNT
18195
18196                 wait_update $HOSTNAME \
18197                         "$LFS getdirstripe -c $DIR/$tdir" "$stripe_count" 40 ||
18198                         error "stripe count $($LFS getdirstripe -c $DIR/$tdir) != $stripe_count"
18199
18200                 wait_update $HOSTNAME \
18201                         "$LFS getdirstripe -H $DIR/$tdir" "crush" 200 ||
18202                         error "stripe hash $($LFS getdirstripe -H $DIR/$tdir) != crush"
18203
18204                 nr_files=$($LFS getstripe -m $DIR/$tdir/* |
18205                            grep -w $stripe_index | wc -l)
18206                 echo "$nr_files files on MDT$stripe_index after split"
18207                 [ $nr_files -lt $((total / (stripe_count - 1))) ] ||
18208                         error "$nr_files files on MDT$stripe_index after split"
18209
18210                 nr_files=$(ls $DIR/$tdir | wc -w)
18211                 [ $nr_files -eq $total ] ||
18212                         error "total sub files $nr_files != $total"
18213         done
18214 }
18215 run_test 230q "dir auto split"
18216
18217 test_231a()
18218 {
18219         # For simplicity this test assumes that max_pages_per_rpc
18220         # is the same across all OSCs
18221         local max_pages=$($LCTL get_param -n osc.*.max_pages_per_rpc | head -n1)
18222         local bulk_size=$((max_pages * PAGE_SIZE))
18223         local brw_size=$(do_facet ost1 $LCTL get_param -n obdfilter.*.brw_size |
18224                                        head -n 1)
18225
18226         mkdir -p $DIR/$tdir
18227         $LFS setstripe -S ${brw_size}M $DIR/$tdir ||
18228                 error "failed to set stripe with -S ${brw_size}M option"
18229
18230         # clear the OSC stats
18231         $LCTL set_param osc.*.stats=0 &>/dev/null
18232         stop_writeback
18233
18234         # Client writes $bulk_size - there must be 1 rpc for $max_pages.
18235         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=$bulk_size count=1 \
18236                 oflag=direct &>/dev/null || error "dd failed"
18237
18238         sync; sleep 1; sync # just to be safe
18239         local nrpcs=$($LCTL get_param osc.*.stats |awk '/ost_write/ {print $2}')
18240         if [ x$nrpcs != "x1" ]; then
18241                 $LCTL get_param osc.*.stats
18242                 error "found $nrpcs ost_write RPCs, not 1 as expected"
18243         fi
18244
18245         start_writeback
18246         # Drop the OSC cache, otherwise we will read from it
18247         cancel_lru_locks osc
18248
18249         # clear the OSC stats
18250         $LCTL set_param osc.*.stats=0 &>/dev/null
18251
18252         # Client reads $bulk_size.
18253         dd if=$DIR/$tdir/$tfile of=/dev/null bs=$bulk_size count=1 \
18254                 iflag=direct &>/dev/null || error "dd failed"
18255
18256         nrpcs=$($LCTL get_param osc.*.stats | awk '/ost_read/ { print $2 }')
18257         if [ x$nrpcs != "x1" ]; then
18258                 $LCTL get_param osc.*.stats
18259                 error "found $nrpcs ost_read RPCs, not 1 as expected"
18260         fi
18261 }
18262 run_test 231a "checking that reading/writing of BRW RPC size results in one RPC"
18263
18264 test_231b() {
18265         mkdir -p $DIR/$tdir
18266         local i
18267         for i in {0..1023}; do
18268                 dd if=/dev/zero of=$DIR/$tdir/$tfile conv=notrunc \
18269                         seek=$((2 * i)) bs=4096 count=1 &>/dev/null ||
18270                         error "dd of=$DIR/$tdir/$tfile seek=$((2 * i)) failed"
18271         done
18272         sync
18273 }
18274 run_test 231b "must not assert on fully utilized OST request buffer"
18275
18276 test_232a() {
18277         mkdir -p $DIR/$tdir
18278         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
18279
18280         #define OBD_FAIL_LDLM_OST_LVB            0x31c
18281         do_facet ost1 $LCTL set_param fail_loc=0x31c
18282
18283         # ignore dd failure
18284         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=1 || true
18285
18286         do_facet ost1 $LCTL set_param fail_loc=0
18287         umount_client $MOUNT || error "umount failed"
18288         mount_client $MOUNT || error "mount failed"
18289         stop ost1 || error "cannot stop ost1"
18290         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
18291 }
18292 run_test 232a "failed lock should not block umount"
18293
18294 test_232b() {
18295         [ $MDS1_VERSION -ge $(version_code 2.10.58) ] ||
18296                 skip "Need MDS version at least 2.10.58"
18297
18298         mkdir -p $DIR/$tdir
18299         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
18300         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=1
18301         sync
18302         cancel_lru_locks osc
18303
18304         #define OBD_FAIL_LDLM_OST_LVB            0x31c
18305         do_facet ost1 $LCTL set_param fail_loc=0x31c
18306
18307         # ignore failure
18308         $LFS data_version $DIR/$tdir/$tfile || true
18309
18310         do_facet ost1 $LCTL set_param fail_loc=0
18311         umount_client $MOUNT || error "umount failed"
18312         mount_client $MOUNT || error "mount failed"
18313         stop ost1 || error "cannot stop ost1"
18314         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
18315 }
18316 run_test 232b "failed data version lock should not block umount"
18317
18318 test_233a() {
18319         [ $MDS1_VERSION -ge $(version_code 2.3.64) ] ||
18320                 skip "Need MDS version at least 2.3.64"
18321         [ -n "$FILESET" ] && skip_env "SKIP due to FILESET set"
18322
18323         local fid=$($LFS path2fid $MOUNT)
18324
18325         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
18326                 error "cannot access $MOUNT using its FID '$fid'"
18327 }
18328 run_test 233a "checking that OBF of the FS root succeeds"
18329
18330 test_233b() {
18331         [ $MDS1_VERSION -ge $(version_code 2.5.90) ] ||
18332                 skip "Need MDS version at least 2.5.90"
18333         [ -n "$FILESET" ] && skip_env "SKIP due to FILESET set"
18334
18335         local fid=$($LFS path2fid $MOUNT/.lustre)
18336
18337         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
18338                 error "cannot access $MOUNT/.lustre using its FID '$fid'"
18339
18340         fid=$($LFS path2fid $MOUNT/.lustre/fid)
18341         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
18342                 error "cannot access $MOUNT/.lustre/fid using its FID '$fid'"
18343 }
18344 run_test 233b "checking that OBF of the FS .lustre succeeds"
18345
18346 test_234() {
18347         local p="$TMP/sanityN-$TESTNAME.parameters"
18348         save_lustre_params client "llite.*.xattr_cache" > $p
18349         lctl set_param llite.*.xattr_cache 1 ||
18350                 skip_env "xattr cache is not supported"
18351
18352         mkdir -p $DIR/$tdir || error "mkdir failed"
18353         touch $DIR/$tdir/$tfile || error "touch failed"
18354         # OBD_FAIL_LLITE_XATTR_ENOMEM
18355         $LCTL set_param fail_loc=0x1405
18356         getfattr -n user.attr $DIR/$tdir/$tfile &&
18357                 error "getfattr should have failed with ENOMEM"
18358         $LCTL set_param fail_loc=0x0
18359         rm -rf $DIR/$tdir
18360
18361         restore_lustre_params < $p
18362         rm -f $p
18363 }
18364 run_test 234 "xattr cache should not crash on ENOMEM"
18365
18366 test_235() {
18367         [ $MDS1_VERSION -lt $(version_code 2.4.52) ] &&
18368                 skip "Need MDS version at least 2.4.52"
18369
18370         flock_deadlock $DIR/$tfile
18371         local RC=$?
18372         case $RC in
18373                 0)
18374                 ;;
18375                 124) error "process hangs on a deadlock"
18376                 ;;
18377                 *) error "error executing flock_deadlock $DIR/$tfile"
18378                 ;;
18379         esac
18380 }
18381 run_test 235 "LU-1715: flock deadlock detection does not work properly"
18382
18383 #LU-2935
18384 test_236() {
18385         check_swap_layouts_support
18386
18387         local ref1=/etc/passwd
18388         local ref2=/etc/group
18389         local file1=$DIR/$tdir/f1
18390         local file2=$DIR/$tdir/f2
18391
18392         test_mkdir -c1 $DIR/$tdir
18393         $LFS setstripe -c 1 $file1 || error "cannot setstripe on '$file1': rc = $?"
18394         cp $ref1 $file1 || error "cp $ref1 $file1 failed: rc = $?"
18395         $LFS setstripe -c 2 $file2 || error "cannot setstripe on '$file2': rc = $?"
18396         cp $ref2 $file2 || error "cp $ref2 $file2 failed: rc = $?"
18397         local fd=$(free_fd)
18398         local cmd="exec $fd<>$file2"
18399         eval $cmd
18400         rm $file2
18401         $LFS swap_layouts $file1 /proc/self/fd/${fd} ||
18402                 error "cannot swap layouts of '$file1' and /proc/self/fd/${fd}"
18403         cmd="exec $fd>&-"
18404         eval $cmd
18405         cmp $ref2 $file1 || error "content compare failed ($ref2 != $file1)"
18406
18407         #cleanup
18408         rm -rf $DIR/$tdir
18409 }
18410 run_test 236 "Layout swap on open unlinked file"
18411
18412 # LU-4659 linkea consistency
18413 test_238() {
18414         [[ $MDS1_VERSION -gt $(version_code 2.5.57) ]] ||
18415                 [[ $MDS1_VERSION -gt $(version_code 2.5.1) &&
18416                    $MDS1_VERSION -lt $(version_code 2.5.50) ]] ||
18417                 skip "Need MDS version at least 2.5.58 or 2.5.2+"
18418
18419         touch $DIR/$tfile
18420         ln $DIR/$tfile $DIR/$tfile.lnk
18421         touch $DIR/$tfile.new
18422         mv $DIR/$tfile.new $DIR/$tfile
18423         local fid1=$($LFS path2fid $DIR/$tfile)
18424         local fid2=$($LFS path2fid $DIR/$tfile.lnk)
18425         local path1=$($LFS fid2path $FSNAME "$fid1")
18426         [ $tfile == $path1 ] || error "linkea inconsistent: $tfile $fid1 $path1"
18427         local path2=$($LFS fid2path $FSNAME "$fid2")
18428         [ $tfile.lnk == $path2 ] ||
18429                 error "linkea inconsistent: $tfile.lnk $fid2 $path2!"
18430         rm -f $DIR/$tfile*
18431 }
18432 run_test 238 "Verify linkea consistency"
18433
18434 test_239A() { # was test_239
18435         [ $MDS1_VERSION -lt $(version_code 2.5.60) ] &&
18436                 skip "Need MDS version at least 2.5.60"
18437
18438         local list=$(comma_list $(mdts_nodes))
18439
18440         mkdir -p $DIR/$tdir
18441         createmany -o $DIR/$tdir/f- 5000
18442         unlinkmany $DIR/$tdir/f- 5000
18443         [ $MDS1_VERSION -gt $(version_code 2.10.4) ] &&
18444                 do_nodes $list "lctl set_param -n osp.*.force_sync=1"
18445         changes=$(do_nodes $list "lctl get_param -n osp.*MDT*.sync_changes \
18446                         osp.*MDT*.sync_in_flight" | calc_sum)
18447         [ "$changes" -eq 0 ] || error "$changes not synced"
18448 }
18449 run_test 239A "osp_sync test"
18450
18451 test_239a() { #LU-5297
18452         remote_mds_nodsh && skip "remote MDS with nodsh"
18453
18454         touch $DIR/$tfile
18455         #define OBD_FAIL_OSP_CHECK_INVALID_REC     0x2100
18456         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2100
18457         chgrp $RUNAS_GID $DIR/$tfile
18458         wait_delete_completed
18459 }
18460 run_test 239a "process invalid osp sync record correctly"
18461
18462 test_239b() { #LU-5297
18463         remote_mds_nodsh && skip "remote MDS with nodsh"
18464
18465         touch $DIR/$tfile1
18466         #define OBD_FAIL_OSP_CHECK_ENOMEM     0x2101
18467         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2101
18468         chgrp $RUNAS_GID $DIR/$tfile1
18469         wait_delete_completed
18470         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
18471         touch $DIR/$tfile2
18472         chgrp $RUNAS_GID $DIR/$tfile2
18473         wait_delete_completed
18474 }
18475 run_test 239b "process osp sync record with ENOMEM error correctly"
18476
18477 test_240() {
18478         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18479         remote_mds_nodsh && skip "remote MDS with nodsh"
18480
18481         mkdir -p $DIR/$tdir
18482
18483         $LFS mkdir -i 0 $DIR/$tdir/d0 ||
18484                 error "failed to mkdir $DIR/$tdir/d0 on MDT0"
18485         $LFS mkdir -i 1 $DIR/$tdir/d0/d1 ||
18486                 error "failed to mkdir $DIR/$tdir/d0/d1 on MDT1"
18487
18488         umount_client $MOUNT || error "umount failed"
18489         #define OBD_FAIL_TGT_DELAY_CONDITIONAL   0x713
18490         do_facet mds2 lctl set_param fail_loc=0x713 fail_val=1
18491         mount_client $MOUNT || error "failed to mount client"
18492
18493         echo "stat $DIR/$tdir/d0/d1, should not fail/ASSERT"
18494         stat $DIR/$tdir/d0/d1 || error "fail to stat $DIR/$tdir/d0/d1"
18495 }
18496 run_test 240 "race between ldlm enqueue and the connection RPC (no ASSERT)"
18497
18498 test_241_bio() {
18499         local count=$1
18500         local bsize=$2
18501
18502         for LOOP in $(seq $count); do
18503                 dd if=$DIR/$tfile of=/dev/null bs=$bsize count=1 2>/dev/null
18504                 cancel_lru_locks $OSC || true
18505         done
18506 }
18507
18508 test_241_dio() {
18509         local count=$1
18510         local bsize=$2
18511
18512         for LOOP in $(seq $1); do
18513                 dd if=$DIR/$tfile of=/dev/null bs=$bsize count=1 iflag=direct \
18514                         2>/dev/null
18515         done
18516 }
18517
18518 test_241a() { # was test_241
18519         local bsize=$PAGE_SIZE
18520
18521         (( bsize < 40960 )) && bsize=40960
18522         dd if=/dev/zero of=$DIR/$tfile count=1 bs=$bsize
18523         ls -la $DIR/$tfile
18524         cancel_lru_locks $OSC
18525         test_241_bio 1000 $bsize &
18526         PID=$!
18527         test_241_dio 1000 $bsize
18528         wait $PID
18529 }
18530 run_test 241a "bio vs dio"
18531
18532 test_241b() {
18533         local bsize=$PAGE_SIZE
18534
18535         (( bsize < 40960 )) && bsize=40960
18536         dd if=/dev/zero of=$DIR/$tfile count=1 bs=$bsize
18537         ls -la $DIR/$tfile
18538         test_241_dio 1000 $bsize &
18539         PID=$!
18540         test_241_dio 1000 $bsize
18541         wait $PID
18542 }
18543 run_test 241b "dio vs dio"
18544
18545 test_242() {
18546         remote_mds_nodsh && skip "remote MDS with nodsh"
18547
18548         mkdir -p $DIR/$tdir
18549         touch $DIR/$tdir/$tfile
18550
18551         #define OBD_FAIL_MDS_READPAGE_PACK      0x105
18552         do_facet mds1 lctl set_param fail_loc=0x105
18553         /bin/ls $DIR/$tdir && error "ls $DIR/$tdir should fail"
18554
18555         do_facet mds1 lctl set_param fail_loc=0
18556         /bin/ls $DIR/$tdir || error "ls $DIR/$tdir failed"
18557 }
18558 run_test 242 "mdt_readpage failure should not cause directory unreadable"
18559
18560 test_243()
18561 {
18562         test_mkdir $DIR/$tdir
18563         group_lock_test -d $DIR/$tdir || error "A group lock test failed"
18564 }
18565 run_test 243 "various group lock tests"
18566
18567 test_244a()
18568 {
18569         test_mkdir $DIR/$tdir
18570         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=35
18571         sendfile_grouplock $DIR/$tdir/$tfile || \
18572                 error "sendfile+grouplock failed"
18573         rm -rf $DIR/$tdir
18574 }
18575 run_test 244a "sendfile with group lock tests"
18576
18577 test_244b()
18578 {
18579         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
18580
18581         local threads=50
18582         local size=$((1024*1024))
18583
18584         test_mkdir $DIR/$tdir
18585         for i in $(seq 1 $threads); do
18586                 local file=$DIR/$tdir/file_$((i / 10))
18587                 $MULTIOP $file OG1234w$size_$((i % 3))w$size_$((i % 4))g1234c &
18588                 local pids[$i]=$!
18589         done
18590         for i in $(seq 1 $threads); do
18591                 wait ${pids[$i]}
18592         done
18593 }
18594 run_test 244b "multi-threaded write with group lock"
18595
18596 test_245() {
18597         local flagname="multi_mod_rpcs"
18598         local connect_data_name="max_mod_rpcs"
18599         local out
18600
18601         # check if multiple modify RPCs flag is set
18602         out=$($LCTL get_param mdc.$FSNAME-MDT0000-*.import |
18603                 grep "connect_flags:")
18604         echo "$out"
18605
18606         echo "$out" | grep -qw $flagname
18607         if [ $? -ne 0 ]; then
18608                 echo "connect flag $flagname is not set"
18609                 return
18610         fi
18611
18612         # check if multiple modify RPCs data is set
18613         out=$($LCTL get_param mdc.$FSNAME-MDT0000-*.import)
18614         echo "$out"
18615
18616         echo "$out" | grep -qw $connect_data_name ||
18617                 error "import should have connect data $connect_data_name"
18618 }
18619 run_test 245 "check mdc connection flag/data: multiple modify RPCs"
18620
18621 cleanup_247() {
18622         local submount=$1
18623
18624         trap 0
18625         umount_client $submount
18626         rmdir $submount
18627 }
18628
18629 test_247a() {
18630         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
18631                 grep -q subtree ||
18632                 skip_env "Fileset feature is not supported"
18633
18634         local submount=${MOUNT}_$tdir
18635
18636         mkdir $MOUNT/$tdir
18637         mkdir -p $submount || error "mkdir $submount failed"
18638         FILESET="$FILESET/$tdir" mount_client $submount ||
18639                 error "mount $submount failed"
18640         trap "cleanup_247 $submount" EXIT
18641         echo foo > $submount/$tfile || error "write $submount/$tfile failed"
18642         [ $(cat $MOUNT/$tdir/$tfile) = "foo" ] ||
18643                 error "read $MOUNT/$tdir/$tfile failed"
18644         cleanup_247 $submount
18645 }
18646 run_test 247a "mount subdir as fileset"
18647
18648 test_247b() {
18649         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
18650                 skip_env "Fileset feature is not supported"
18651
18652         local submount=${MOUNT}_$tdir
18653
18654         rm -rf $MOUNT/$tdir
18655         mkdir -p $submount || error "mkdir $submount failed"
18656         SKIP_FILESET=1
18657         FILESET="$FILESET/$tdir" mount_client $submount &&
18658                 error "mount $submount should fail"
18659         rmdir $submount
18660 }
18661 run_test 247b "mount subdir that dose not exist"
18662
18663 test_247c() {
18664         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
18665                 skip_env "Fileset feature is not supported"
18666
18667         local submount=${MOUNT}_$tdir
18668
18669         mkdir -p $MOUNT/$tdir/dir1
18670         mkdir -p $submount || error "mkdir $submount failed"
18671         trap "cleanup_247 $submount" EXIT
18672         FILESET="$FILESET/$tdir" mount_client $submount ||
18673                 error "mount $submount failed"
18674         local fid=$($LFS path2fid $MOUNT/)
18675         $LFS fid2path $submount $fid && error "fid2path should fail"
18676         cleanup_247 $submount
18677 }
18678 run_test 247c "running fid2path outside subdirectory root"
18679
18680 test_247d() {
18681         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
18682                 skip "Fileset feature is not supported"
18683
18684         local submount=${MOUNT}_$tdir
18685
18686         mkdir -p $MOUNT/$tdir/dir1
18687         mkdir -p $submount || error "mkdir $submount failed"
18688         FILESET="$FILESET/$tdir" mount_client $submount ||
18689                 error "mount $submount failed"
18690         trap "cleanup_247 $submount" EXIT
18691
18692         local td=$submount/dir1
18693         local fid=$($LFS path2fid $td)
18694         [ -z "$fid" ] && error "path2fid unable to get $td FID"
18695
18696         # check that we get the same pathname back
18697         local rootpath
18698         local found
18699         for rootpath in "$submount" "$submount///" "$submount/dir1"; do
18700                 echo "$rootpath $fid"
18701                 found=$($LFS fid2path $rootpath "$fid")
18702                 [ -n "found" ] || error "fid2path should succeed"
18703                 [ "$found" == "$td" ] || error "fid2path $found != $td"
18704         done
18705         # check wrong root path format
18706         rootpath=$submount"_wrong"
18707         found=$($LFS fid2path $rootpath "$fid")
18708         [ -z "$found" ] || error "fid2path should fail ($rootpath != $submount)"
18709
18710         cleanup_247 $submount
18711 }
18712 run_test 247d "running fid2path inside subdirectory root"
18713
18714 # LU-8037
18715 test_247e() {
18716         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
18717                 grep -q subtree ||
18718                 skip "Fileset feature is not supported"
18719
18720         local submount=${MOUNT}_$tdir
18721
18722         mkdir $MOUNT/$tdir
18723         mkdir -p $submount || error "mkdir $submount failed"
18724         FILESET="$FILESET/.." mount_client $submount &&
18725                 error "mount $submount should fail"
18726         rmdir $submount
18727 }
18728 run_test 247e "mount .. as fileset"
18729
18730 test_247f() {
18731         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18732         [ $MDS1_VERSION -lt $(version_code 2.13.52) ] &&
18733                 skip "Need at least version 2.13.52"
18734         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
18735                 grep -q subtree ||
18736                 skip "Fileset feature is not supported"
18737
18738         mkdir $DIR/$tdir || error "mkdir $tdir failed"
18739         $LFS mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir/remote ||
18740                 error "mkdir remote failed"
18741         mkdir $DIR/$tdir/remote/subdir || error "mkdir remote/subdir failed"
18742         $LFS mkdir -c $MDSCOUNT $DIR/$tdir/striped ||
18743                 error "mkdir striped failed"
18744         mkdir $DIR/$tdir/striped/subdir || error "mkdir striped/subdir failed"
18745
18746         local submount=${MOUNT}_$tdir
18747
18748         mkdir -p $submount || error "mkdir $submount failed"
18749
18750         local dir
18751         local fileset=$FILESET
18752
18753         for dir in $tdir/remote $tdir/remote/subdir \
18754                    $tdir/striped $tdir/striped/subdir $tdir/striped/. ; do
18755                 FILESET="$fileset/$dir" mount_client $submount ||
18756                         error "mount $dir failed"
18757                 umount_client $submount
18758         done
18759 }
18760 run_test 247f "mount striped or remote directory as fileset"
18761
18762 test_248a() {
18763         local fast_read_sav=$($LCTL get_param -n llite.*.fast_read 2>/dev/null)
18764         [ -z "$fast_read_sav" ] && skip "no fast read support"
18765
18766         # create a large file for fast read verification
18767         dd if=/dev/zero of=$DIR/$tfile bs=1M count=128 > /dev/null 2>&1
18768
18769         # make sure the file is created correctly
18770         $CHECKSTAT -s $((128*1024*1024)) $DIR/$tfile ||
18771                 { rm -f $DIR/$tfile; skip "file creation error"; }
18772
18773         echo "Test 1: verify that fast read is 4 times faster on cache read"
18774
18775         # small read with fast read enabled
18776         $LCTL set_param -n llite.*.fast_read=1
18777         local t_fast=$(dd if=$DIR/$tfile of=/dev/null bs=4k 2>&1 |
18778                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
18779                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
18780         # small read with fast read disabled
18781         $LCTL set_param -n llite.*.fast_read=0
18782         local t_slow=$(dd if=$DIR/$tfile of=/dev/null bs=4k 2>&1 |
18783                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
18784                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
18785
18786         # verify that fast read is 4 times faster for cache read
18787         [ $(bc <<< "4 * $t_fast < $t_slow") -eq 1 ] ||
18788                 error_not_in_vm "fast read was not 4 times faster: " \
18789                            "$t_fast vs $t_slow"
18790
18791         echo "Test 2: verify the performance between big and small read"
18792         $LCTL set_param -n llite.*.fast_read=1
18793
18794         # 1k non-cache read
18795         cancel_lru_locks osc
18796         local t_1k=$(dd if=$DIR/$tfile of=/dev/null bs=1k 2>&1 |
18797                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
18798                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
18799
18800         # 1M non-cache read
18801         cancel_lru_locks osc
18802         local t_1m=$(dd if=$DIR/$tfile of=/dev/null bs=1k 2>&1 |
18803                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
18804                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
18805
18806         # verify that big IO is not 4 times faster than small IO
18807         [ $(bc <<< "4 * $t_1k >= $t_1m") -eq 1 ] ||
18808                 error_not_in_vm "bigger IO is way too fast: $t_1k vs $t_1m"
18809
18810         $LCTL set_param -n llite.*.fast_read=$fast_read_sav
18811         rm -f $DIR/$tfile
18812 }
18813 run_test 248a "fast read verification"
18814
18815 test_248b() {
18816         # Default short_io_bytes=16384, try both smaller and larger sizes.
18817         # Lustre O_DIRECT read and write needs to be a multiple of PAGE_SIZE.
18818         # 6017024 = 2^12*13*113 = 47008*128 = 11752*512 = 4096*1469 = 53248*113
18819         echo "bs=53248 count=113 normal buffered write"
18820         dd if=/dev/urandom of=$TMP/$tfile.0 bs=53248 count=113 ||
18821                 error "dd of initial data file failed"
18822         stack_trap "rm -f $DIR/$tfile.[0-3] $TMP/$tfile.[0-3]" EXIT
18823
18824         echo "bs=47008 count=128 oflag=dsync normal write $tfile.0"
18825         dd if=$TMP/$tfile.0 of=$DIR/$tfile.0 bs=47008 count=128 oflag=dsync ||
18826                 error "dd with sync normal writes failed"
18827         cmp $TMP/$tfile.0 $DIR/$tfile.0 || error "compare $DIR/$tfile.0 failed"
18828
18829         echo "bs=11752 count=512 oflag=dsync small write $tfile.1"
18830         dd if=$TMP/$tfile.0 of=$DIR/$tfile.1 bs=11752 count=512 oflag=dsync ||
18831                 error "dd with sync small writes failed"
18832         cmp $TMP/$tfile.0 $DIR/$tfile.1 || error "compare $DIR/$tfile.1 failed"
18833
18834         cancel_lru_locks osc
18835
18836         # calculate the small O_DIRECT size and count for the client PAGE_SIZE
18837         local num=$((13 * 113 / (PAGE_SIZE / 4096)))
18838         echo "bs=$PAGE_SIZE count=$num iflag=direct small read $tfile.1"
18839         dd if=$DIR/$tfile.1 of=$TMP/$tfile.1 bs=$PAGE_SIZE count=$num \
18840                 iflag=direct || error "dd with O_DIRECT small read failed"
18841         # adjust bytes checked to handle larger PAGE_SIZE for ARM/PPC
18842         cmp --bytes=$((PAGE_SIZE * num)) $TMP/$tfile.0 $TMP/$tfile.1 ||
18843                 error "compare $TMP/$tfile.1 failed"
18844
18845         local save=$($LCTL get_param -n osc.*OST000*.short_io_bytes | head -n 1)
18846         stack_trap "$LCTL set_param osc.$FSNAME-*.short_io_bytes=$save" EXIT
18847
18848         # just to see what the maximum tunable value is, and test parsing
18849         echo "test invalid parameter 2MB"
18850         $LCTL set_param osc.$FSNAME-OST0000*.short_io_bytes=2M &&
18851                 error "too-large short_io_bytes allowed"
18852         echo "test maximum parameter 512KB"
18853         # if we can set a larger short_io_bytes, run test regardless of version
18854         if ! $LCTL set_param osc.$FSNAME-OST0000*.short_io_bytes=512K; then
18855                 # older clients may not allow setting it this large, that's OK
18856                 [ $CLIENT_VERSION -ge $(version_code 2.13.50) ] ||
18857                         skip "Need at least client version 2.13.50"
18858                 error "medium short_io_bytes failed"
18859         fi
18860         $LCTL get_param osc.$FSNAME-OST0000*.short_io_bytes
18861         size=$($LCTL get_param -n osc.$FSNAME-OST0000*.short_io_bytes)
18862
18863         echo "test large parameter 64KB"
18864         $LCTL set_param osc.$FSNAME-*.short_io_bytes=65536
18865         $LCTL get_param osc.$FSNAME-OST0000*.short_io_bytes
18866
18867         echo "bs=47008 count=128 oflag=dsync large write $tfile.2"
18868         dd if=$TMP/$tfile.0 of=$DIR/$tfile.2 bs=47008 count=128 oflag=dsync ||
18869                 error "dd with sync large writes failed"
18870         cmp $TMP/$tfile.0 $DIR/$tfile.2 || error "compare $DIR/$tfile.2 failed"
18871
18872         # calculate the large O_DIRECT size and count for the client PAGE_SIZE
18873         local size=$(((4096 * 13 + PAGE_SIZE - 1) / PAGE_SIZE * PAGE_SIZE))
18874         num=$((113 * 4096 / PAGE_SIZE))
18875         echo "bs=$size count=$num oflag=direct large write $tfile.3"
18876         dd if=$TMP/$tfile.0 of=$DIR/$tfile.3 bs=$size count=$num oflag=direct ||
18877                 error "dd with O_DIRECT large writes failed"
18878         cmp --bytes=$((size * num)) $TMP/$tfile.0 $DIR/$tfile.3 ||
18879                 error "compare $DIR/$tfile.3 failed"
18880
18881         cancel_lru_locks osc
18882
18883         echo "bs=$size count=$num iflag=direct large read $tfile.2"
18884         dd if=$DIR/$tfile.2 of=$TMP/$tfile.2 bs=$size count=$num iflag=direct ||
18885                 error "dd with O_DIRECT large read failed"
18886         cmp --bytes=$((size * num)) $TMP/$tfile.0 $TMP/$tfile.2 ||
18887                 error "compare $TMP/$tfile.2 failed"
18888
18889         echo "bs=$size count=$num iflag=direct large read $tfile.3"
18890         dd if=$DIR/$tfile.3 of=$TMP/$tfile.3 bs=$size count=$num iflag=direct ||
18891                 error "dd with O_DIRECT large read failed"
18892         cmp --bytes=$((size * num)) $TMP/$tfile.0 $TMP/$tfile.3 ||
18893                 error "compare $TMP/$tfile.3 failed"
18894 }
18895 run_test 248b "test short_io read and write for both small and large sizes"
18896
18897 test_249() { # LU-7890
18898         [ $MDS1_VERSION -lt $(version_code 2.8.53) ] &&
18899                 skip "Need at least version 2.8.54"
18900
18901         rm -f $DIR/$tfile
18902         $LFS setstripe -c 1 $DIR/$tfile
18903         # Offset 2T == 4k * 512M
18904         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 seek=512M ||
18905                 error "dd to 2T offset failed"
18906 }
18907 run_test 249 "Write above 2T file size"
18908
18909 test_250() {
18910         [ "$(facet_fstype ost$(($($LFS getstripe -i $DIR/$tfile) + 1)))" = "zfs" ] \
18911          && skip "no 16TB file size limit on ZFS"
18912
18913         $LFS setstripe -c 1 $DIR/$tfile
18914         # ldiskfs extent file size limit is (16TB - 4KB - 1) bytes
18915         local size=$((16 * 1024 * 1024 * 1024 * 1024 - 4096 - 1))
18916         $TRUNCATE $DIR/$tfile $size || error "truncate $tfile to $size failed"
18917         dd if=/dev/zero of=$DIR/$tfile bs=10 count=1 oflag=append \
18918                 conv=notrunc,fsync && error "append succeeded"
18919         return 0
18920 }
18921 run_test 250 "Write above 16T limit"
18922
18923 test_251() {
18924         $LFS setstripe -c -1 -S 1048576 $DIR/$tfile
18925
18926         #define OBD_FAIL_LLITE_LOST_LAYOUT 0x1407
18927         #Skip once - writing the first stripe will succeed
18928         $LCTL set_param fail_loc=0xa0001407 fail_val=1
18929         $MULTIOP $DIR/$tfile o:O_RDWR:w2097152c 2>&1 | grep -q "short write" &&
18930                 error "short write happened"
18931
18932         $LCTL set_param fail_loc=0xa0001407 fail_val=1
18933         $MULTIOP $DIR/$tfile or2097152c 2>&1 | grep -q "short read" &&
18934                 error "short read happened"
18935
18936         rm -f $DIR/$tfile
18937 }
18938 run_test 251 "Handling short read and write correctly"
18939
18940 test_252() {
18941         remote_mds_nodsh && skip "remote MDS with nodsh"
18942         remote_ost_nodsh && skip "remote OST with nodsh"
18943         if [ "$ost1_FSTYPE" != ldiskfs ] || [ "$mds1_FSTYPE" != ldiskfs ]; then
18944                 skip_env "ldiskfs only test"
18945         fi
18946
18947         local tgt
18948         local dev
18949         local out
18950         local uuid
18951         local num
18952         local gen
18953
18954         # check lr_reader on OST0000
18955         tgt=ost1
18956         dev=$(facet_device $tgt)
18957         out=$(do_facet $tgt $LR_READER $dev)
18958         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
18959         echo "$out"
18960         uuid=$(echo "$out" | grep -i uuid | awk '{ print $2 }')
18961         [ "$uuid" == "$(ostuuid_from_index 0)" ] ||
18962                 error "Invalid uuid returned by $LR_READER on target $tgt"
18963         echo -e "uuid returned by $LR_READER is '$uuid'\n"
18964
18965         # check lr_reader -c on MDT0000
18966         tgt=mds1
18967         dev=$(facet_device $tgt)
18968         if ! do_facet $tgt $LR_READER -h | grep -q OPTIONS; then
18969                 skip "$LR_READER does not support additional options"
18970         fi
18971         out=$(do_facet $tgt $LR_READER -c $dev)
18972         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
18973         echo "$out"
18974         num=$(echo "$out" | grep -c "mdtlov")
18975         [ "$num" -eq $((MDSCOUNT - 1)) ] ||
18976                 error "Invalid number of mdtlov clients returned by $LR_READER"
18977         echo -e "Number of mdtlov clients returned by $LR_READER is '$num'\n"
18978
18979         # check lr_reader -cr on MDT0000
18980         out=$(do_facet $tgt $LR_READER -cr $dev)
18981         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
18982         echo "$out"
18983         echo "$out" | grep -q "^reply_data:$" ||
18984                 error "$LR_READER should have returned 'reply_data' section"
18985         num=$(echo "$out" | grep -c "client_generation")
18986         echo -e "Number of reply data returned by $LR_READER is '$num'\n"
18987 }
18988 run_test 252 "check lr_reader tool"
18989
18990 test_253() {
18991         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18992         remote_mds_nodsh && skip "remote MDS with nodsh"
18993         remote_mgs_nodsh && skip "remote MGS with nodsh"
18994
18995         local ostidx=0
18996         local rc=0
18997         local ost_name=$(ostname_from_index $ostidx)
18998
18999         # on the mdt's osc
19000         local mdtosc_proc1=$(get_mdtosc_proc_path $SINGLEMDS $ost_name)
19001         do_facet $SINGLEMDS $LCTL get_param -n \
19002                 osp.$mdtosc_proc1.reserved_mb_high ||
19003                 skip  "remote MDS does not support reserved_mb_high"
19004
19005         rm -rf $DIR/$tdir
19006         wait_mds_ost_sync
19007         wait_delete_completed
19008         mkdir $DIR/$tdir
19009
19010         pool_add $TESTNAME || error "Pool creation failed"
19011         pool_add_targets $TESTNAME 0 || error "Pool add targets failed"
19012
19013         $LFS setstripe $DIR/$tdir -i $ostidx -c 1 -p $FSNAME.$TESTNAME ||
19014                 error "Setstripe failed"
19015
19016         dd if=/dev/zero of=$DIR/$tdir/$tfile.0 bs=1M count=10
19017
19018         local wms=$(ost_watermarks_set_enospc $tfile $ostidx |
19019                     grep "watermarks")
19020         stack_trap "ost_watermarks_clear_enospc $tfile $ostidx $wms" EXIT
19021
19022         local oa_status=$(do_facet $SINGLEMDS $LCTL get_param -n \
19023                         osp.$mdtosc_proc1.prealloc_status)
19024         echo "prealloc_status $oa_status"
19025
19026         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=1M count=1 &&
19027                 error "File creation should fail"
19028
19029         #object allocation was stopped, but we still able to append files
19030         dd if=/dev/zero of=$DIR/$tdir/$tfile.0 bs=1M seek=6 count=5 \
19031                 oflag=append || error "Append failed"
19032
19033         rm -f $DIR/$tdir/$tfile.0
19034
19035         # For this test, we want to delete the files we created to go out of
19036         # space but leave the watermark, so we remain nearly out of space
19037         ost_watermarks_enospc_delete_files $tfile $ostidx
19038
19039         wait_delete_completed
19040
19041         sleep_maxage
19042
19043         for i in $(seq 10 12); do
19044                 dd if=/dev/zero of=$DIR/$tdir/$tfile.$i bs=1M count=1 \
19045                         2>/dev/null || error "File creation failed after rm"
19046         done
19047
19048         oa_status=$(do_facet $SINGLEMDS $LCTL get_param -n \
19049                         osp.$mdtosc_proc1.prealloc_status)
19050         echo "prealloc_status $oa_status"
19051
19052         if (( oa_status != 0 )); then
19053                 error "Object allocation still disable after rm"
19054         fi
19055 }
19056 run_test 253 "Check object allocation limit"
19057
19058 test_254() {
19059         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19060         remote_mds_nodsh && skip "remote MDS with nodsh"
19061         do_facet $SINGLEMDS $LCTL get_param -n mdd.$MDT0.changelog_size ||
19062                 skip "MDS does not support changelog_size"
19063
19064         local cl_user
19065         local MDT0=$(facet_svc $SINGLEMDS)
19066
19067         changelog_register || error "changelog_register failed"
19068
19069         changelog_clear 0 || error "changelog_clear failed"
19070
19071         local size1=$(do_facet $SINGLEMDS \
19072                       $LCTL get_param -n mdd.$MDT0.changelog_size)
19073         echo "Changelog size $size1"
19074
19075         rm -rf $DIR/$tdir
19076         $LFS mkdir -i 0 $DIR/$tdir
19077         # change something
19078         mkdir -p $DIR/$tdir/pics/2008/zachy
19079         touch $DIR/$tdir/pics/2008/zachy/timestamp
19080         cp /etc/hosts $DIR/$tdir/pics/2008/zachy/pic1.jpg
19081         mv $DIR/$tdir/pics/2008/zachy $DIR/$tdir/pics/zach
19082         ln $DIR/$tdir/pics/zach/pic1.jpg $DIR/$tdir/pics/2008/portland.jpg
19083         ln -s $DIR/$tdir/pics/2008/portland.jpg $DIR/$tdir/pics/desktop.jpg
19084         rm $DIR/$tdir/pics/desktop.jpg
19085
19086         local size2=$(do_facet $SINGLEMDS \
19087                       $LCTL get_param -n mdd.$MDT0.changelog_size)
19088         echo "Changelog size after work $size2"
19089
19090         (( $size2 > $size1 )) ||
19091                 error "new Changelog size=$size2 less than old size=$size1"
19092 }
19093 run_test 254 "Check changelog size"
19094
19095 ladvise_no_type()
19096 {
19097         local type=$1
19098         local file=$2
19099
19100         lfs ladvise -a invalid $file 2>&1 | grep "Valid types" |
19101                 awk -F: '{print $2}' | grep $type > /dev/null
19102         if [ $? -ne 0 ]; then
19103                 return 0
19104         fi
19105         return 1
19106 }
19107
19108 ladvise_no_ioctl()
19109 {
19110         local file=$1
19111
19112         lfs ladvise -a willread $file > /dev/null 2>&1
19113         if [ $? -eq 0 ]; then
19114                 return 1
19115         fi
19116
19117         lfs ladvise -a willread $file 2>&1 |
19118                 grep "Inappropriate ioctl for device" > /dev/null
19119         if [ $? -eq 0 ]; then
19120                 return 0
19121         fi
19122         return 1
19123 }
19124
19125 percent() {
19126         bc <<<"scale=2; ($1 - $2) * 100 / $2"
19127 }
19128
19129 # run a random read IO workload
19130 # usage: random_read_iops <filename> <filesize> <iosize>
19131 random_read_iops() {
19132         local file=$1
19133         local fsize=$2
19134         local iosize=${3:-4096}
19135
19136         $READS -f $file -s $fsize -b $iosize -n $((fsize / iosize)) -t 60 |
19137                 sed -e '/^$/d' -e 's#.*s, ##' -e 's#MB/s##'
19138 }
19139
19140 drop_file_oss_cache() {
19141         local file="$1"
19142         local nodes="$2"
19143
19144         $LFS ladvise -a dontneed $file 2>/dev/null ||
19145                 do_nodes $nodes "echo 3 > /proc/sys/vm/drop_caches"
19146 }
19147
19148 ladvise_willread_performance()
19149 {
19150         local repeat=10
19151         local average_origin=0
19152         local average_cache=0
19153         local average_ladvise=0
19154
19155         for ((i = 1; i <= $repeat; i++)); do
19156                 echo "Iter $i/$repeat: reading without willread hint"
19157                 cancel_lru_locks osc
19158                 drop_file_oss_cache $DIR/$tfile $(comma_list $(osts_nodes))
19159                 local speed_origin=$(random_read_iops $DIR/$tfile $size)
19160                 echo "Iter $i/$repeat: uncached speed: $speed_origin"
19161                 average_origin=$(bc <<<"$average_origin + $speed_origin")
19162
19163                 cancel_lru_locks osc
19164                 local speed_cache=$(random_read_iops $DIR/$tfile $size)
19165                 echo "Iter $i/$repeat: OSS cache speed: $speed_cache"
19166                 average_cache=$(bc <<<"$average_cache + $speed_cache")
19167
19168                 cancel_lru_locks osc
19169                 drop_file_oss_cache $DIR/$tfile $(comma_list $(osts_nodes))
19170                 $LFS ladvise -a willread $DIR/$tfile || error "ladvise failed"
19171                 local speed_ladvise=$(random_read_iops $DIR/$tfile $size)
19172                 echo "Iter $i/$repeat: ladvise speed: $speed_ladvise"
19173                 average_ladvise=$(bc <<<"$average_ladvise + $speed_ladvise")
19174         done
19175         average_origin=$(bc <<<"scale=2; $average_origin / $repeat")
19176         average_cache=$(bc <<<"scale=2; $average_cache / $repeat")
19177         average_ladvise=$(bc <<<"scale=2; $average_ladvise / $repeat")
19178
19179         speedup_cache=$(percent $average_cache $average_origin)
19180         speedup_ladvise=$(percent $average_ladvise $average_origin)
19181
19182         echo "Average uncached read: $average_origin"
19183         echo "Average speedup with OSS cached read: " \
19184                 "$average_cache = +$speedup_cache%"
19185         echo "Average speedup with ladvise willread: " \
19186                 "$average_ladvise = +$speedup_ladvise%"
19187
19188         local lowest_speedup=20
19189         if [ ${average_cache%.*} -lt $lowest_speedup ]; then
19190                 echo "Speedup with OSS cached read less than $lowest_speedup%," \
19191                         "got $average_cache%. Skipping ladvise willread check."
19192                 return 0
19193         fi
19194
19195         # the test won't work on ZFS until it supports 'ladvise dontneed', but
19196         # it is still good to run until then to exercise 'ladvise willread'
19197         ! $LFS ladvise -a dontneed $DIR/$tfile &&
19198                 [ "$ost1_FSTYPE" = "zfs" ] &&
19199                 echo "osd-zfs does not support dontneed or drop_caches" &&
19200                 return 0
19201
19202         lowest_speedup=$(bc <<<"scale=2; $average_cache / 2")
19203         [ ${average_ladvise%.*} -gt $lowest_speedup ] ||
19204                 error_not_in_vm "Speedup with willread is less than " \
19205                         "$lowest_speedup%, got $average_ladvise%"
19206 }
19207
19208 test_255a() {
19209         [ $OST1_VERSION -lt $(version_code 2.8.54) ] &&
19210                 skip "lustre < 2.8.54 does not support ladvise "
19211         remote_ost_nodsh && skip "remote OST with nodsh"
19212
19213         lfs setstripe -c -1 -i 0 $DIR/$tfile || error "$tfile failed"
19214
19215         ladvise_no_type willread $DIR/$tfile &&
19216                 skip "willread ladvise is not supported"
19217
19218         ladvise_no_ioctl $DIR/$tfile &&
19219                 skip "ladvise ioctl is not supported"
19220
19221         local size_mb=100
19222         local size=$((size_mb * 1048576))
19223         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=$size_mb ||
19224                 error "dd to $DIR/$tfile failed"
19225
19226         lfs ladvise -a willread $DIR/$tfile ||
19227                 error "Ladvise failed with no range argument"
19228
19229         lfs ladvise -a willread -s 0 $DIR/$tfile ||
19230                 error "Ladvise failed with no -l or -e argument"
19231
19232         lfs ladvise -a willread -e 1 $DIR/$tfile ||
19233                 error "Ladvise failed with only -e argument"
19234
19235         lfs ladvise -a willread -l 1 $DIR/$tfile ||
19236                 error "Ladvise failed with only -l argument"
19237
19238         lfs ladvise -a willread -s 2 -e 1 $DIR/$tfile &&
19239                 error "End offset should not be smaller than start offset"
19240
19241         lfs ladvise -a willread -s 2 -e 2 $DIR/$tfile &&
19242                 error "End offset should not be equal to start offset"
19243
19244         lfs ladvise -a willread -s $size -l 1 $DIR/$tfile ||
19245                 error "Ladvise failed with overflowing -s argument"
19246
19247         lfs ladvise -a willread -s 1 -e $((size + 1)) $DIR/$tfile ||
19248                 error "Ladvise failed with overflowing -e argument"
19249
19250         lfs ladvise -a willread -s 1 -l $size $DIR/$tfile ||
19251                 error "Ladvise failed with overflowing -l argument"
19252
19253         lfs ladvise -a willread -l 1 -e 2 $DIR/$tfile &&
19254                 error "Ladvise succeeded with conflicting -l and -e arguments"
19255
19256         echo "Synchronous ladvise should wait"
19257         local delay=4
19258 #define OBD_FAIL_OST_LADVISE_PAUSE       0x237
19259         do_nodes $(comma_list $(osts_nodes)) \
19260                 $LCTL set_param fail_val=$delay fail_loc=0x237
19261
19262         local start_ts=$SECONDS
19263         lfs ladvise -a willread $DIR/$tfile ||
19264                 error "Ladvise failed with no range argument"
19265         local end_ts=$SECONDS
19266         local inteval_ts=$((end_ts - start_ts))
19267
19268         if [ $inteval_ts -lt $(($delay - 1)) ]; then
19269                 error "Synchronous advice didn't wait reply"
19270         fi
19271
19272         echo "Asynchronous ladvise shouldn't wait"
19273         local start_ts=$SECONDS
19274         lfs ladvise -a willread -b $DIR/$tfile ||
19275                 error "Ladvise failed with no range argument"
19276         local end_ts=$SECONDS
19277         local inteval_ts=$((end_ts - start_ts))
19278
19279         if [ $inteval_ts -gt $(($delay / 2)) ]; then
19280                 error "Asynchronous advice blocked"
19281         fi
19282
19283         do_nodes $(comma_list $(osts_nodes)) $LCTL set_param fail_loc=0
19284         ladvise_willread_performance
19285 }
19286 run_test 255a "check 'lfs ladvise -a willread'"
19287
19288 facet_meminfo() {
19289         local facet=$1
19290         local info=$2
19291
19292         do_facet $facet "cat /proc/meminfo | grep ^${info}:" | awk '{print $2}'
19293 }
19294
19295 test_255b() {
19296         [ $OST1_VERSION -lt $(version_code 2.8.54) ] &&
19297                 skip "lustre < 2.8.54 does not support ladvise "
19298         remote_ost_nodsh && skip "remote OST with nodsh"
19299
19300         lfs setstripe -c 1 -i 0 $DIR/$tfile
19301
19302         ladvise_no_type dontneed $DIR/$tfile &&
19303                 skip "dontneed ladvise is not supported"
19304
19305         ladvise_no_ioctl $DIR/$tfile &&
19306                 skip "ladvise ioctl is not supported"
19307
19308         ! $LFS ladvise -a dontneed $DIR/$tfile &&
19309                 [ "$ost1_FSTYPE" = "zfs" ] &&
19310                 skip "zfs-osd does not support 'ladvise dontneed'"
19311
19312         local size_mb=100
19313         local size=$((size_mb * 1048576))
19314         # In order to prevent disturbance of other processes, only check 3/4
19315         # of the memory usage
19316         local kibibytes=$((size_mb * 1024 * 3 / 4))
19317
19318         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=$size_mb ||
19319                 error "dd to $DIR/$tfile failed"
19320
19321         #force write to complete before dropping OST cache & checking memory
19322         sync
19323
19324         local total=$(facet_meminfo ost1 MemTotal)
19325         echo "Total memory: $total KiB"
19326
19327         do_facet ost1 "sync && echo 3 > /proc/sys/vm/drop_caches"
19328         local before_read=$(facet_meminfo ost1 Cached)
19329         echo "Cache used before read: $before_read KiB"
19330
19331         lfs ladvise -a willread $DIR/$tfile ||
19332                 error "Ladvise willread failed"
19333         local after_read=$(facet_meminfo ost1 Cached)
19334         echo "Cache used after read: $after_read KiB"
19335
19336         lfs ladvise -a dontneed $DIR/$tfile ||
19337                 error "Ladvise dontneed again failed"
19338         local no_read=$(facet_meminfo ost1 Cached)
19339         echo "Cache used after dontneed ladvise: $no_read KiB"
19340
19341         if [ $total -lt $((before_read + kibibytes)) ]; then
19342                 echo "Memory is too small, abort checking"
19343                 return 0
19344         fi
19345
19346         if [ $((before_read + kibibytes)) -gt $after_read ]; then
19347                 error "Ladvise willread should use more memory" \
19348                         "than $kibibytes KiB"
19349         fi
19350
19351         if [ $((no_read + kibibytes)) -gt $after_read ]; then
19352                 error "Ladvise dontneed should release more memory" \
19353                         "than $kibibytes KiB"
19354         fi
19355 }
19356 run_test 255b "check 'lfs ladvise -a dontneed'"
19357
19358 test_255c() {
19359         [ $OST1_VERSION -lt $(version_code 2.10.50) ] &&
19360                 skip "lustre < 2.10.50 does not support lockahead"
19361
19362         local count
19363         local new_count
19364         local difference
19365         local i
19366         local rc
19367
19368         test_mkdir -p $DIR/$tdir
19369         $LFS setstripe -i 0 -c 1 $DIR/$tdir
19370
19371         #test 10 returns only success/failure
19372         i=10
19373         lockahead_test -d $DIR/$tdir -t $i -f $tfile
19374         rc=$?
19375         if [ $rc -eq 255 ]; then
19376                 error "Ladvise test${i} failed, ${rc}"
19377         fi
19378
19379         #test 11 counts lock enqueue requests, all others count new locks
19380         i=11
19381         count=$(do_facet ost1 \
19382                 $LCTL get_param -n ost.OSS.ost.stats)
19383         count=$(echo "$count" | grep ldlm_extent_enqueue | awk '{ print $2 }')
19384
19385         lockahead_test -d $DIR/$tdir -t $i -f $tfile
19386         rc=$?
19387         if [ $rc -eq 255 ]; then
19388                 error "Ladvise test${i} failed, ${rc}"
19389         fi
19390
19391         new_count=$(do_facet ost1 \
19392                 $LCTL get_param -n ost.OSS.ost.stats)
19393         new_count=$(echo "$new_count" | grep ldlm_extent_enqueue | \
19394                    awk '{ print $2 }')
19395
19396         difference="$((new_count - count))"
19397         if [ $difference -ne $rc ]; then
19398                 error "Ladvise test${i}, bad enqueue count, returned " \
19399                       "${rc}, actual ${difference}"
19400         fi
19401
19402         for i in $(seq 12 21); do
19403                 # If we do not do this, we run the risk of having too many
19404                 # locks and starting lock cancellation while we are checking
19405                 # lock counts.
19406                 cancel_lru_locks osc
19407
19408                 count=$($LCTL get_param -n \
19409                        ldlm.namespaces.$FSNAME-OST0000*osc-[-0-9a-f]*.lock_unused_count)
19410
19411                 lockahead_test -d $DIR/$tdir -t $i -f $tfile
19412                 rc=$?
19413                 if [ $rc -eq 255 ]; then
19414                         error "Ladvise test ${i} failed, ${rc}"
19415                 fi
19416
19417                 new_count=$($LCTL get_param -n \
19418                        ldlm.namespaces.$FSNAME-OST0000*osc-[-0-9a-f]*.lock_unused_count)
19419                 difference="$((new_count - count))"
19420
19421                 # Test 15 output is divided by 100 to map down to valid return
19422                 if [ $i -eq 15 ]; then
19423                         rc="$((rc * 100))"
19424                 fi
19425
19426                 if [ $difference -ne $rc ]; then
19427                         error "Ladvise test ${i}, bad lock count, returned " \
19428                               "${rc}, actual ${difference}"
19429                 fi
19430         done
19431
19432         #test 22 returns only success/failure
19433         i=22
19434         lockahead_test -d $DIR/$tdir -t $i -f $tfile
19435         rc=$?
19436         if [ $rc -eq 255 ]; then
19437                 error "Ladvise test${i} failed, ${rc}"
19438         fi
19439 }
19440 run_test 255c "suite of ladvise lockahead tests"
19441
19442 test_256() {
19443         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19444         remote_mds_nodsh && skip "remote MDS with nodsh"
19445         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip "ldiskfs only test"
19446         changelog_users $SINGLEMDS | grep "^cl" &&
19447                 skip "active changelog user"
19448
19449         local cl_user
19450         local cat_sl
19451         local mdt_dev
19452
19453         mdt_dev=$(mdsdevname 1)
19454         echo $mdt_dev
19455
19456         changelog_register || error "changelog_register failed"
19457
19458         rm -rf $DIR/$tdir
19459         mkdir -p $DIR/$tdir
19460
19461         changelog_clear 0 || error "changelog_clear failed"
19462
19463         # change something
19464         touch $DIR/$tdir/{1..10}
19465
19466         # stop the MDT
19467         stop $SINGLEMDS || error "Fail to stop MDT"
19468
19469         # remount the MDT
19470
19471         start $SINGLEMDS $mdt_dev $MDS_MOUNT_OPTS || error "Fail to start MDT"
19472
19473         #after mount new plainllog is used
19474         touch $DIR/$tdir/{11..19}
19475         local tmpfile="$(mktemp --tmpdir -u $tfile.XXXXXX)"
19476         stack_trap "rm -f $tmpfile"
19477         cat_sl=$(do_facet $SINGLEMDS "sync; \
19478                  $DEBUGFS -c -R 'dump changelog_catalog $tmpfile' $mdt_dev; \
19479                  llog_reader $tmpfile | grep -c type=1064553b")
19480         do_facet $SINGLEMDS llog_reader $tmpfile
19481
19482         [ $cat_sl != 2 ] && error "Changelog catalog has $cat_sl != 2 slots"
19483
19484         changelog_clear 0 || error "changelog_clear failed"
19485
19486         cat_sl=$(do_facet $SINGLEMDS "sync; \
19487                  $DEBUGFS -c -R 'dump changelog_catalog $tmpfile' $mdt_dev; \
19488                  llog_reader $tmpfile | grep -c type=1064553b")
19489
19490         if (( cat_sl == 2 )); then
19491                 error "Empty plain llog was not deleted from changelog catalog"
19492         elif (( cat_sl != 1 )); then
19493                 error "Active plain llog shouldn't be deleted from catalog"
19494         fi
19495 }
19496 run_test 256 "Check llog delete for empty and not full state"
19497
19498 test_257() {
19499         remote_mds_nodsh && skip "remote MDS with nodsh"
19500         [[ $MDS1_VERSION -lt $(version_code 2.8.55) ]] &&
19501                 skip "Need MDS version at least 2.8.55"
19502
19503         test_mkdir $DIR/$tdir
19504
19505         setfattr -n trusted.name1 -v value1 $DIR/$tdir ||
19506                 error "setfattr -n trusted.name1=value1 $DIR/$tdir failed"
19507         stat $DIR/$tdir
19508
19509 #define OBD_FAIL_MDS_XATTR_REP                  0x161
19510         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
19511         local facet=mds$((mdtidx + 1))
19512         set_nodes_failloc $(facet_active_host $facet) 0x80000161
19513         getfattr -n trusted.name1 $DIR/$tdir 2> /dev/null
19514
19515         stop $facet || error "stop MDS failed"
19516         start $facet $(mdsdevname $((mdtidx + 1))) $MDS_MOUNT_OPTS ||
19517                 error "start MDS fail"
19518         wait_recovery_complete $facet
19519 }
19520 run_test 257 "xattr locks are not lost"
19521
19522 # Verify we take the i_mutex when security requires it
19523 test_258a() {
19524 #define OBD_FAIL_IMUTEX_SEC 0x141c
19525         $LCTL set_param fail_loc=0x141c
19526         touch $DIR/$tfile
19527         chmod u+s $DIR/$tfile
19528         chmod a+rwx $DIR/$tfile
19529         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 oflag=append
19530         RC=$?
19531         if [ $RC -ne 0 ]; then
19532                 error "error, failed to take i_mutex, rc=$?"
19533         fi
19534         rm -f $DIR/$tfile
19535 }
19536 run_test 258a "verify i_mutex security behavior when suid attributes is set"
19537
19538 # Verify we do NOT take the i_mutex in the normal case
19539 test_258b() {
19540 #define OBD_FAIL_IMUTEX_NOSEC 0x141d
19541         $LCTL set_param fail_loc=0x141d
19542         touch $DIR/$tfile
19543         chmod a+rwx $DIR
19544         chmod a+rw $DIR/$tfile
19545         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 oflag=append
19546         RC=$?
19547         if [ $RC -ne 0 ]; then
19548                 error "error, took i_mutex unnecessarily, rc=$?"
19549         fi
19550         rm -f $DIR/$tfile
19551
19552 }
19553 run_test 258b "verify i_mutex security behavior"
19554
19555 test_259() {
19556         local file=$DIR/$tfile
19557         local before
19558         local after
19559
19560         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip "ldiskfs only test"
19561
19562         stack_trap "rm -f $file" EXIT
19563
19564         wait_delete_completed
19565         before=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
19566         echo "before: $before"
19567
19568         $LFS setstripe -i 0 -c 1 $file
19569         dd if=/dev/zero of=$file bs=1M count=10 || error "couldn't write"
19570         sync_all_data
19571         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
19572         echo "after write: $after"
19573
19574 #define OBD_FAIL_OSD_FAIL_AT_TRUNCATE          0x2301
19575         do_facet ost1 $LCTL set_param fail_loc=0x2301
19576         $TRUNCATE $file 0
19577         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
19578         echo "after truncate: $after"
19579
19580         stop ost1
19581         do_facet ost1 $LCTL set_param fail_loc=0
19582         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
19583         sleep 2
19584         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
19585         echo "after restart: $after"
19586         [ $((after - before)) -ge $(fs_log_size ost1) ] &&
19587                 error "missing truncate?"
19588
19589         return 0
19590 }
19591 run_test 259 "crash at delayed truncate"
19592
19593 test_260() {
19594 #define OBD_FAIL_MDC_CLOSE               0x806
19595         $LCTL set_param fail_loc=0x80000806
19596         touch $DIR/$tfile
19597
19598 }
19599 run_test 260 "Check mdc_close fail"
19600
19601 ### Data-on-MDT sanity tests ###
19602 test_270a() {
19603         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
19604                 skip "Need MDS version at least 2.10.55 for DoM"
19605
19606         # create DoM file
19607         local dom=$DIR/$tdir/dom_file
19608         local tmp=$DIR/$tdir/tmp_file
19609
19610         mkdir -p $DIR/$tdir
19611
19612         # basic checks for DoM component creation
19613         $LFS setstripe -E 1024K -E 2048K -L mdt $dom 2>/dev/null &&
19614                 error "Can set MDT layout to non-first entry"
19615
19616         $LFS setstripe -E 1024K -L mdt -E 2048K -L mdt $dom 2>/dev/null &&
19617                 error "Can define multiple entries as MDT layout"
19618
19619         $LFS setstripe -E 1M -L mdt $dom || error "Can't create DoM layout"
19620
19621         [ $($LFS getstripe -L $dom) == "mdt" ] || error "bad pattern"
19622         [ $($LFS getstripe -c $dom) == 0 ] || error "bad stripe count"
19623         [ $($LFS getstripe -S $dom) == 1048576 ] || error "bad stripe size"
19624
19625         local mdtidx=$($LFS getstripe -m $dom)
19626         local mdtname=MDT$(printf %04x $mdtidx)
19627         local facet=mds$((mdtidx + 1))
19628         local space_check=1
19629
19630         # Skip free space checks with ZFS
19631         [ "$(facet_fstype $facet)" == "zfs" ] && space_check=0
19632
19633         # write
19634         sync
19635         local size_tmp=$((65536 * 3))
19636         local mdtfree1=$(do_facet $facet \
19637                          lctl get_param -n osd*.*$mdtname.kbytesfree)
19638
19639         dd if=/dev/urandom of=$tmp bs=1024 count=$((size_tmp / 1024))
19640         # check also direct IO along write
19641         # IO size must be a multiple of PAGE_SIZE on all platforms (ARM=64KB)
19642         dd if=$tmp of=$dom bs=65536 count=$((size_tmp / 65536)) oflag=direct
19643         sync
19644         cmp $tmp $dom || error "file data is different"
19645         [ $(stat -c%s $dom) == $size_tmp ] ||
19646                 error "bad size after write: $(stat -c%s $dom) != $size_tmp"
19647         if [ $space_check == 1 ]; then
19648                 local mdtfree2=$(do_facet $facet \
19649                                  lctl get_param -n osd*.*$mdtname.kbytesfree)
19650
19651                 # increase in usage from by $size_tmp
19652                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_tmp / 1024)) ] ||
19653                         error "MDT free space wrong after write: " \
19654                               "$mdtfree1 >= $mdtfree2 + $size_tmp/1024"
19655         fi
19656
19657         # truncate
19658         local size_dom=10000
19659
19660         $TRUNCATE $dom $size_dom
19661         [ $(stat -c%s $dom) == $size_dom ] ||
19662                 error "bad size after truncate: $(stat -c%s $dom) != $size_dom"
19663         if [ $space_check == 1 ]; then
19664                 mdtfree1=$(do_facet $facet \
19665                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
19666                 # decrease in usage from $size_tmp to new $size_dom
19667                 [ $(($mdtfree1 - $mdtfree2)) -ge \
19668                   $(((size_tmp - size_dom) / 1024)) ] ||
19669                         error "MDT free space is wrong after truncate: " \
19670                               "$mdtfree1 >= $mdtfree2 + ($size_tmp - $size_dom) / 1024"
19671         fi
19672
19673         # append
19674         cat $tmp >> $dom
19675         sync
19676         size_dom=$((size_dom + size_tmp))
19677         [ $(stat -c%s $dom) == $size_dom ] ||
19678                 error "bad size after append: $(stat -c%s $dom) != $size_dom"
19679         if [ $space_check == 1 ]; then
19680                 mdtfree2=$(do_facet $facet \
19681                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
19682                 # increase in usage by $size_tmp from previous
19683                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_tmp / 1024)) ] ||
19684                         error "MDT free space is wrong after append: " \
19685                               "$mdtfree1 >= $mdtfree2 + $size_tmp/1024"
19686         fi
19687
19688         # delete
19689         rm $dom
19690         if [ $space_check == 1 ]; then
19691                 mdtfree1=$(do_facet $facet \
19692                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
19693                 # decrease in usage by $size_dom from previous
19694                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_dom / 1024)) ] ||
19695                         error "MDT free space is wrong after removal: " \
19696                               "$mdtfree1 >= $mdtfree2 + $size_dom/1024"
19697         fi
19698
19699         # combined striping
19700         $LFS setstripe -E 1024K -L mdt -E EOF $dom ||
19701                 error "Can't create DoM + OST striping"
19702
19703         size_tmp=2031616 # must be a multiple of PAGE_SIZE=65536 on ARM
19704         dd if=/dev/urandom of=$tmp bs=1024 count=$((size_tmp / 1024))
19705         # check also direct IO along write
19706         dd if=$tmp of=$dom bs=65536 count=$((size_tmp / 65536)) oflag=direct
19707         sync
19708         cmp $tmp $dom || error "file data is different"
19709         [ $(stat -c%s $dom) == $size_tmp ] ||
19710                 error "bad size after write: $(stat -c%s $dom) != $size_tmp"
19711         rm $dom $tmp
19712
19713         return 0
19714 }
19715 run_test 270a "DoM: basic functionality tests"
19716
19717 test_270b() {
19718         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
19719                 skip "Need MDS version at least 2.10.55"
19720
19721         local dom=$DIR/$tdir/dom_file
19722         local max_size=1048576
19723
19724         mkdir -p $DIR/$tdir
19725         $LFS setstripe -E $max_size -L mdt $dom
19726
19727         # truncate over the limit
19728         $TRUNCATE $dom $(($max_size + 1)) &&
19729                 error "successful truncate over the maximum size"
19730         # write over the limit
19731         dd if=/dev/zero of=$dom bs=$max_size seek=1 count=1 &&
19732                 error "successful write over the maximum size"
19733         # append over the limit
19734         dd if=/dev/zero of=$dom bs=$(($max_size - 3)) count=1
19735         echo "12345" >> $dom && error "successful append over the maximum size"
19736         rm $dom
19737
19738         return 0
19739 }
19740 run_test 270b "DoM: maximum size overflow checks for DoM-only file"
19741
19742 test_270c() {
19743         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
19744                 skip "Need MDS version at least 2.10.55"
19745
19746         mkdir -p $DIR/$tdir
19747         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
19748
19749         # check files inherit DoM EA
19750         touch $DIR/$tdir/first
19751         [ $($LFS getstripe -L $DIR/$tdir/first) == "mdt" ] ||
19752                 error "bad pattern"
19753         [ $($LFS getstripe -c $DIR/$tdir/first) == 0 ] ||
19754                 error "bad stripe count"
19755         [ $($LFS getstripe -S $DIR/$tdir/first) == 1048576 ] ||
19756                 error "bad stripe size"
19757
19758         # check directory inherits DoM EA and uses it as default
19759         mkdir $DIR/$tdir/subdir
19760         touch $DIR/$tdir/subdir/second
19761         [ $($LFS getstripe -L $DIR/$tdir/subdir/second) == "mdt" ] ||
19762                 error "bad pattern in sub-directory"
19763         [ $($LFS getstripe -c $DIR/$tdir/subdir/second) == 0 ] ||
19764                 error "bad stripe count in sub-directory"
19765         [ $($LFS getstripe -S $DIR/$tdir/subdir/second) == 1048576 ] ||
19766                 error "bad stripe size in sub-directory"
19767         return 0
19768 }
19769 run_test 270c "DoM: DoM EA inheritance tests"
19770
19771 test_270d() {
19772         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
19773                 skip "Need MDS version at least 2.10.55"
19774
19775         mkdir -p $DIR/$tdir
19776         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
19777
19778         # inherit default DoM striping
19779         mkdir $DIR/$tdir/subdir
19780         touch $DIR/$tdir/subdir/f1
19781
19782         # change default directory striping
19783         $LFS setstripe -c 1 $DIR/$tdir/subdir
19784         touch $DIR/$tdir/subdir/f2
19785         [ $($LFS getstripe -c $DIR/$tdir/subdir/f2) == 1 ] ||
19786                 error "wrong default striping in file 2"
19787         [ $($LFS getstripe -L $DIR/$tdir/subdir/f2) == "raid0" ] ||
19788                 error "bad pattern in file 2"
19789         return 0
19790 }
19791 run_test 270d "DoM: change striping from DoM to RAID0"
19792
19793 test_270e() {
19794         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
19795                 skip "Need MDS version at least 2.10.55"
19796
19797         mkdir -p $DIR/$tdir/dom
19798         mkdir -p $DIR/$tdir/norm
19799         DOMFILES=20
19800         NORMFILES=10
19801         $LFS setstripe -E 1M -L mdt $DIR/$tdir/dom
19802         $LFS setstripe -i 0 -S 2M $DIR/$tdir/norm
19803
19804         createmany -o $DIR/$tdir/dom/dom- $DOMFILES
19805         createmany -o $DIR/$tdir/norm/norm- $NORMFILES
19806
19807         # find DoM files by layout
19808         NUM=$($LFS find -L mdt -type f $DIR/$tdir 2>/dev/null | wc -l)
19809         [ $NUM -eq  $DOMFILES ] ||
19810                 error "lfs find -L: found $NUM, expected $DOMFILES"
19811         echo "Test 1: lfs find 20 DOM files by layout: OK"
19812
19813         # there should be 1 dir with default DOM striping
19814         NUM=$($LFS find -L mdt -type d $DIR/$tdir 2>/dev/null | wc -l)
19815         [ $NUM -eq  1 ] ||
19816                 error "lfs find -L: found $NUM, expected 1 dir"
19817         echo "Test 2: lfs find 1 DOM dir by layout: OK"
19818
19819         # find DoM files by stripe size
19820         NUM=$($LFS find -S -1200K -type f $DIR/$tdir 2>/dev/null | wc -l)
19821         [ $NUM -eq  $DOMFILES ] ||
19822                 error "lfs find -S: found $NUM, expected $DOMFILES"
19823         echo "Test 4: lfs find 20 DOM files by stripe size: OK"
19824
19825         # find files by stripe offset except DoM files
19826         NUM=$($LFS find -i 0 -type f $DIR/$tdir 2>/dev/null | wc -l)
19827         [ $NUM -eq  $NORMFILES ] ||
19828                 error "lfs find -i: found $NUM, expected $NORMFILES"
19829         echo "Test 5: lfs find no DOM files by stripe index: OK"
19830         return 0
19831 }
19832 run_test 270e "DoM: lfs find with DoM files test"
19833
19834 test_270f() {
19835         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
19836                 skip "Need MDS version at least 2.10.55"
19837
19838         local mdtname=${FSNAME}-MDT0000-mdtlov
19839         local dom=$DIR/$tdir/dom_file
19840         local dom_limit_saved=$(do_facet mds1 $LCTL get_param -n \
19841                                                 lod.$mdtname.dom_stripesize)
19842         local dom_limit=131072
19843
19844         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=$dom_limit
19845         local dom_current=$(do_facet mds1 $LCTL get_param -n \
19846                                                 lod.$mdtname.dom_stripesize)
19847         [ ${dom_limit} -eq ${dom_current} ] ||
19848                 error "Cannot change per-MDT DoM stripe limit to $dom_limit"
19849
19850         $LFS mkdir -i 0 -c 1 $DIR/$tdir
19851         $LFS setstripe -d $DIR/$tdir
19852         $LFS setstripe -E $dom_limit -L mdt $DIR/$tdir ||
19853                 error "Can't set directory default striping"
19854
19855         # exceed maximum stripe size
19856         $LFS setstripe -E $((dom_limit * 2)) -L mdt $dom ||
19857                 error "Can't create file with $((dom_limit * 2)) DoM stripe"
19858         [ $($LFS getstripe -S $dom) -eq $((dom_limit * 2)) ] &&
19859                 error "Able to create DoM component size more than LOD limit"
19860
19861         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=0
19862         dom_current=$(do_facet mds1 $LCTL get_param -n \
19863                                                 lod.$mdtname.dom_stripesize)
19864         [ 0 -eq ${dom_current} ] ||
19865                 error "Can't set zero DoM stripe limit"
19866         rm $dom
19867
19868         # attempt to create DoM file on server with disabled DoM should
19869         # remove DoM entry from layout and be succeed
19870         $LFS setstripe -E $dom_limit -L mdt -E -1 $dom ||
19871                 error "Can't create DoM file (DoM is disabled)"
19872         [ $($LFS getstripe -L $dom) == "mdt" ] &&
19873                 error "File has DoM component while DoM is disabled"
19874         rm $dom
19875
19876         # attempt to create DoM file with only DoM stripe should return error
19877         $LFS setstripe -E $dom_limit -L mdt $dom &&
19878                 error "Able to create DoM-only file while DoM is disabled"
19879
19880         # too low values to be aligned with smallest stripe size 64K
19881         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=30000
19882         dom_current=$(do_facet mds1 $LCTL get_param -n \
19883                                                 lod.$mdtname.dom_stripesize)
19884         [ 30000 -eq ${dom_current} ] &&
19885                 error "Can set too small DoM stripe limit"
19886
19887         # 64K is a minimal stripe size in Lustre, expect limit of that size
19888         [ 65536 -eq ${dom_current} ] ||
19889                 error "Limit is not set to 64K but ${dom_current}"
19890
19891         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=2147483648
19892         dom_current=$(do_facet mds1 $LCTL get_param -n \
19893                                                 lod.$mdtname.dom_stripesize)
19894         echo $dom_current
19895         [ 2147483648 -eq ${dom_current} ] &&
19896                 error "Can set too large DoM stripe limit"
19897
19898         do_facet mds1 $LCTL set_param -n \
19899                                 lod.$mdtname.dom_stripesize=$((dom_limit * 2))
19900         $LFS setstripe -E $((dom_limit * 2)) -L mdt $dom ||
19901                 error "Can't create DoM component size after limit change"
19902         do_facet mds1 $LCTL set_param -n \
19903                                 lod.$mdtname.dom_stripesize=$((dom_limit / 2))
19904         $LFS setstripe -E $dom_limit -L mdt ${dom}_big ||
19905                 error "Can't create DoM file after limit decrease"
19906         [ $($LFS getstripe -S ${dom}_big) -eq $((dom_limit / 2)) ] ||
19907                 error "Can create big DoM component after limit decrease"
19908         touch ${dom}_def ||
19909                 error "Can't create file with old default layout"
19910
19911         do_facet mds1 $LCTL set_param -n lod.*.dom_stripesize=$dom_limit_saved
19912         return 0
19913 }
19914 run_test 270f "DoM: maximum DoM stripe size checks"
19915
19916 test_270g() {
19917         [ $MDS1_VERSION -ge $(version_code 2.13.52) ] ||
19918                 skip "Need MDS version at least 2.13.52"
19919         local dom=$DIR/$tdir/$tfile
19920
19921         $LFS mkdir -i 0 -c 1 $DIR/$tdir
19922         local lodname=${FSNAME}-MDT0000-mdtlov
19923
19924         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
19925         save_lustre_params mds1 "lod.${lodname}.dom_stripesize_max_kb" > $save
19926         save_lustre_params mds1 "lod.${lodname}.dom_threshold_free_mb" >> $save
19927         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
19928
19929         local dom_limit=1024
19930         local dom_threshold="50%"
19931
19932         $LFS setstripe -d $DIR/$tdir
19933         $LFS setstripe -E ${dom_limit}K -L mdt $DIR/$tdir ||
19934                 error "Can't set directory default striping"
19935
19936         do_facet mds1 $LCTL set_param -n \
19937                                 lod.${lodname}.dom_stripesize_max_kb=$dom_limit
19938         # set 0 threshold and create DOM file to change tunable stripesize
19939         do_facet mds1 $LCTL set_param -n lod.${lodname}.dom_threshold_free_mb=0
19940         $LFS setstripe -E ${dom_limit}K -L mdt -E -1 $dom ||
19941                 error "Failed to create $dom file"
19942         # now tunable dom_cur_stripesize should reach maximum
19943         local dom_current=$(do_facet mds1 $LCTL get_param -n \
19944                                         lod.${lodname}.dom_stripesize_cur_kb)
19945         [[ $dom_current == $dom_limit ]] ||
19946                 error "Current DOM stripesize is not maximum"
19947         rm $dom
19948
19949         # set threshold for further tests
19950         do_facet mds1 $LCTL set_param -n \
19951                         lod.${lodname}.dom_threshold_free_mb=$dom_threshold
19952         echo "DOM threshold is $dom_threshold free space"
19953         local dom_def
19954         local dom_set
19955         # Spoof bfree to exceed threshold
19956         #define OBD_FAIL_MDS_STATFS_SPOOF   0x168
19957         do_facet mds1 $LCTL set_param -n fail_loc=0x0168
19958         for spfree in 40 20 0 15 30 55; do
19959                 do_facet mds1 $LCTL set_param -n fail_val=$spfree
19960                 $LFS setstripe -E ${dom_limit}K -L mdt -E -1 $dom ||
19961                         error "Failed to create $dom file"
19962                 dom_def=$(do_facet mds1 $LCTL get_param -n \
19963                                         lod.${lodname}.dom_stripesize_cur_kb)
19964                 echo "Free space: ${spfree}%, default DOM stripe: ${dom_def}K"
19965                 [[ $dom_def != $dom_current ]] ||
19966                         error "Default stripe size was not changed"
19967                 if [[ $spfree > 0 ]] ; then
19968                         dom_set=$($LFS getstripe -S $dom)
19969                         [[ $dom_set == $((dom_def * 1024)) ]] ||
19970                                 error "DOM component size is still old"
19971                 else
19972                         [[ $($LFS getstripe -L $dom) != "mdt" ]] ||
19973                                 error "DoM component is set with no free space"
19974                 fi
19975                 rm $dom
19976                 dom_current=$dom_def
19977         done
19978 }
19979 run_test 270g "DoM: default DoM stripe size depends on free space"
19980
19981 test_270h() {
19982         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
19983                 skip "Need MDS version at least 2.13.53"
19984
19985         local mdtname=${FSNAME}-MDT0000-mdtlov
19986         local dom=$DIR/$tdir/$tfile
19987         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
19988
19989         save_lustre_params mds1 "lod.*.dom_stripesize" > $save
19990         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
19991
19992         $LFS mkdir -i 0 -c 1 $DIR/$tdir
19993         $LFS setstripe -E 1M -c1  -E -1 -c2 ${dom}_1 ||
19994                 error "can't create OST file"
19995         # mirrored file with DOM entry in the second mirror
19996         $LFS mirror extend -N -E 1M -L mdt -E eof -c2 ${dom}_1 ||
19997                 error "can't create mirror with DoM component"
19998
19999         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=0
20000
20001         # DOM component in the middle and has other enries in the same mirror,
20002         # should succeed but lost DoM component
20003         $LFS setstripe --copy=${dom}_1 $dom ||
20004                 error "Can't create file from OST|DOM mirror layout"
20005         # check new file has no DoM layout after all
20006         [[ $($LFS getstripe -L $dom) != "mdt" ]] ||
20007                 error "File has DoM component while DoM is disabled"
20008 }
20009 run_test 270h "DoM: DoM stripe removal when disabled on server"
20010
20011 test_271a() {
20012         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
20013                 skip "Need MDS version at least 2.10.55"
20014
20015         local dom=$DIR/$tdir/dom
20016
20017         mkdir -p $DIR/$tdir
20018
20019         $LFS setstripe -E 1024K -L mdt $dom
20020
20021         lctl set_param -n mdc.*.stats=clear
20022         dd if=/dev/zero of=$dom bs=4096 count=1 || return 1
20023         cat $dom > /dev/null
20024         local reads=$(lctl get_param -n mdc.*.stats | grep -c ost_read)
20025         [ $reads -eq 0 ] || error "Unexpected $reads READ RPCs"
20026         ls $dom
20027         rm -f $dom
20028 }
20029 run_test 271a "DoM: data is cached for read after write"
20030
20031 test_271b() {
20032         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
20033                 skip "Need MDS version at least 2.10.55"
20034
20035         local dom=$DIR/$tdir/dom
20036
20037         mkdir -p $DIR/$tdir
20038
20039         $LFS setstripe -E 1024K -L mdt -E EOF $dom
20040
20041         lctl set_param -n mdc.*.stats=clear
20042         dd if=/dev/zero of=$dom bs=4096 count=1 || return 1
20043         cancel_lru_locks mdc
20044         $CHECKSTAT -t file -s 4096 $dom || error "stat #1 fails"
20045         # second stat to check size is cached on client
20046         $CHECKSTAT -t file -s 4096 $dom || error "stat #2 fails"
20047         local gls=$(lctl get_param -n mdc.*.stats | grep -c ldlm_glimpse)
20048         [ $gls -eq 0 ] || error "Unexpected $gls glimpse RPCs"
20049         rm -f $dom
20050 }
20051 run_test 271b "DoM: no glimpse RPC for stat (DoM only file)"
20052
20053 test_271ba() {
20054         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
20055                 skip "Need MDS version at least 2.10.55"
20056
20057         local dom=$DIR/$tdir/dom
20058
20059         mkdir -p $DIR/$tdir
20060
20061         $LFS setstripe -E 1024K -L mdt -E EOF $dom
20062
20063         lctl set_param -n mdc.*.stats=clear
20064         lctl set_param -n osc.*.stats=clear
20065         dd if=/dev/zero of=$dom bs=2048K count=1 || return 1
20066         cancel_lru_locks mdc
20067         $CHECKSTAT -t file -s 2097152 $dom || error "stat"
20068         # second stat to check size is cached on client
20069         $CHECKSTAT -t file -s 2097152 $dom || error "stat"
20070         local gls=$(lctl get_param -n mdc.*.stats | grep -c ldlm_glimpse)
20071         [ $gls == 0 ] || error "Unexpected $gls glimpse RPCs"
20072         local gls=$(lctl get_param -n osc.*.stats | grep -c ldlm_glimpse)
20073         [ $gls == 0 ] || error "Unexpected $gls OSC glimpse RPCs"
20074         rm -f $dom
20075 }
20076 run_test 271ba "DoM: no glimpse RPC for stat (combined file)"
20077
20078
20079 get_mdc_stats() {
20080         local mdtidx=$1
20081         local param=$2
20082         local mdt=MDT$(printf %04x $mdtidx)
20083
20084         if [ -z $param ]; then
20085                 lctl get_param -n mdc.*$mdt*.stats
20086         else
20087                 lctl get_param -n mdc.*$mdt*.stats | awk "/$param/"'{print $2}'
20088         fi
20089 }
20090
20091 test_271c() {
20092         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
20093                 skip "Need MDS version at least 2.10.55"
20094
20095         local dom=$DIR/$tdir/dom
20096
20097         mkdir -p $DIR/$tdir
20098
20099         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
20100
20101         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
20102         local facet=mds$((mdtidx + 1))
20103
20104         cancel_lru_locks mdc
20105         do_facet $facet lctl set_param -n mdt.*.dom_lock=0
20106         createmany -o $dom 1000
20107         lctl set_param -n mdc.*.stats=clear
20108         smalliomany -w $dom 1000 200
20109         get_mdc_stats $mdtidx
20110         local enq=$(get_mdc_stats $mdtidx ldlm_ibits_enqueue)
20111         # Each file has 1 open, 1 IO enqueues, total 2000
20112         # but now we have also +1 getxattr for security.capability, total 3000
20113         [ $enq -ge 2000 ] || error "Too few enqueues $enq, expected > 2000"
20114         unlinkmany $dom 1000
20115
20116         cancel_lru_locks mdc
20117         do_facet $facet lctl set_param -n mdt.*.dom_lock=1
20118         createmany -o $dom 1000
20119         lctl set_param -n mdc.*.stats=clear
20120         smalliomany -w $dom 1000 200
20121         local enq_2=$(get_mdc_stats $mdtidx ldlm_ibits_enqueue)
20122         # Expect to see reduced amount of RPCs by 1000 due to single enqueue
20123         # for OPEN and IO lock.
20124         [ $((enq - enq_2)) -ge 1000 ] ||
20125                 error "Too many enqueues $enq_2, expected about $((enq - 1000))"
20126         unlinkmany $dom 1000
20127         return 0
20128 }
20129 run_test 271c "DoM: IO lock at open saves enqueue RPCs"
20130
20131 cleanup_271def_tests() {
20132         trap 0
20133         rm -f $1
20134 }
20135
20136 test_271d() {
20137         [ $MDS1_VERSION -lt $(version_code 2.10.57) ] &&
20138                 skip "Need MDS version at least 2.10.57"
20139
20140         local dom=$DIR/$tdir/dom
20141         local tmp=$TMP/$tfile
20142         trap "cleanup_271def_tests $tmp" EXIT
20143
20144         mkdir -p $DIR/$tdir
20145
20146         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
20147
20148         local mdtidx=$($LFS getstripe --mdt-index $DIR/$tdir)
20149
20150         cancel_lru_locks mdc
20151         dd if=/dev/urandom of=$tmp bs=1000 count=1
20152         dd if=$tmp of=$dom bs=1000 count=1
20153         cancel_lru_locks mdc
20154
20155         cat /etc/hosts >> $tmp
20156         lctl set_param -n mdc.*.stats=clear
20157
20158         # append data to the same file it should update local page
20159         echo "Append to the same page"
20160         cat /etc/hosts >> $dom
20161         local num=$(get_mdc_stats $mdtidx ost_read)
20162         local ra=$(get_mdc_stats $mdtidx req_active)
20163         local rw=$(get_mdc_stats $mdtidx req_waittime)
20164
20165         [ -z $num ] || error "$num READ RPC occured"
20166         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
20167         echo "... DONE"
20168
20169         # compare content
20170         cmp $tmp $dom || error "file miscompare"
20171
20172         cancel_lru_locks mdc
20173         lctl set_param -n mdc.*.stats=clear
20174
20175         echo "Open and read file"
20176         cat $dom > /dev/null
20177         local num=$(get_mdc_stats $mdtidx ost_read)
20178         local ra=$(get_mdc_stats $mdtidx req_active)
20179         local rw=$(get_mdc_stats $mdtidx req_waittime)
20180
20181         [ -z $num ] || error "$num READ RPC occured"
20182         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
20183         echo "... DONE"
20184
20185         # compare content
20186         cmp $tmp $dom || error "file miscompare"
20187
20188         return 0
20189 }
20190 run_test 271d "DoM: read on open (1K file in reply buffer)"
20191
20192 test_271f() {
20193         [ $MDS1_VERSION -lt $(version_code 2.10.57) ] &&
20194                 skip "Need MDS version at least 2.10.57"
20195
20196         local dom=$DIR/$tdir/dom
20197         local tmp=$TMP/$tfile
20198         trap "cleanup_271def_tests $tmp" EXIT
20199
20200         mkdir -p $DIR/$tdir
20201
20202         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
20203
20204         local mdtidx=$($LFS getstripe --mdt-index $DIR/$tdir)
20205
20206         cancel_lru_locks mdc
20207         dd if=/dev/urandom of=$tmp bs=265000 count=1
20208         dd if=$tmp of=$dom bs=265000 count=1
20209         cancel_lru_locks mdc
20210         cat /etc/hosts >> $tmp
20211         lctl set_param -n mdc.*.stats=clear
20212
20213         echo "Append to the same page"
20214         cat /etc/hosts >> $dom
20215         local num=$(get_mdc_stats $mdtidx ost_read)
20216         local ra=$(get_mdc_stats $mdtidx req_active)
20217         local rw=$(get_mdc_stats $mdtidx req_waittime)
20218
20219         [ -z $num ] || error "$num READ RPC occured"
20220         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
20221         echo "... DONE"
20222
20223         # compare content
20224         cmp $tmp $dom || error "file miscompare"
20225
20226         cancel_lru_locks mdc
20227         lctl set_param -n mdc.*.stats=clear
20228
20229         echo "Open and read file"
20230         cat $dom > /dev/null
20231         local num=$(get_mdc_stats $mdtidx ost_read)
20232         local ra=$(get_mdc_stats $mdtidx req_active)
20233         local rw=$(get_mdc_stats $mdtidx req_waittime)
20234
20235         [ -z $num ] && num=0
20236         [ $num -eq 1 ] || error "expect 1 READ RPC, $num occured"
20237         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
20238         echo "... DONE"
20239
20240         # compare content
20241         cmp $tmp $dom || error "file miscompare"
20242
20243         return 0
20244 }
20245 run_test 271f "DoM: read on open (200K file and read tail)"
20246
20247 test_271g() {
20248         [[ $($LCTL get_param mdc.*.import) =~ async_discard ]] ||
20249                 skip "Skipping due to old client or server version"
20250
20251         $LFS setstripe -E 1024K -L mdt -E EOF $DIR1/$tfile
20252         # to get layout
20253         $CHECKSTAT -t file $DIR1/$tfile
20254
20255         $MULTIOP $DIR1/$tfile Ow40960_w4096c &
20256         MULTIOP_PID=$!
20257         sleep 1
20258         #define OBD_FAIL_LDLM_CANCEL_BL_CB_RACE
20259         $LCTL set_param fail_loc=0x80000314
20260         rm $DIR1/$tfile || error "Unlink fails"
20261         RC=$?
20262         kill -USR1 $MULTIOP_PID && wait $MULTIOP_PID || error "multiop failure"
20263         [ $RC -eq 0 ] || error "Failed write to stale object"
20264 }
20265 run_test 271g "Discard DoM data vs client flush race"
20266
20267 test_272a() {
20268         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
20269                 skip "Need MDS version at least 2.11.50"
20270
20271         local dom=$DIR/$tdir/dom
20272         mkdir -p $DIR/$tdir
20273
20274         $LFS setstripe -E 256K -L mdt -E -1 -c1 $dom
20275         dd if=/dev/urandom of=$dom bs=512K count=1 ||
20276                 error "failed to write data into $dom"
20277         local old_md5=$(md5sum $dom)
20278
20279         $LFS migrate -E 256K -L mdt -E -1 -c2 $dom ||
20280                 error "failed to migrate to the same DoM component"
20281
20282         local new_md5=$(md5sum $dom)
20283
20284         [ "$old_md5" == "$new_md5" ] ||
20285                 error "md5sum differ: $old_md5, $new_md5"
20286
20287         [ $($LFS getstripe -c $dom) -eq 2 ] ||
20288                 error "bad final stripe count: $($LFS getstripe -c $dom) != 2"
20289 }
20290 run_test 272a "DoM migration: new layout with the same DOM component"
20291
20292 test_272b() {
20293         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
20294                 skip "Need MDS version at least 2.11.50"
20295
20296         local dom=$DIR/$tdir/dom
20297         mkdir -p $DIR/$tdir
20298         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
20299
20300         local mdtidx=$($LFS getstripe -m $dom)
20301         local mdtname=MDT$(printf %04x $mdtidx)
20302         local facet=mds$((mdtidx + 1))
20303
20304         local mdtfree1=$(do_facet $facet \
20305                 lctl get_param -n osd*.*$mdtname.kbytesfree)
20306         dd if=/dev/urandom of=$dom bs=2M count=1 ||
20307                 error "failed to write data into $dom"
20308         local old_md5=$(md5sum $dom)
20309         cancel_lru_locks mdc
20310         local mdtfree1=$(do_facet $facet \
20311                 lctl get_param -n osd*.*$mdtname.kbytesfree)
20312
20313         $LFS migrate -c2 $dom ||
20314                 error "failed to migrate to the new composite layout"
20315         [ $($LFS getstripe -L $dom) != 'mdt' ] ||
20316                 error "MDT stripe was not removed"
20317
20318         cancel_lru_locks mdc
20319         local new_md5=$(md5sum $dom)
20320         [ "$old_md5" == "$new_md5" ] ||
20321                 error "$old_md5 != $new_md5"
20322
20323         # Skip free space checks with ZFS
20324         if [ "$(facet_fstype $facet)" != "zfs" ]; then
20325                 local mdtfree2=$(do_facet $facet \
20326                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
20327                 [ $mdtfree2 -gt $mdtfree1 ] ||
20328                         error "MDT space is not freed after migration"
20329         fi
20330         return 0
20331 }
20332 run_test 272b "DoM migration: DOM file to the OST-striped file (plain)"
20333
20334 test_272c() {
20335         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
20336                 skip "Need MDS version at least 2.11.50"
20337
20338         local dom=$DIR/$tdir/$tfile
20339         mkdir -p $DIR/$tdir
20340         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
20341
20342         local mdtidx=$($LFS getstripe -m $dom)
20343         local mdtname=MDT$(printf %04x $mdtidx)
20344         local facet=mds$((mdtidx + 1))
20345
20346         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
20347                 error "failed to write data into $dom"
20348         local old_md5=$(md5sum $dom)
20349         cancel_lru_locks mdc
20350         local mdtfree1=$(do_facet $facet \
20351                 lctl get_param -n osd*.*$mdtname.kbytesfree)
20352
20353         $LFS migrate -E 2M -c1 -E -1 -c2 $dom ||
20354                 error "failed to migrate to the new composite layout"
20355         [ $($LFS getstripe -L $dom) == 'mdt' ] &&
20356                 error "MDT stripe was not removed"
20357
20358         cancel_lru_locks mdc
20359         local new_md5=$(md5sum $dom)
20360         [ "$old_md5" == "$new_md5" ] ||
20361                 error "$old_md5 != $new_md5"
20362
20363         # Skip free space checks with ZFS
20364         if [ "$(facet_fstype $facet)" != "zfs" ]; then
20365                 local mdtfree2=$(do_facet $facet \
20366                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
20367                 [ $mdtfree2 -gt $mdtfree1 ] ||
20368                         error "MDS space is not freed after migration"
20369         fi
20370         return 0
20371 }
20372 run_test 272c "DoM migration: DOM file to the OST-striped file (composite)"
20373
20374 test_272d() {
20375         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
20376                 skip "Need MDS version at least 2.12.55"
20377
20378         local dom=$DIR/$tdir/$tfile
20379         mkdir -p $DIR/$tdir
20380         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
20381
20382         local mdtidx=$($LFS getstripe -m $dom)
20383         local mdtname=MDT$(printf %04x $mdtidx)
20384         local facet=mds$((mdtidx + 1))
20385
20386         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
20387                 error "failed to write data into $dom"
20388         local old_md5=$(md5sum $dom)
20389         cancel_lru_locks mdc
20390         local mdtfree1=$(do_facet $facet \
20391                 lctl get_param -n osd*.*$mdtname.kbytesfree)
20392
20393         $LFS mirror extend -N -E 2M -c1 -E -1 -c2 $dom ||
20394                 error "failed mirroring to the new composite layout"
20395         $LFS mirror resync $dom ||
20396                 error "failed mirror resync"
20397         $LFS mirror split --mirror-id 1 -d $dom ||
20398                 error "failed mirror split"
20399
20400         [ $($LFS getstripe -L $dom) != 'mdt' ] ||
20401                 error "MDT stripe was not removed"
20402
20403         cancel_lru_locks mdc
20404         local new_md5=$(md5sum $dom)
20405         [ "$old_md5" == "$new_md5" ] ||
20406                 error "$old_md5 != $new_md5"
20407
20408         # Skip free space checks with ZFS
20409         if [ "$(facet_fstype $facet)" != "zfs" ]; then
20410                 local mdtfree2=$(do_facet $facet \
20411                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
20412                 [ $mdtfree2 -gt $mdtfree1 ] ||
20413                         error "MDS space is not freed after DOM mirror deletion"
20414         fi
20415         return 0
20416 }
20417 run_test 272d "DoM mirroring: OST-striped mirror to DOM file"
20418
20419 test_272e() {
20420         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
20421                 skip "Need MDS version at least 2.12.55"
20422
20423         local dom=$DIR/$tdir/$tfile
20424         mkdir -p $DIR/$tdir
20425         $LFS setstripe -c 2 $dom
20426
20427         dd if=/dev/urandom of=$dom bs=512K count=1 oflag=direct ||
20428                 error "failed to write data into $dom"
20429         local old_md5=$(md5sum $dom)
20430         cancel_lru_locks mdc
20431
20432         $LFS mirror extend -N -E 1M -L mdt -E eof -c2 $dom ||
20433                 error "failed mirroring to the DOM layout"
20434         $LFS mirror resync $dom ||
20435                 error "failed mirror resync"
20436         $LFS mirror split --mirror-id 1 -d $dom ||
20437                 error "failed mirror split"
20438
20439         [ $($LFS getstripe -L $dom) != 'mdt' ] ||
20440                 error "MDT stripe was not removed"
20441
20442         cancel_lru_locks mdc
20443         local new_md5=$(md5sum $dom)
20444         [ "$old_md5" == "$new_md5" ] ||
20445                 error "$old_md5 != $new_md5"
20446
20447         return 0
20448 }
20449 run_test 272e "DoM mirroring: DOM mirror to the OST-striped file"
20450
20451 test_272f() {
20452         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
20453                 skip "Need MDS version at least 2.12.55"
20454
20455         local dom=$DIR/$tdir/$tfile
20456         mkdir -p $DIR/$tdir
20457         $LFS setstripe -c 2 $dom
20458
20459         dd if=/dev/urandom of=$dom bs=512K count=1 oflag=direct ||
20460                 error "failed to write data into $dom"
20461         local old_md5=$(md5sum $dom)
20462         cancel_lru_locks mdc
20463
20464         $LFS migrate -E 1M -L mdt -E eof -c2 -v $dom ||
20465                 error "failed migrating to the DOM file"
20466
20467         cancel_lru_locks mdc
20468         local new_md5=$(md5sum $dom)
20469         [ "$old_md5" != "$new_md5" ] &&
20470                 error "$old_md5 != $new_md5"
20471
20472         return 0
20473 }
20474 run_test 272f "DoM migration: OST-striped file to DOM file"
20475
20476 test_273a() {
20477         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
20478                 skip "Need MDS version at least 2.11.50"
20479
20480         # Layout swap cannot be done if either file has DOM component,
20481         # this will never be supported, migration should be used instead
20482
20483         local dom=$DIR/$tdir/$tfile
20484         mkdir -p $DIR/$tdir
20485
20486         $LFS setstripe -c2 ${dom}_plain
20487         $LFS setstripe -E 1M -L mdt -E -1 -c2 ${dom}_dom
20488         $LFS swap_layouts ${dom}_plain ${dom}_dom &&
20489                 error "can swap layout with DoM component"
20490         $LFS swap_layouts ${dom}_dom ${dom}_plain &&
20491                 error "can swap layout with DoM component"
20492
20493         $LFS setstripe -E 1M -c1 -E -1 -c2 ${dom}_comp
20494         $LFS swap_layouts ${dom}_comp ${dom}_dom &&
20495                 error "can swap layout with DoM component"
20496         $LFS swap_layouts ${dom}_dom ${dom}_comp &&
20497                 error "can swap layout with DoM component"
20498         return 0
20499 }
20500 run_test 273a "DoM: layout swapping should fail with DOM"
20501
20502 test_275() {
20503         remote_ost_nodsh && skip "remote OST with nodsh"
20504         [ $OST1_VERSION -lt $(version_code 2.10.57) ] &&
20505                 skip "Need OST version >= 2.10.57"
20506
20507         local file=$DIR/$tfile
20508         local oss
20509
20510         oss=$(comma_list $(osts_nodes))
20511
20512         dd if=/dev/urandom of=$file bs=1M count=2 ||
20513                 error "failed to create a file"
20514         cancel_lru_locks osc
20515
20516         #lock 1
20517         dd if=$file of=/dev/null bs=1M count=1 iflag=direct ||
20518                 error "failed to read a file"
20519
20520 #define OBD_FAIL_LDLM_PAUSE_CANCEL2      0x31f
20521         $LCTL set_param fail_loc=0x8000031f
20522
20523         cancel_lru_locks osc &
20524         sleep 1
20525
20526 #define OBD_FAIL_LDLM_PROLONG_PAUSE      0x32b
20527         do_nodes $oss $LCTL set_param fail_loc=0x8000032b
20528         #IO takes another lock, but matches the PENDING one
20529         #and places it to the IO RPC
20530         dd if=$file of=/dev/null bs=1M count=1 iflag=direct ||
20531                 error "failed to read a file with PENDING lock"
20532 }
20533 run_test 275 "Read on a canceled duplicate lock"
20534
20535 test_276() {
20536         remote_ost_nodsh && skip "remote OST with nodsh"
20537         local pid
20538
20539         do_facet ost1 "(while true; do \
20540                 $LCTL get_param obdfilter.*.filesfree > /dev/null 2>&1; \
20541                 done) & pid=\\\$!; echo \\\$pid > $TMP/sanity_276_pid" &
20542         pid=$!
20543
20544         for LOOP in $(seq 20); do
20545                 stop ost1
20546                 start ost1 $(ostdevname 1) $OST_MOUNT_OPTS
20547         done
20548         kill -9 $pid
20549         do_facet ost1 "pid=\\\$(cat $TMP/sanity_276_pid); kill -9 \\\$pid; \
20550                 rm $TMP/sanity_276_pid"
20551 }
20552 run_test 276 "Race between mount and obd_statfs"
20553
20554 test_277() {
20555         $LCTL set_param ldlm.namespaces.*.lru_size=0
20556         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
20557         local cached_mb=$($LCTL get_param llite.*.max_cached_mb |
20558                         grep ^used_mb | awk '{print $2}')
20559         [ $cached_mb -eq 1 ] || error "expected mb 1 got $cached_mb"
20560         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 \
20561                 oflag=direct conv=notrunc
20562         cached_mb=$($LCTL get_param llite.*.max_cached_mb |
20563                         grep ^used_mb | awk '{print $2}')
20564         [ $cached_mb -eq 0 ] || error "expected mb 0 got $cached_mb"
20565 }
20566 run_test 277 "Direct IO shall drop page cache"
20567
20568 test_278() {
20569         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
20570         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
20571         [[ "$(facet_host mds1)" != "$(facet_host mds2)" ]] &&
20572                 skip "needs the same host for mdt1 mdt2" && return
20573
20574         local pid1
20575         local pid2
20576
20577 #define OBD_FAIL_OBD_STOP_MDS_RACE     0x60b
20578         do_facet mds2 $LCTL set_param fail_loc=0x8000060c
20579         stop mds2 &
20580         pid2=$!
20581
20582         stop mds1
20583
20584         echo "Starting MDTs"
20585         start mds1 $(mdsdevname 1) $MDS_MOUNT_OPTS
20586         wait $pid2
20587 #For the error assertion will happen. lu_env_get_key(..., &mdt_thread_key)
20588 #will return NULL
20589         do_facet mds2 $LCTL set_param fail_loc=0
20590
20591         start mds2 $(mdsdevname 2) $MDS_MOUNT_OPTS
20592         wait_recovery_complete mds2
20593 }
20594 run_test 278 "Race starting MDS between MDTs stop/start"
20595
20596 test_280() {
20597         [ $MGS_VERSION -lt $(version_code 2.13.52) ] &&
20598                 skip "Need MGS version at least 2.13.52"
20599         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20600         combined_mgs_mds || skip "needs combined MGS/MDT"
20601
20602         umount_client $MOUNT
20603 #define OBD_FAIL_MDS_LLOG_UMOUNT_RACE   0x15e
20604         do_facet mgs $LCTL set_param fail_loc=0x8000015e fail_val=0
20605
20606         mount_client $MOUNT &
20607         sleep 1
20608         stop mgs || error "stop mgs failed"
20609         #for a race mgs would crash
20610         start mgs $(mgsdevname) $MGS_MOUNT_OPTS || error "start mgs failed"
20611         mount_client $MOUNT || error "mount client failed"
20612 }
20613 run_test 280 "Race between MGS umount and client llog processing"
20614
20615 cleanup_test_300() {
20616         trap 0
20617         umask $SAVE_UMASK
20618 }
20619 test_striped_dir() {
20620         local mdt_index=$1
20621         local stripe_count
20622         local stripe_index
20623
20624         mkdir -p $DIR/$tdir
20625
20626         SAVE_UMASK=$(umask)
20627         trap cleanup_test_300 RETURN EXIT
20628
20629         $LFS setdirstripe -i $mdt_index -c 2 -H all_char -o 755 \
20630                                                 $DIR/$tdir/striped_dir ||
20631                 error "set striped dir error"
20632
20633         local mode=$(stat -c%a $DIR/$tdir/striped_dir)
20634         [ "$mode" = "755" ] || error "expect 755 got $mode"
20635
20636         $LFS getdirstripe $DIR/$tdir/striped_dir > /dev/null 2>&1 ||
20637                 error "getdirstripe failed"
20638         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir)
20639         if [ "$stripe_count" != "2" ]; then
20640                 error "1:stripe_count is $stripe_count, expect 2"
20641         fi
20642         stripe_count=$($LFS getdirstripe -T $DIR/$tdir/striped_dir)
20643         if [ "$stripe_count" != "2" ]; then
20644                 error "2:stripe_count is $stripe_count, expect 2"
20645         fi
20646
20647         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir)
20648         if [ "$stripe_index" != "$mdt_index" ]; then
20649                 error "stripe_index is $stripe_index, expect $mdt_index"
20650         fi
20651
20652         [ $(stat -c%h $DIR/$tdir/striped_dir) == '2' ] ||
20653                 error "nlink error after create striped dir"
20654
20655         mkdir $DIR/$tdir/striped_dir/a
20656         mkdir $DIR/$tdir/striped_dir/b
20657
20658         stat $DIR/$tdir/striped_dir/a ||
20659                 error "create dir under striped dir failed"
20660         stat $DIR/$tdir/striped_dir/b ||
20661                 error "create dir under striped dir failed"
20662
20663         [ $(stat -c%h $DIR/$tdir/striped_dir) == '4' ] ||
20664                 error "nlink error after mkdir"
20665
20666         rmdir $DIR/$tdir/striped_dir/a
20667         [ $(stat -c%h $DIR/$tdir/striped_dir) == '3' ] ||
20668                 error "nlink error after rmdir"
20669
20670         rmdir $DIR/$tdir/striped_dir/b
20671         [ $(stat -c%h $DIR/$tdir/striped_dir) == '2' ] ||
20672                 error "nlink error after rmdir"
20673
20674         chattr +i $DIR/$tdir/striped_dir
20675         createmany -o $DIR/$tdir/striped_dir/f 10 &&
20676                 error "immutable flags not working under striped dir!"
20677         chattr -i $DIR/$tdir/striped_dir
20678
20679         rmdir $DIR/$tdir/striped_dir ||
20680                 error "rmdir striped dir error"
20681
20682         cleanup_test_300
20683
20684         true
20685 }
20686
20687 test_300a() {
20688         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
20689                 skip "skipped for lustre < 2.7.0"
20690         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20691         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20692
20693         test_striped_dir 0 || error "failed on striped dir on MDT0"
20694         test_striped_dir 1 || error "failed on striped dir on MDT0"
20695 }
20696 run_test 300a "basic striped dir sanity test"
20697
20698 test_300b() {
20699         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
20700                 skip "skipped for lustre < 2.7.0"
20701         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20702         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20703
20704         local i
20705         local mtime1
20706         local mtime2
20707         local mtime3
20708
20709         test_mkdir $DIR/$tdir || error "mkdir fail"
20710         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
20711                 error "set striped dir error"
20712         for i in {0..9}; do
20713                 mtime1=$(stat -c %Y $DIR/$tdir/striped_dir)
20714                 sleep 1
20715                 touch $DIR/$tdir/striped_dir/file_$i || error "touch error $i"
20716                 mtime2=$(stat -c %Y $DIR/$tdir/striped_dir)
20717                 [ $mtime1 -eq $mtime2 ] && error "mtime unchanged after create"
20718                 sleep 1
20719                 rm -f $DIR/$tdir/striped_dir/file_$i || error "unlink error $i"
20720                 mtime3=$(stat -c %Y $DIR/$tdir/striped_dir)
20721                 [ $mtime2 -eq $mtime3 ] && error "mtime unchanged after unlink"
20722         done
20723         true
20724 }
20725 run_test 300b "check ctime/mtime for striped dir"
20726
20727 test_300c() {
20728         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
20729                 skip "skipped for lustre < 2.7.0"
20730         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20731         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20732
20733         local file_count
20734
20735         mkdir -p $DIR/$tdir
20736         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir ||
20737                 error "set striped dir error"
20738
20739         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/striped_dir ||
20740                 error "chown striped dir failed"
20741
20742         $RUNAS createmany -o $DIR/$tdir/striped_dir/f 5000 ||
20743                 error "create 5k files failed"
20744
20745         file_count=$(ls $DIR/$tdir/striped_dir | wc -l)
20746
20747         [ "$file_count" = 5000 ] || error "file count $file_count != 5000"
20748
20749         rm -rf $DIR/$tdir
20750 }
20751 run_test 300c "chown && check ls under striped directory"
20752
20753 test_300d() {
20754         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
20755                 skip "skipped for lustre < 2.7.0"
20756         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20757         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20758
20759         local stripe_count
20760         local file
20761
20762         mkdir -p $DIR/$tdir
20763         $LFS setstripe -c 2 $DIR/$tdir
20764
20765         #local striped directory
20766         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
20767                 error "set striped dir error"
20768         #look at the directories for debug purposes
20769         ls -l $DIR/$tdir
20770         $LFS getdirstripe $DIR/$tdir
20771         ls -l $DIR/$tdir/striped_dir
20772         $LFS getdirstripe $DIR/$tdir/striped_dir
20773         createmany -o $DIR/$tdir/striped_dir/f 10 ||
20774                 error "create 10 files failed"
20775
20776         #remote striped directory
20777         $LFS setdirstripe -i 1 -c 2 $DIR/$tdir/remote_striped_dir ||
20778                 error "set striped dir error"
20779         #look at the directories for debug purposes
20780         ls -l $DIR/$tdir
20781         $LFS getdirstripe $DIR/$tdir
20782         ls -l $DIR/$tdir/remote_striped_dir
20783         $LFS getdirstripe $DIR/$tdir/remote_striped_dir
20784         createmany -o $DIR/$tdir/remote_striped_dir/f 10 ||
20785                 error "create 10 files failed"
20786
20787         for file in $(find $DIR/$tdir); do
20788                 stripe_count=$($LFS getstripe -c $file)
20789                 [ $stripe_count -eq 2 ] ||
20790                         error "wrong stripe $stripe_count for $file"
20791         done
20792
20793         rm -rf $DIR/$tdir
20794 }
20795 run_test 300d "check default stripe under striped directory"
20796
20797 test_300e() {
20798         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
20799                 skip "Need MDS version at least 2.7.55"
20800         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20801         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20802
20803         local stripe_count
20804         local file
20805
20806         mkdir -p $DIR/$tdir
20807
20808         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
20809                 error "set striped dir error"
20810
20811         touch $DIR/$tdir/striped_dir/a
20812         touch $DIR/$tdir/striped_dir/b
20813         touch $DIR/$tdir/striped_dir/c
20814
20815         mkdir $DIR/$tdir/striped_dir/dir_a
20816         mkdir $DIR/$tdir/striped_dir/dir_b
20817         mkdir $DIR/$tdir/striped_dir/dir_c
20818
20819         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_a ||
20820                 error "set striped adir under striped dir error"
20821
20822         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_b ||
20823                 error "set striped bdir under striped dir error"
20824
20825         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_c ||
20826                 error "set striped cdir under striped dir error"
20827
20828         mrename $DIR/$tdir/striped_dir/dir_a $DIR/$tdir/striped_dir/dir_b ||
20829                 error "rename dir under striped dir fails"
20830
20831         mrename $DIR/$tdir/striped_dir/stp_a $DIR/$tdir/striped_dir/stp_b ||
20832                 error "rename dir under different stripes fails"
20833
20834         mrename $DIR/$tdir/striped_dir/a $DIR/$tdir/striped_dir/c ||
20835                 error "rename file under striped dir should succeed"
20836
20837         mrename $DIR/$tdir/striped_dir/dir_b $DIR/$tdir/striped_dir/dir_c ||
20838                 error "rename dir under striped dir should succeed"
20839
20840         rm -rf $DIR/$tdir
20841 }
20842 run_test 300e "check rename under striped directory"
20843
20844 test_300f() {
20845         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20846         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20847         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
20848                 skip "Need MDS version at least 2.7.55"
20849
20850         local stripe_count
20851         local file
20852
20853         rm -rf $DIR/$tdir
20854         mkdir -p $DIR/$tdir
20855
20856         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
20857                 error "set striped dir error"
20858
20859         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir1 ||
20860                 error "set striped dir error"
20861
20862         touch $DIR/$tdir/striped_dir/a
20863         mkdir $DIR/$tdir/striped_dir/dir_a
20864         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir/stp_a ||
20865                 error "create striped dir under striped dir fails"
20866
20867         touch $DIR/$tdir/striped_dir1/b
20868         mkdir $DIR/$tdir/striped_dir1/dir_b
20869         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir/stp_b ||
20870                 error "create striped dir under striped dir fails"
20871
20872         mrename $DIR/$tdir/striped_dir/dir_a $DIR/$tdir/striped_dir1/dir_b ||
20873                 error "rename dir under different striped dir should fail"
20874
20875         mrename $DIR/$tdir/striped_dir/stp_a $DIR/$tdir/striped_dir1/stp_b ||
20876                 error "rename striped dir under diff striped dir should fail"
20877
20878         mrename $DIR/$tdir/striped_dir/a $DIR/$tdir/striped_dir1/a ||
20879                 error "rename file under diff striped dirs fails"
20880
20881         rm -rf $DIR/$tdir
20882 }
20883 run_test 300f "check rename cross striped directory"
20884
20885 test_300_check_default_striped_dir()
20886 {
20887         local dirname=$1
20888         local default_count=$2
20889         local default_index=$3
20890         local stripe_count
20891         local stripe_index
20892         local dir_stripe_index
20893         local dir
20894
20895         echo "checking $dirname $default_count $default_index"
20896         $LFS setdirstripe -D -c $default_count -i $default_index \
20897                                 -t all_char $DIR/$tdir/$dirname ||
20898                 error "set default stripe on striped dir error"
20899         stripe_count=$($LFS getdirstripe -D -c $DIR/$tdir/$dirname)
20900         [ $stripe_count -eq $default_count ] ||
20901                 error "expect $default_count get $stripe_count for $dirname"
20902
20903         stripe_index=$($LFS getdirstripe -D -i $DIR/$tdir/$dirname)
20904         [ $stripe_index -eq $default_index ] ||
20905                 error "expect $default_index get $stripe_index for $dirname"
20906
20907         mkdir $DIR/$tdir/$dirname/{test1,test2,test3,test4} ||
20908                                                 error "create dirs failed"
20909
20910         createmany -o $DIR/$tdir/$dirname/f- 10 || error "create files failed"
20911         unlinkmany $DIR/$tdir/$dirname/f- 10    || error "unlink files failed"
20912         for dir in $(find $DIR/$tdir/$dirname/*); do
20913                 stripe_count=$($LFS getdirstripe -c $dir)
20914                 [ $stripe_count -eq $default_count ] ||
20915                 [ $stripe_count -eq 0 ] || [ $default_count -eq 1 ] ||
20916                 error "stripe count $default_count != $stripe_count for $dir"
20917
20918                 stripe_index=$($LFS getdirstripe -i $dir)
20919                 [ $default_index -eq -1 ] ||
20920                         [ $stripe_index -eq $default_index ] ||
20921                         error "$stripe_index != $default_index for $dir"
20922
20923                 #check default stripe
20924                 stripe_count=$($LFS getdirstripe -D -c $dir)
20925                 [ $stripe_count -eq $default_count ] ||
20926                 error "default count $default_count != $stripe_count for $dir"
20927
20928                 stripe_index=$($LFS getdirstripe -D -i $dir)
20929                 [ $stripe_index -eq $default_index ] ||
20930                 error "default index $default_index != $stripe_index for $dir"
20931         done
20932         rmdir $DIR/$tdir/$dirname/* || error "rmdir failed"
20933 }
20934
20935 test_300g() {
20936         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20937         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
20938                 skip "Need MDS version at least 2.7.55"
20939
20940         local dir
20941         local stripe_count
20942         local stripe_index
20943
20944         mkdir $DIR/$tdir
20945         mkdir $DIR/$tdir/normal_dir
20946
20947         #Checking when client cache stripe index
20948         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
20949         $LFS setdirstripe -D -i1 $DIR/$tdir/striped_dir ||
20950                 error "create striped_dir failed"
20951
20952         $LFS setdirstripe -i0 $DIR/$tdir/striped_dir/dir0 ||
20953                 error "create dir0 fails"
20954         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/dir0)
20955         [ $stripe_index -eq 0 ] ||
20956                 error "dir0 expect index 0 got $stripe_index"
20957
20958         mkdir $DIR/$tdir/striped_dir/dir1 ||
20959                 error "create dir1 fails"
20960         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/dir1)
20961         [ $stripe_index -eq 1 ] ||
20962                 error "dir1 expect index 1 got $stripe_index"
20963
20964         #check default stripe count/stripe index
20965         test_300_check_default_striped_dir normal_dir $MDSCOUNT 1
20966         test_300_check_default_striped_dir normal_dir 1 0
20967         test_300_check_default_striped_dir normal_dir 2 1
20968         test_300_check_default_striped_dir normal_dir 2 -1
20969
20970         #delete default stripe information
20971         echo "delete default stripeEA"
20972         $LFS setdirstripe -d $DIR/$tdir/normal_dir ||
20973                 error "set default stripe on striped dir error"
20974
20975         mkdir -p $DIR/$tdir/normal_dir/{test1,test2,test3,test4}
20976         for dir in $(find $DIR/$tdir/normal_dir/*); do
20977                 stripe_count=$($LFS getdirstripe -c $dir)
20978                 [ $stripe_count -eq 0 ] ||
20979                         error "expect 1 get $stripe_count for $dir"
20980                 stripe_index=$($LFS getdirstripe -i $dir)
20981                 [ $stripe_index -eq 0 ] ||
20982                         error "expect 0 get $stripe_index for $dir"
20983         done
20984 }
20985 run_test 300g "check default striped directory for normal directory"
20986
20987 test_300h() {
20988         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20989         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
20990                 skip "Need MDS version at least 2.7.55"
20991
20992         local dir
20993         local stripe_count
20994
20995         mkdir $DIR/$tdir
20996         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
20997                 error "set striped dir error"
20998
20999         test_300_check_default_striped_dir striped_dir $MDSCOUNT 1
21000         test_300_check_default_striped_dir striped_dir 1 0
21001         test_300_check_default_striped_dir striped_dir 2 1
21002         test_300_check_default_striped_dir striped_dir 2 -1
21003
21004         #delete default stripe information
21005         $LFS setdirstripe -d $DIR/$tdir/striped_dir ||
21006                 error "set default stripe on striped dir error"
21007
21008         mkdir -p $DIR/$tdir/striped_dir/{test1,test2,test3,test4}
21009         for dir in $(find $DIR/$tdir/striped_dir/*); do
21010                 stripe_count=$($LFS getdirstripe -c $dir)
21011                 [ $stripe_count -eq 0 ] ||
21012                         error "expect 1 get $stripe_count for $dir"
21013         done
21014 }
21015 run_test 300h "check default striped directory for striped directory"
21016
21017 test_300i() {
21018         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21019         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21020         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
21021                 skip "Need MDS version at least 2.7.55"
21022
21023         local stripe_count
21024         local file
21025
21026         mkdir $DIR/$tdir
21027
21028         $LFS setdirstripe -i 0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
21029                 error "set striped dir error"
21030
21031         createmany -o $DIR/$tdir/striped_dir/f- 10 ||
21032                 error "create files under striped dir failed"
21033
21034         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/hashdir ||
21035                 error "set striped hashdir error"
21036
21037         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/hashdir/d0 ||
21038                 error "create dir0 under hash dir failed"
21039         $LFS setdirstripe -i0 -c$MDSCOUNT -H fnv_1a_64 $DIR/$tdir/hashdir/d1 ||
21040                 error "create dir1 under hash dir failed"
21041
21042         # unfortunately, we need to umount to clear dir layout cache for now
21043         # once we fully implement dir layout, we can drop this
21044         umount_client $MOUNT || error "umount failed"
21045         mount_client $MOUNT || error "mount failed"
21046
21047         $LFS find -H fnv_1a_64 $DIR/$tdir/hashdir
21048         local dircnt=$($LFS find -H fnv_1a_64 $DIR/$tdir/hashdir | wc -l)
21049         [ $dircnt -eq 1 ] || error "lfs find striped dir got:$dircnt,except:1"
21050
21051         #set the stripe to be unknown hash type
21052         #define OBD_FAIL_UNKNOWN_LMV_STRIPE     0x1901
21053         $LCTL set_param fail_loc=0x1901
21054         for ((i = 0; i < 10; i++)); do
21055                 $CHECKSTAT -t file $DIR/$tdir/striped_dir/f-$i ||
21056                         error "stat f-$i failed"
21057                 rm $DIR/$tdir/striped_dir/f-$i || error "unlink f-$i failed"
21058         done
21059
21060         touch $DIR/$tdir/striped_dir/f0 &&
21061                 error "create under striped dir with unknown hash should fail"
21062
21063         $LCTL set_param fail_loc=0
21064
21065         umount_client $MOUNT || error "umount failed"
21066         mount_client $MOUNT || error "mount failed"
21067
21068         return 0
21069 }
21070 run_test 300i "client handle unknown hash type striped directory"
21071
21072 test_300j() {
21073         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21074         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21075         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
21076                 skip "Need MDS version at least 2.7.55"
21077
21078         local stripe_count
21079         local file
21080
21081         mkdir $DIR/$tdir
21082
21083         #define OBD_FAIL_SPLIT_UPDATE_REC       0x1702
21084         $LCTL set_param fail_loc=0x1702
21085         $LFS setdirstripe -i 0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
21086                 error "set striped dir error"
21087
21088         createmany -o $DIR/$tdir/striped_dir/f- 10 ||
21089                 error "create files under striped dir failed"
21090
21091         $LCTL set_param fail_loc=0
21092
21093         rm -rf $DIR/$tdir || error "unlink striped dir fails"
21094
21095         return 0
21096 }
21097 run_test 300j "test large update record"
21098
21099 test_300k() {
21100         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21101         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21102         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
21103                 skip "Need MDS version at least 2.7.55"
21104
21105         # this test needs a huge transaction
21106         local kb
21107         kb=$(do_facet $SINGLEMDS "$LCTL get_param -n \
21108              osd*.$FSNAME-MDT0000.kbytestotal")
21109         [ $kb -lt $((1024*1024)) ] && skip "MDT0 too small: $kb"
21110
21111         local stripe_count
21112         local file
21113
21114         mkdir $DIR/$tdir
21115
21116         #define OBD_FAIL_LARGE_STRIPE   0x1703
21117         $LCTL set_param fail_loc=0x1703
21118         $LFS setdirstripe -i 0 -c192 $DIR/$tdir/striped_dir ||
21119                 error "set striped dir error"
21120         $LCTL set_param fail_loc=0
21121
21122         $LFS getdirstripe $DIR/$tdir/striped_dir ||
21123                 error "getstripeddir fails"
21124         rm -rf $DIR/$tdir/striped_dir ||
21125                 error "unlink striped dir fails"
21126
21127         return 0
21128 }
21129 run_test 300k "test large striped directory"
21130
21131 test_300l() {
21132         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21133         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21134         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
21135                 skip "Need MDS version at least 2.7.55"
21136
21137         local stripe_index
21138
21139         test_mkdir -p $DIR/$tdir/striped_dir
21140         chown $RUNAS_ID $DIR/$tdir/striped_dir ||
21141                         error "chown $RUNAS_ID failed"
21142         $LFS setdirstripe -i 1 -D $DIR/$tdir/striped_dir ||
21143                 error "set default striped dir failed"
21144
21145         #define OBD_FAIL_MDS_STALE_DIR_LAYOUT    0x158
21146         $LCTL set_param fail_loc=0x80000158
21147         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir || error "create dir fails"
21148
21149         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/test_dir)
21150         [ $stripe_index -eq 1 ] ||
21151                 error "expect 1 get $stripe_index for $dir"
21152 }
21153 run_test 300l "non-root user to create dir under striped dir with stale layout"
21154
21155 test_300m() {
21156         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21157         [ $MDSCOUNT -ge 2 ] && skip_env "Only for single MDT"
21158         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
21159                 skip "Need MDS version at least 2.7.55"
21160
21161         mkdir -p $DIR/$tdir/striped_dir
21162         $LFS setdirstripe -D -c 1 $DIR/$tdir/striped_dir ||
21163                 error "set default stripes dir error"
21164
21165         mkdir $DIR/$tdir/striped_dir/a || error "mkdir a fails"
21166
21167         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir/a)
21168         [ $stripe_count -eq 0 ] ||
21169                         error "expect 0 get $stripe_count for a"
21170
21171         $LFS setdirstripe -D -c 2 $DIR/$tdir/striped_dir ||
21172                 error "set default stripes dir error"
21173
21174         mkdir $DIR/$tdir/striped_dir/b || error "mkdir b fails"
21175
21176         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir/b)
21177         [ $stripe_count -eq 0 ] ||
21178                         error "expect 0 get $stripe_count for b"
21179
21180         $LFS setdirstripe -D -c1 -i2 $DIR/$tdir/striped_dir ||
21181                 error "set default stripes dir error"
21182
21183         mkdir $DIR/$tdir/striped_dir/c &&
21184                 error "default stripe_index is invalid, mkdir c should fails"
21185
21186         rm -rf $DIR/$tdir || error "rmdir fails"
21187 }
21188 run_test 300m "setstriped directory on single MDT FS"
21189
21190 cleanup_300n() {
21191         local list=$(comma_list $(mdts_nodes))
21192
21193         trap 0
21194         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
21195 }
21196
21197 test_300n() {
21198         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21199         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21200         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
21201                 skip "Need MDS version at least 2.7.55"
21202         remote_mds_nodsh && skip "remote MDS with nodsh"
21203
21204         local stripe_index
21205         local list=$(comma_list $(mdts_nodes))
21206
21207         trap cleanup_300n RETURN EXIT
21208         mkdir -p $DIR/$tdir
21209         chmod 777 $DIR/$tdir
21210         $RUNAS $LFS setdirstripe -i0 -c$MDSCOUNT \
21211                                 $DIR/$tdir/striped_dir > /dev/null 2>&1 &&
21212                 error "create striped dir succeeds with gid=0"
21213
21214         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=-1
21215         $RUNAS $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir ||
21216                 error "create striped dir fails with gid=-1"
21217
21218         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
21219         $RUNAS $LFS setdirstripe -i 1 -c$MDSCOUNT -D \
21220                                 $DIR/$tdir/striped_dir > /dev/null 2>&1 &&
21221                 error "set default striped dir succeeds with gid=0"
21222
21223
21224         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=-1
21225         $RUNAS $LFS setdirstripe -i 1 -c$MDSCOUNT -D $DIR/$tdir/striped_dir ||
21226                 error "set default striped dir fails with gid=-1"
21227
21228
21229         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
21230         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir ||
21231                                         error "create test_dir fails"
21232         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir1 ||
21233                                         error "create test_dir1 fails"
21234         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir2 ||
21235                                         error "create test_dir2 fails"
21236         cleanup_300n
21237 }
21238 run_test 300n "non-root user to create dir under striped dir with default EA"
21239
21240 test_300o() {
21241         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21242         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21243         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
21244                 skip "Need MDS version at least 2.7.55"
21245
21246         local numfree1
21247         local numfree2
21248
21249         mkdir -p $DIR/$tdir
21250
21251         numfree1=$(lctl get_param -n mdc.*MDT0000*.filesfree)
21252         numfree2=$(lctl get_param -n mdc.*MDT0001*.filesfree)
21253         if [ $numfree1 -lt 66000 ] || [ $numfree2 -lt 66000 ]; then
21254                 skip "not enough free inodes $numfree1 $numfree2"
21255         fi
21256
21257         numfree1=$(lctl get_param -n mdc.*MDT0000-mdc-*.kbytesfree)
21258         numfree2=$(lctl get_param -n mdc.*MDT0001-mdc-*.kbytesfree)
21259         if [ $numfree1 -lt 300000 ] || [ $numfree2 -lt 300000 ]; then
21260                 skip "not enough free space $numfree1 $numfree2"
21261         fi
21262
21263         $LFS setdirstripe -c2 $DIR/$tdir/striped_dir ||
21264                 error "setdirstripe fails"
21265
21266         createmany -d $DIR/$tdir/striped_dir/d 131000 ||
21267                 error "create dirs fails"
21268
21269         $LCTL set_param ldlm.namespaces.*mdc-*.lru_size=0
21270         ls $DIR/$tdir/striped_dir > /dev/null ||
21271                 error "ls striped dir fails"
21272         unlinkmany -d $DIR/$tdir/striped_dir/d 131000 ||
21273                 error "unlink big striped dir fails"
21274 }
21275 run_test 300o "unlink big sub stripe(> 65000 subdirs)"
21276
21277 test_300p() {
21278         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21279         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21280         remote_mds_nodsh && skip "remote MDS with nodsh"
21281
21282         mkdir -p $DIR/$tdir
21283
21284         #define OBD_FAIL_OUT_ENOSPC     0x1704
21285         do_facet mds2 lctl set_param fail_loc=0x80001704
21286         $LFS setdirstripe -i 0 -c2 $DIR/$tdir/bad_striped_dir > /dev/null 2>&1 \
21287                  && error "create striped directory should fail"
21288
21289         [ -e $DIR/$tdir/bad_striped_dir ] && error "striped dir exists"
21290
21291         $LFS setdirstripe -c2 $DIR/$tdir/bad_striped_dir
21292         true
21293 }
21294 run_test 300p "create striped directory without space"
21295
21296 test_300q() {
21297         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21298         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21299
21300         local fd=$(free_fd)
21301         local cmd="exec $fd<$tdir"
21302         cd $DIR
21303         $LFS mkdir -c $MDSCOUNT $tdir || error "create $tdir fails"
21304         eval $cmd
21305         cmd="exec $fd<&-"
21306         trap "eval $cmd" EXIT
21307         cd $tdir || error "cd $tdir fails"
21308         rmdir  ../$tdir || error "rmdir $tdir fails"
21309         mkdir local_dir && error "create dir succeeds"
21310         $LFS setdirstripe -i1 remote_dir && error "create remote dir succeeds"
21311         eval $cmd
21312         return 0
21313 }
21314 run_test 300q "create remote directory under orphan directory"
21315
21316 test_300r() {
21317         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
21318                 skip "Need MDS version at least 2.7.55" && return
21319         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
21320
21321         mkdir $DIR/$tdir
21322
21323         $LFS setdirstripe -i 0 -c -1 $DIR/$tdir/striped_dir ||
21324                 error "set striped dir error"
21325
21326         $LFS getdirstripe $DIR/$tdir/striped_dir ||
21327                 error "getstripeddir fails"
21328
21329         local stripe_count
21330         stripe_count=$($LFS getdirstripe $DIR/$tdir/striped_dir |
21331                       awk '/lmv_stripe_count:/ { print $2 }')
21332
21333         [ $MDSCOUNT -ne $stripe_count ] &&
21334                 error "wrong stripe count $stripe_count expected $MDSCOUNT"
21335
21336         rm -rf $DIR/$tdir/striped_dir ||
21337                 error "unlink striped dir fails"
21338 }
21339 run_test 300r "test -1 striped directory"
21340
21341 prepare_remote_file() {
21342         mkdir $DIR/$tdir/src_dir ||
21343                 error "create remote source failed"
21344
21345         cp /etc/hosts $DIR/$tdir/src_dir/a ||
21346                  error "cp to remote source failed"
21347         touch $DIR/$tdir/src_dir/a
21348
21349         $LFS mkdir -i 1 $DIR/$tdir/tgt_dir ||
21350                 error "create remote target dir failed"
21351
21352         touch $DIR/$tdir/tgt_dir/b
21353
21354         mrename $DIR/$tdir/src_dir/a $DIR/$tdir/tgt_dir/b ||
21355                 error "rename dir cross MDT failed!"
21356
21357         $CHECKSTAT -t file $DIR/$tdir/src_dir/a &&
21358                 error "src_child still exists after rename"
21359
21360         $CHECKSTAT -t file $DIR/$tdir/tgt_dir/b ||
21361                 error "missing file(a) after rename"
21362
21363         diff /etc/hosts $DIR/$tdir/tgt_dir/b ||
21364                 error "diff after rename"
21365 }
21366
21367 test_310a() {
21368         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 4 MDTs"
21369         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21370
21371         local remote_file=$DIR/$tdir/tgt_dir/b
21372
21373         mkdir -p $DIR/$tdir
21374
21375         prepare_remote_file || error "prepare remote file failed"
21376
21377         #open-unlink file
21378         $OPENUNLINK $remote_file $remote_file ||
21379                 error "openunlink $remote_file failed"
21380         $CHECKSTAT -a $remote_file || error "$remote_file exists"
21381 }
21382 run_test 310a "open unlink remote file"
21383
21384 test_310b() {
21385         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 4 MDTs"
21386         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21387
21388         local remote_file=$DIR/$tdir/tgt_dir/b
21389
21390         mkdir -p $DIR/$tdir
21391
21392         prepare_remote_file || error "prepare remote file failed"
21393
21394         ln $remote_file $DIR/$tfile || error "link failed for remote file"
21395         $MULTIOP $DIR/$tfile Ouc || error "mulitop failed"
21396         $CHECKSTAT -t file $remote_file || error "check file failed"
21397 }
21398 run_test 310b "unlink remote file with multiple links while open"
21399
21400 test_310c() {
21401         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21402         [[ $MDSCOUNT -lt 4 ]] && skip_env "needs >= 4 MDTs"
21403
21404         local remote_file=$DIR/$tdir/tgt_dir/b
21405
21406         mkdir -p $DIR/$tdir
21407
21408         prepare_remote_file || error "prepare remote file failed"
21409
21410         ln $remote_file $DIR/$tfile || error "link failed for remote file"
21411         multiop_bg_pause $remote_file O_uc ||
21412                         error "mulitop failed for remote file"
21413         MULTIPID=$!
21414         $MULTIOP $DIR/$tfile Ouc
21415         kill -USR1 $MULTIPID
21416         wait $MULTIPID
21417 }
21418 run_test 310c "open-unlink remote file with multiple links"
21419
21420 #LU-4825
21421 test_311() {
21422         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21423         [ $OSTCOUNT -lt 2 ] && skip "needs >= 2 OSTs"
21424         [ $MDS1_VERSION -lt $(version_code 2.8.54) ] &&
21425                 skip "lustre < 2.8.54 does not contain LU-4825 fix"
21426         remote_mds_nodsh && skip "remote MDS with nodsh"
21427
21428         local old_iused=$($LFS df -i | grep OST0000 | awk '{ print $3 }')
21429         local mdts=$(comma_list $(mdts_nodes))
21430
21431         mkdir -p $DIR/$tdir
21432         $LFS setstripe -i 0 -c 1 $DIR/$tdir
21433         createmany -o $DIR/$tdir/$tfile. 1000
21434
21435         # statfs data is not real time, let's just calculate it
21436         old_iused=$((old_iused + 1000))
21437
21438         local count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
21439                         osp.*OST0000*MDT0000.create_count")
21440         local max_count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
21441                                 osp.*OST0000*MDT0000.max_create_count")
21442         do_nodes $mdts "$LCTL set_param -n osp.*OST0000*.max_create_count=0"
21443
21444         $LFS setstripe -i 0 $DIR/$tdir/$tfile || error "setstripe failed"
21445         local index=$($LFS getstripe -i $DIR/$tdir/$tfile)
21446         [ $index -ne 0 ] || error "$tfile stripe index is 0"
21447
21448         unlinkmany $DIR/$tdir/$tfile. 1000
21449
21450         do_nodes $mdts "$LCTL set_param -n \
21451                         osp.*OST0000*.max_create_count=$max_count"
21452         [ $MDS1_VERSION -lt $(version_code 2.12.51) ] &&
21453                 do_nodes $mdts "$LCTL set_param -n \
21454                                 osp.*OST0000*.create_count=$count"
21455         do_nodes $mdts "$LCTL get_param osp.*OST0000*.create_count" |
21456                         grep "=0" && error "create_count is zero"
21457
21458         local new_iused
21459         for i in $(seq 120); do
21460                 new_iused=$($LFS df -i | grep OST0000 | awk '{ print $3 }')
21461                 # system may be too busy to destroy all objs in time, use
21462                 # a somewhat small value to not fail autotest
21463                 [ $((old_iused - new_iused)) -gt 400 ] && break
21464                 sleep 1
21465         done
21466
21467         echo "waited $i sec, old Iused $old_iused, new Iused $new_iused"
21468         [ $((old_iused - new_iused)) -gt 400 ] ||
21469                 error "objs not destroyed after unlink"
21470 }
21471 run_test 311 "disable OSP precreate, and unlink should destroy objs"
21472
21473 zfs_oid_to_objid()
21474 {
21475         local ost=$1
21476         local objid=$2
21477
21478         local vdevdir=$(dirname $(facet_vdevice $ost))
21479         local cmd="$ZDB -e -p $vdevdir -ddddd $(facet_device $ost)"
21480         local zfs_zapid=$(do_facet $ost $cmd |
21481                           grep -w "/O/0/d$((objid%32))" -C 5 |
21482                           awk '/Object/{getline; print $1}')
21483         local zfs_objid=$(do_facet $ost $cmd $zfs_zapid |
21484                           awk "/$objid = /"'{printf $3}')
21485
21486         echo $zfs_objid
21487 }
21488
21489 zfs_object_blksz() {
21490         local ost=$1
21491         local objid=$2
21492
21493         local vdevdir=$(dirname $(facet_vdevice $ost))
21494         local cmd="$ZDB -e -p $vdevdir -dddd $(facet_device $ost)"
21495         local blksz=$(do_facet $ost $cmd $objid |
21496                       awk '/dblk/{getline; printf $4}')
21497
21498         case "${blksz: -1}" in
21499                 k|K) blksz=$((${blksz:0:$((${#blksz} - 1))}*1024)) ;;
21500                 m|M) blksz=$((${blksz:0:$((${#blksz} - 1))}*1024*1024)) ;;
21501                 *) ;;
21502         esac
21503
21504         echo $blksz
21505 }
21506
21507 test_312() { # LU-4856
21508         remote_ost_nodsh && skip "remote OST with nodsh"
21509         [ "$ost1_FSTYPE" = "zfs" ] ||
21510                 skip_env "the test only applies to zfs"
21511
21512         local max_blksz=$(do_facet ost1 \
21513                           $ZFS get -p recordsize $(facet_device ost1) |
21514                           awk '!/VALUE/{print $3}')
21515
21516         # to make life a little bit easier
21517         $LFS mkdir -c 1 -i 0 $DIR/$tdir
21518         $LFS setstripe -c 1 -i 0 $DIR/$tdir
21519
21520         local tf=$DIR/$tdir/$tfile
21521         touch $tf
21522         local oid=$($LFS getstripe $tf | awk '/obdidx/{getline; print $2}')
21523
21524         # Get ZFS object id
21525         local zfs_objid=$(zfs_oid_to_objid ost1 $oid)
21526         # block size change by sequential overwrite
21527         local bs
21528
21529         for ((bs=$PAGE_SIZE; bs <= max_blksz; bs *= 4)) ; do
21530                 dd if=/dev/zero of=$tf bs=$bs count=1 oflag=sync conv=notrunc
21531
21532                 local blksz=$(zfs_object_blksz ost1 $zfs_objid)
21533                 [ $blksz -eq $bs ] || error "blksz error: $blksz, expected: $bs"
21534         done
21535         rm -f $tf
21536
21537         # block size change by sequential append write
21538         dd if=/dev/zero of=$tf bs=$PAGE_SIZE count=1 oflag=sync conv=notrunc
21539         oid=$($LFS getstripe $tf | awk '/obdidx/{getline; print $2}')
21540         zfs_objid=$(zfs_oid_to_objid ost1 $oid)
21541         local count
21542
21543         for ((count = 1; count < $((max_blksz / PAGE_SIZE)); count *= 2)); do
21544                 dd if=/dev/zero of=$tf bs=$PAGE_SIZE count=$count seek=$count \
21545                         oflag=sync conv=notrunc
21546
21547                 blksz=$(zfs_object_blksz ost1 $zfs_objid)
21548                 [ $blksz -eq $((2 * count * PAGE_SIZE)) ] ||
21549                         error "blksz error, actual $blksz, " \
21550                                 "expected: 2 * $count * $PAGE_SIZE"
21551         done
21552         rm -f $tf
21553
21554         # random write
21555         touch $tf
21556         oid=$($LFS getstripe $tf | awk '/obdidx/{getline; print $2}')
21557         zfs_objid=$(zfs_oid_to_objid ost1 $oid)
21558
21559         dd if=/dev/zero of=$tf bs=1K count=1 oflag=sync conv=notrunc
21560         blksz=$(zfs_object_blksz ost1 $zfs_objid)
21561         [ $blksz -eq $PAGE_SIZE ] ||
21562                 error "blksz error: $blksz, expected: $PAGE_SIZE"
21563
21564         dd if=/dev/zero of=$tf bs=64K count=1 oflag=sync conv=notrunc seek=128
21565         blksz=$(zfs_object_blksz ost1 $zfs_objid)
21566         [ $blksz -eq 65536 ] || error "blksz error: $blksz, expected: 64k"
21567
21568         dd if=/dev/zero of=$tf bs=1M count=1 oflag=sync conv=notrunc
21569         blksz=$(zfs_object_blksz ost1 $zfs_objid)
21570         [ $blksz -eq 65536 ] || error "rewrite error: $blksz, expected: 64k"
21571 }
21572 run_test 312 "make sure ZFS adjusts its block size by write pattern"
21573
21574 test_313() {
21575         remote_ost_nodsh && skip "remote OST with nodsh"
21576
21577         local file=$DIR/$tfile
21578
21579         rm -f $file
21580         $LFS setstripe -c 1 -i 0 $file || error "setstripe failed"
21581
21582         # define OBD_FAIL_TGT_RCVD_EIO           0x720
21583         do_facet ost1 "$LCTL set_param fail_loc=0x720"
21584         dd if=/dev/zero of=$file bs=$PAGE_SIZE oflag=direct count=1 &&
21585                 error "write should failed"
21586         do_facet ost1 "$LCTL set_param fail_loc=0"
21587         rm -f $file
21588 }
21589 run_test 313 "io should fail after last_rcvd update fail"
21590
21591 test_314() {
21592         [ $OSTCOUNT -lt 2 ] && skip "needs >= 2 OSTs"
21593
21594         $LFS setstripe -c 2 -i 0 $DIR/$tfile || error "setstripe failed"
21595         do_facet ost1 "$LCTL set_param fail_loc=0x720"
21596         rm -f $DIR/$tfile
21597         wait_delete_completed
21598         do_facet ost1 "$LCTL set_param fail_loc=0"
21599 }
21600 run_test 314 "OSP shouldn't fail after last_rcvd update failure"
21601
21602 test_315() { # LU-618
21603         [ -f /proc/$$/io ] || skip_env "no IO accounting in kernel"
21604
21605         local file=$DIR/$tfile
21606         rm -f $file
21607
21608         $MULTIOP $file oO_CREAT:O_DIRECT:O_RDWR:w4063232c ||
21609                 error "multiop file write failed"
21610         $MULTIOP $file oO_RDONLY:r4063232_c &
21611         PID=$!
21612
21613         sleep 2
21614
21615         local rbytes=$(awk '/read_bytes/ { print $2 }' /proc/$PID/io)
21616         kill -USR1 $PID
21617
21618         [ $rbytes -gt 4000000 ] || error "read is not accounted ($rbytes)"
21619         rm -f $file
21620 }
21621 run_test 315 "read should be accounted"
21622
21623 test_316() {
21624         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
21625         large_xattr_enabled || skip_env "ea_inode feature disabled"
21626
21627         rm -rf $DIR/$tdir/d
21628         mkdir -p $DIR/$tdir/d
21629         chown nobody $DIR/$tdir/d
21630         touch $DIR/$tdir/d/file
21631
21632         $LFS mv -m1 $DIR/$tdir/d || error "lfs mv failed"
21633 }
21634 run_test 316 "lfs mv"
21635
21636 test_317() {
21637         [ $MDS1_VERSION -lt $(version_code 2.11.53) ] &&
21638                 skip "Need MDS version at least 2.11.53"
21639         if [ "$ost1_FSTYPE" == "zfs" ]; then
21640                 skip "LU-10370: no implementation for ZFS"
21641         fi
21642
21643         local trunc_sz
21644         local grant_blk_size
21645
21646         grant_blk_size=$($LCTL get_param osc.$FSNAME*.import |
21647                         awk '/grant_block_size:/ { print $2; exit; }')
21648         #
21649         # Create File of size 5M. Truncate it to below size's and verify
21650         # blocks count.
21651         #
21652         dd if=/dev/zero of=$DIR/$tfile bs=5M count=1 conv=fsync ||
21653                 error "Create file $DIR/$tfile failed"
21654         stack_trap "rm -f $DIR/$tfile" EXIT
21655
21656         for trunc_sz in 2097152 4097 4000 509 0; do
21657                 $TRUNCATE $DIR/$tfile $trunc_sz ||
21658                         error "truncate $tfile to $trunc_sz failed"
21659                 local sz=$(stat --format=%s $DIR/$tfile)
21660                 local blk=$(stat --format=%b $DIR/$tfile)
21661                 local trunc_blk=$((((trunc_sz + (grant_blk_size - 1) ) /
21662                                      grant_blk_size) * 8))
21663
21664                 if [[ $blk -ne $trunc_blk ]]; then
21665                         $(which stat) $DIR/$tfile
21666                         error "Expected Block $trunc_blk got $blk for $tfile"
21667                 fi
21668
21669                 $CHECKSTAT -s $trunc_sz $DIR/$tfile ||
21670                         error "Expected Size $trunc_sz got $sz for $tfile"
21671         done
21672
21673         #
21674         # sparse file test
21675         # Create file with a hole and write actual two blocks. Block count
21676         # must be 16.
21677         #
21678         dd if=/dev/zero of=$DIR/$tfile bs=$grant_blk_size count=2 seek=5 \
21679                 conv=fsync || error "Create file : $DIR/$tfile"
21680
21681         # Calculate the final truncate size.
21682         trunc_sz=$(($(stat --format=%s $DIR/$tfile) - (grant_blk_size + 1)))
21683
21684         #
21685         # truncate to size $trunc_sz bytes. Strip the last block
21686         # The block count must drop to 8
21687         #
21688         $TRUNCATE $DIR/$tfile $trunc_sz ||
21689                 error "truncate $tfile to $trunc_sz failed"
21690
21691         local trunc_bsz=$((grant_blk_size / $(stat --format=%B $DIR/$tfile)))
21692         sz=$(stat --format=%s $DIR/$tfile)
21693         blk=$(stat --format=%b $DIR/$tfile)
21694
21695         if [[ $blk -ne $trunc_bsz ]]; then
21696                 $(which stat) $DIR/$tfile
21697                 error "Expected Block $trunc_bsz got $blk for $tfile"
21698         fi
21699
21700         $CHECKSTAT -s $trunc_sz $DIR/$tfile ||
21701                 error "Expected Size $trunc_sz got $sz for $tfile"
21702 }
21703 run_test 317 "Verify blocks get correctly update after truncate"
21704
21705 test_318() {
21706         local old_max_active=$($LCTL get_param -n \
21707                             llite.*.max_read_ahead_async_active 2>/dev/null)
21708
21709         $LCTL set_param llite.*.max_read_ahead_async_active=256
21710         local max_active=$($LCTL get_param -n \
21711                            llite.*.max_read_ahead_async_active 2>/dev/null)
21712         [ $max_active -ne 256 ] && error "expected 256 but got $max_active"
21713
21714         $LCTL set_param llite.*.max_read_ahead_async_active=0 ||
21715                 error "set max_read_ahead_async_active should succeed"
21716
21717         $LCTL set_param llite.*.max_read_ahead_async_active=512
21718         max_active=$($LCTL get_param -n \
21719                      llite.*.max_read_ahead_async_active 2>/dev/null)
21720         [ $max_active -eq 512 ] || error "expected 512 but got $max_active"
21721
21722         # restore @max_active
21723         [ $old_max_active -ne 0 ] && $LCTL set_param \
21724                 llite.*.max_read_ahead_async_active=$old_max_active
21725
21726         local old_threshold=$($LCTL get_param -n \
21727                 llite.*.read_ahead_async_file_threshold_mb 2>/dev/null)
21728         local max_per_file_mb=$($LCTL get_param -n \
21729                 llite.*.max_read_ahead_per_file_mb 2>/dev/null)
21730
21731         local invalid=$(($max_per_file_mb + 1))
21732         $LCTL set_param \
21733                 llite.*.read_ahead_async_file_threshold_mb=$invalid\
21734                         && error "set $invalid should fail"
21735
21736         local valid=$(($invalid - 1))
21737         $LCTL set_param \
21738                 llite.*.read_ahead_async_file_threshold_mb=$valid ||
21739                         error "set $valid should succeed"
21740         local threshold=$($LCTL get_param -n \
21741                 llite.*.read_ahead_async_file_threshold_mb 2>/dev/null)
21742         [ $threshold -eq $valid ] || error \
21743                 "expect threshold $valid got $threshold"
21744         $LCTL set_param \
21745                 llite.*.read_ahead_async_file_threshold_mb=$old_threshold
21746 }
21747 run_test 318 "Verify async readahead tunables"
21748
21749 test_319() {
21750         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return 0
21751
21752         local before=$(date +%s)
21753         local evict
21754         local mdir=$DIR/$tdir
21755         local file=$mdir/xxx
21756
21757         $LFS mkdir -i0 $mdir || error "mkdir $mdir fails"
21758         touch $file
21759
21760 #define OBD_FAIL_LDLM_LOCAL_CANCEL_PAUSE 0x32c
21761         $LCTL set_param fail_val=5 fail_loc=0x8000032c
21762         $LFS mv -m1 $file &
21763
21764         sleep 1
21765         dd if=$file of=/dev/null
21766         wait
21767         evict=$($LCTL get_param mdc.$FSNAME-MDT*.state |
21768           awk -F"[ [,]" '/EVICTED ]$/ { if (mx<$5) {mx=$5;} } END { print mx }')
21769
21770         [ -z "$evict" ] || [[ $evict -le $before ]] || error "eviction happened"
21771 }
21772 run_test 319 "lost lease lock on migrate error"
21773
21774 test_398a() { # LU-4198
21775         $LFS setstripe -c 1 -i 0 $DIR/$tfile
21776         $LCTL set_param ldlm.namespaces.*.lru_size=clear
21777
21778         # request a new lock on client
21779         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
21780
21781         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=direct conv=notrunc
21782         local lock_count=$($LCTL get_param -n \
21783                            ldlm.namespaces.*-OST0000-osc-ffff*.lru_size)
21784         [[ $lock_count -eq 0 ]] || error "lock should be cancelled by direct IO"
21785
21786         $LCTL set_param ldlm.namespaces.*-OST0000-osc-ffff*.lru_size=clear
21787
21788         # no lock cached, should use lockless IO and not enqueue new lock
21789         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=direct conv=notrunc
21790         lock_count=$($LCTL get_param -n \
21791                      ldlm.namespaces.*-OST0000-osc-ffff*.lru_size)
21792         [[ $lock_count -eq 0 ]] || error "no lock should be held by direct IO"
21793 }
21794 run_test 398a "direct IO should cancel lock otherwise lockless"
21795
21796 test_398b() { # LU-4198
21797         which fio || skip_env "no fio installed"
21798         $LFS setstripe -c -1 $DIR/$tfile
21799
21800         local size=12
21801         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$size
21802
21803         local njobs=4
21804         echo "mix direct rw ${size}M to OST0 by fio with $njobs jobs..."
21805         fio --name=rand-rw --rw=randrw --bs=$PAGE_SIZE --direct=1 \
21806                 --numjobs=$njobs --fallocate=none \
21807                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
21808                 --filename=$DIR/$tfile &
21809         bg_pid=$!
21810
21811         echo "mix buffer rw ${size}M to OST0 by fio with $njobs jobs..."
21812         fio --name=rand-rw --rw=randrw --bs=$PAGE_SIZE \
21813                 --numjobs=$njobs --fallocate=none \
21814                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
21815                 --filename=$DIR/$tfile || true
21816         wait $bg_pid
21817
21818         rm -rf $DIR/$tfile
21819 }
21820 run_test 398b "DIO and buffer IO race"
21821
21822 test_398c() { # LU-4198
21823         which fio || skip_env "no fio installed"
21824
21825         saved_debug=$($LCTL get_param -n debug)
21826         $LCTL set_param debug=0
21827
21828         local size=$(lctl get_param -n osc.$FSNAME-OST0000*.kbytesavail | head -1)
21829         ((size /= 1024)) # by megabytes
21830         ((size /= 2)) # write half of the OST at most
21831         [ $size -gt 40 ] && size=40 #reduce test time anyway
21832
21833         $LFS setstripe -c 1 $DIR/$tfile
21834
21835         # it seems like ldiskfs reserves more space than necessary if the
21836         # writing blocks are not mapped, so it extends the file firstly
21837         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$size && sync
21838         cancel_lru_locks osc
21839
21840         # clear and verify rpc_stats later
21841         $LCTL set_param osc.${FSNAME}-OST0000-osc-ffff*.rpc_stats=clear
21842
21843         local njobs=4
21844         echo "writing ${size}M to OST0 by fio with $njobs jobs..."
21845         fio --name=rand-write --rw=randwrite --bs=$PAGE_SIZE --direct=1 \
21846                 --numjobs=$njobs --fallocate=none --ioengine=libaio \
21847                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
21848                 --filename=$DIR/$tfile
21849         [ $? -eq 0 ] || error "fio write error"
21850
21851         [ $($LCTL get_param -n \
21852          ldlm.namespaces.${FSNAME}-OST0000-osc-ffff*.lock_count) -eq 0 ] ||
21853                 error "Locks were requested while doing AIO"
21854
21855         # get the percentage of 1-page I/O
21856         pct=$($LCTL get_param osc.${FSNAME}-OST0000-osc-ffff*.rpc_stats |
21857                 grep -A 1 'pages per rpc' | grep -v 'pages per rpc' |
21858                 awk '{print $7}')
21859         [ $pct -le 50 ] || error "$pct% of I/O are 1-page"
21860
21861         echo "mix rw ${size}M to OST0 by fio with $njobs jobs..."
21862         fio --name=rand-rw --rw=randrw --bs=$PAGE_SIZE --direct=1 \
21863                 --numjobs=$njobs --fallocate=none --ioengine=libaio \
21864                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
21865                 --filename=$DIR/$tfile
21866         [ $? -eq 0 ] || error "fio mixed read write error"
21867
21868         echo "AIO with large block size ${size}M"
21869         fio --name=rand-rw --rw=randrw --bs=${size}M --direct=1 \
21870                 --numjobs=1 --fallocate=none --ioengine=libaio \
21871                 --iodepth=16 --allow_file_create=0 --size=${size}M \
21872                 --filename=$DIR/$tfile
21873         [ $? -eq 0 ] || error "fio large block size failed"
21874
21875         rm -rf $DIR/$tfile
21876         $LCTL set_param debug="$saved_debug"
21877 }
21878 run_test 398c "run fio to test AIO"
21879
21880 test_398d() { #  LU-13846
21881         test -f aiocp || skip_env "no aiocp installed"
21882         local aio_file=$DIR/aio_file
21883
21884         $LFS setstripe -c -1 -S 1M $DIR/$tfile $aio_file
21885
21886         dd if=/dev/urandom of=$DIR/$tfile bs=1M count=64
21887         aiocp -a $PAGE_SIZE -b 64M -s 64M -f O_DIRECT $DIR/$tfile $aio_file
21888
21889         diff $DIR/$tfile $aio_file || "file diff after aiocp"
21890         rm -rf $DIR/$tfile $aio_file
21891 }
21892 run_test 398d "run aiocp to verify block size > stripe size"
21893
21894 test_fake_rw() {
21895         local read_write=$1
21896         if [ "$read_write" = "write" ]; then
21897                 local dd_cmd="dd if=/dev/zero of=$DIR/$tfile"
21898         elif [ "$read_write" = "read" ]; then
21899                 local dd_cmd="dd of=/dev/null if=$DIR/$tfile"
21900         else
21901                 error "argument error"
21902         fi
21903
21904         # turn off debug for performance testing
21905         local saved_debug=$($LCTL get_param -n debug)
21906         $LCTL set_param debug=0
21907
21908         $LFS setstripe -c 1 -i 0 $DIR/$tfile
21909
21910         # get ost1 size - $FSNAME-OST0000
21911         local ost1_avail_size=$($LFS df | awk /${ost1_svc}/'{ print $4 }')
21912         local blocks=$((ost1_avail_size/2/1024)) # half avail space by megabytes
21913         [ $blocks -gt 1000 ] && blocks=1000 # 1G in maximum
21914
21915         if [ "$read_write" = "read" ]; then
21916                 truncate -s $(expr 1048576 \* $blocks) $DIR/$tfile
21917         fi
21918
21919         local start_time=$(date +%s.%N)
21920         $dd_cmd bs=1M count=$blocks oflag=sync ||
21921                 error "real dd $read_write error"
21922         local duration=$(bc <<< "$(date +%s.%N) - $start_time")
21923
21924         if [ "$read_write" = "write" ]; then
21925                 rm -f $DIR/$tfile
21926         fi
21927
21928         # define OBD_FAIL_OST_FAKE_RW           0x238
21929         do_facet ost1 $LCTL set_param fail_loc=0x238
21930
21931         local start_time=$(date +%s.%N)
21932         $dd_cmd bs=1M count=$blocks oflag=sync ||
21933                 error "fake dd $read_write error"
21934         local duration_fake=$(bc <<< "$(date +%s.%N) - $start_time")
21935
21936         if [ "$read_write" = "write" ]; then
21937                 # verify file size
21938                 cancel_lru_locks osc
21939                 $CHECKSTAT -t file -s $((blocks * 1024 * 1024)) $DIR/$tfile ||
21940                         error "$tfile size not $blocks MB"
21941         fi
21942         do_facet ost1 $LCTL set_param fail_loc=0
21943
21944         echo "fake $read_write $duration_fake vs. normal $read_write" \
21945                 "$duration in seconds"
21946         [ $(bc <<< "$duration_fake < $duration") -eq 1 ] ||
21947                 error_not_in_vm "fake write is slower"
21948
21949         $LCTL set_param -n debug="$saved_debug"
21950         rm -f $DIR/$tfile
21951 }
21952 test_399a() { # LU-7655 for OST fake write
21953         remote_ost_nodsh && skip "remote OST with nodsh"
21954
21955         test_fake_rw write
21956 }
21957 run_test 399a "fake write should not be slower than normal write"
21958
21959 test_399b() { # LU-8726 for OST fake read
21960         remote_ost_nodsh && skip "remote OST with nodsh"
21961         if [ "$ost1_FSTYPE" != "ldiskfs" ]; then
21962                 skip_env "ldiskfs only test"
21963         fi
21964
21965         test_fake_rw read
21966 }
21967 run_test 399b "fake read should not be slower than normal read"
21968
21969 test_400a() { # LU-1606, was conf-sanity test_74
21970         if ! which $CC > /dev/null 2>&1; then
21971                 skip_env "$CC is not installed"
21972         fi
21973
21974         local extra_flags=''
21975         local out=$TMP/$tfile
21976         local prefix=/usr/include/lustre
21977         local prog
21978
21979         # Oleg removes c files in his test rig so test if any c files exist
21980         [ -z "$(ls -A $LUSTRE_TESTS_API_DIR)" ] && \
21981                 skip_env "Needed c test files are missing"
21982
21983         if ! [[ -d $prefix ]]; then
21984                 # Assume we're running in tree and fixup the include path.
21985                 extra_flags+=" -I$LUSTRE/../lnet/include/uapi -I$LUSTRE/include/uapi -I$LUSTRE/include"
21986                 extra_flags+=" -L$LUSTRE/utils/.lib"
21987         fi
21988
21989         for prog in $LUSTRE_TESTS_API_DIR/*.c; do
21990                 $CC -Wall -Werror -std=c99 $extra_flags -o $out $prog -llustreapi ||
21991                         error "client api broken"
21992         done
21993         rm -f $out
21994 }
21995 run_test 400a "Lustre client api program can compile and link"
21996
21997 test_400b() { # LU-1606, LU-5011
21998         local header
21999         local out=$TMP/$tfile
22000         local prefix=/usr/include/linux/lustre
22001
22002         # We use a hard coded prefix so that this test will not fail
22003         # when run in tree. There are headers in lustre/include/lustre/
22004         # that are not packaged (like lustre_idl.h) and have more
22005         # complicated include dependencies (like config.h and lnet/types.h).
22006         # Since this test about correct packaging we just skip them when
22007         # they don't exist (see below) rather than try to fixup cppflags.
22008
22009         if ! which $CC > /dev/null 2>&1; then
22010                 skip_env "$CC is not installed"
22011         fi
22012
22013         for header in $prefix/*.h; do
22014                 if ! [[ -f "$header" ]]; then
22015                         continue
22016                 fi
22017
22018                 if [[ "$(basename $header)" == lustre_ioctl.h ]]; then
22019                         continue # lustre_ioctl.h is internal header
22020                 fi
22021
22022                 $CC -Wall -Werror -std=c99 -include $header -c -x c /dev/null -o $out ||
22023                         error "cannot compile '$header'"
22024         done
22025         rm -f $out
22026 }
22027 run_test 400b "packaged headers can be compiled"
22028
22029 test_401a() { #LU-7437
22030         local printf_arg=$(find -printf 2>&1 | grep "unrecognized:")
22031         [ -n "$printf_arg" ] && skip_env "find does not support -printf"
22032
22033         #count the number of parameters by "list_param -R"
22034         local params=$($LCTL list_param -R '*' 2>/dev/null | wc -l)
22035         #count the number of parameters by listing proc files
22036         local proc_regexp="/{proc,sys}/{fs,sys,kernel/debug}/{lustre,lnet}/"
22037         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
22038         echo "proc_dirs='$proc_dirs'"
22039         [ -n "$proc_dirs" ] || error "no proc_dirs on $HOSTNAME"
22040         local procs=$(find -L $proc_dirs -mindepth 1 -printf '%P\n' 2>/dev/null|
22041                       sort -u | wc -l)
22042
22043         [ $params -eq $procs ] ||
22044                 error "found $params parameters vs. $procs proc files"
22045
22046         # test the list_param -D option only returns directories
22047         params=$($LCTL list_param -R -D '*' 2>/dev/null | wc -l)
22048         #count the number of parameters by listing proc directories
22049         procs=$(find -L $proc_dirs -mindepth 1 -type d -printf '%P\n' 2>/dev/null |
22050                 sort -u | wc -l)
22051
22052         [ $params -eq $procs ] ||
22053                 error "found $params parameters vs. $procs proc files"
22054 }
22055 run_test 401a "Verify if 'lctl list_param -R' can list parameters recursively"
22056
22057 test_401b() {
22058         local save=$($LCTL get_param -n jobid_var)
22059         local tmp=testing
22060
22061         $LCTL set_param foo=bar jobid_var=$tmp bar=baz &&
22062                 error "no error returned when setting bad parameters"
22063
22064         local jobid_new=$($LCTL get_param -n foe jobid_var baz)
22065         [[ "$jobid_new" == "$tmp" ]] || error "jobid tmp $jobid_new != $tmp"
22066
22067         $LCTL set_param -n fog=bam jobid_var=$save bat=fog
22068         local jobid_old=$($LCTL get_param -n foe jobid_var bag)
22069         [[ "$jobid_old" == "$save" ]] || error "jobid new $jobid_old != $save"
22070 }
22071 run_test 401b "Verify 'lctl {get,set}_param' continue after error"
22072
22073 test_401c() {
22074         local jobid_var_old=$($LCTL get_param -n jobid_var)
22075         local jobid_var_new
22076
22077         $LCTL set_param jobid_var= &&
22078                 error "no error returned for 'set_param a='"
22079
22080         jobid_var_new=$($LCTL get_param -n jobid_var)
22081         [[ "$jobid_var_old" == "$jobid_var_new" ]] ||
22082                 error "jobid_var was changed by setting without value"
22083
22084         $LCTL set_param jobid_var &&
22085                 error "no error returned for 'set_param a'"
22086
22087         jobid_var_new=$($LCTL get_param -n jobid_var)
22088         [[ "$jobid_var_old" == "$jobid_var_new" ]] ||
22089                 error "jobid_var was changed by setting without value"
22090 }
22091 run_test 401c "Verify 'lctl set_param' without value fails in either format."
22092
22093 test_401d() {
22094         local jobid_var_old=$($LCTL get_param -n jobid_var)
22095         local jobid_var_new
22096         local new_value="foo=bar"
22097
22098         $LCTL set_param jobid_var=$new_value ||
22099                 error "'set_param a=b' did not accept a value containing '='"
22100
22101         jobid_var_new=$($LCTL get_param -n jobid_var)
22102         [[ "$jobid_var_new" == "$new_value" ]] ||
22103                 error "'set_param a=b' failed on a value containing '='"
22104
22105         # Reset the jobid_var to test the other format
22106         $LCTL set_param jobid_var=$jobid_var_old
22107         jobid_var_new=$($LCTL get_param -n jobid_var)
22108         [[ "$jobid_var_new" == "$jobid_var_old" ]] ||
22109                 error "failed to reset jobid_var"
22110
22111         $LCTL set_param jobid_var $new_value ||
22112                 error "'set_param a b' did not accept a value containing '='"
22113
22114         jobid_var_new=$($LCTL get_param -n jobid_var)
22115         [[ "$jobid_var_new" == "$new_value" ]] ||
22116                 error "'set_param a b' failed on a value containing '='"
22117
22118         $LCTL set_param jobid_var $jobid_var_old
22119         jobid_var_new=$($LCTL get_param -n jobid_var)
22120         [[ "$jobid_var_new" == "$jobid_var_old" ]] ||
22121                 error "failed to reset jobid_var"
22122 }
22123 run_test 401d "Verify 'lctl set_param' accepts values containing '='"
22124
22125 test_402() {
22126         [[ $MDS1_VERSION -ge $(version_code 2.7.66) ]] ||
22127         [[ $MDS1_VERSION -ge $(version_code 2.7.18.4) &&
22128                 $MDS1_VERSION -lt $(version_code 2.7.50) ]] ||
22129         [[ $MDS1_VERSION -ge $(version_code 2.7.2) &&
22130                 $MDS1_VERSION -lt $(version_code 2.7.11) ]] ||
22131                 skip "Need MDS version 2.7.2+ or 2.7.18.4+ or 2.7.66+"
22132         remote_mds_nodsh && skip "remote MDS with nodsh"
22133
22134         $LFS setdirstripe -i 0 $DIR/$tdir || error "setdirstripe -i 0 failed"
22135 #define OBD_FAIL_MDS_FLD_LOOKUP 0x15c
22136         do_facet mds1 "lctl set_param fail_loc=0x8000015c"
22137         touch $DIR/$tdir/$tfile && error "touch should fail with ENOENT" ||
22138                 echo "Touch failed - OK"
22139 }
22140 run_test 402 "Return ENOENT to lod_generate_and_set_lovea"
22141
22142 test_403() {
22143         local file1=$DIR/$tfile.1
22144         local file2=$DIR/$tfile.2
22145         local tfile=$TMP/$tfile
22146
22147         rm -f $file1 $file2 $tfile
22148
22149         touch $file1
22150         ln $file1 $file2
22151
22152         # 30 sec OBD_TIMEOUT in ll_getattr()
22153         # right before populating st_nlink
22154         $LCTL set_param fail_loc=0x80001409
22155         stat -c %h $file1 > $tfile &
22156
22157         # create an alias, drop all locks and reclaim the dentry
22158         < $file2
22159         cancel_lru_locks mdc
22160         cancel_lru_locks osc
22161         sysctl -w vm.drop_caches=2
22162
22163         wait
22164
22165         [ $(cat $tfile) -gt 0 ] || error "wrong nlink count: $(cat $tfile)"
22166
22167         rm -f $tfile $file1 $file2
22168 }
22169 run_test 403 "i_nlink should not drop to zero due to aliasing"
22170
22171 test_404() { # LU-6601
22172         [[ $MDS1_VERSION -ge $(version_code 2.8.53) ]] ||
22173                 skip "Need server version newer than 2.8.52"
22174         remote_mds_nodsh && skip "remote MDS with nodsh"
22175
22176         local mosps=$(do_facet $SINGLEMDS $LCTL dl |
22177                 awk '/osp .*-osc-MDT/ { print $4}')
22178
22179         local osp
22180         for osp in $mosps; do
22181                 echo "Deactivate: " $osp
22182                 do_facet $SINGLEMDS $LCTL --device %$osp deactivate
22183                 local stat=$(do_facet $SINGLEMDS $LCTL dl |
22184                         awk -vp=$osp '$4 == p { print $2 }')
22185                 [ $stat = IN ] || {
22186                         do_facet $SINGLEMDS $LCTL dl | grep -w $osp
22187                         error "deactivate error"
22188                 }
22189                 echo "Activate: " $osp
22190                 do_facet $SINGLEMDS $LCTL --device %$osp activate
22191                 local stat=$(do_facet $SINGLEMDS $LCTL dl |
22192                         awk -vp=$osp '$4 == p { print $2 }')
22193                 [ $stat = UP ] || {
22194                         do_facet $SINGLEMDS $LCTL dl | grep -w $osp
22195                         error "activate error"
22196                 }
22197         done
22198 }
22199 run_test 404 "validate manual {de}activated works properly for OSPs"
22200
22201 test_405() {
22202         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
22203         [ $MDS1_VERSION -lt $(version_code 2.6.92) ] ||
22204                 [ $CLIENT_VERSION -lt $(version_code 2.6.99) ] &&
22205                         skip "Layout swap lock is not supported"
22206
22207         check_swap_layouts_support
22208         check_swap_layout_no_dom $DIR
22209
22210         test_mkdir $DIR/$tdir
22211         swap_lock_test -d $DIR/$tdir ||
22212                 error "One layout swap locked test failed"
22213 }
22214 run_test 405 "Various layout swap lock tests"
22215
22216 test_406() {
22217         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22218         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
22219         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
22220         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22221         [ $MDS1_VERSION -lt $(version_code 2.8.50) ] &&
22222                 skip "Need MDS version at least 2.8.50"
22223
22224         local def_stripe_size=$($LFS getstripe -S $MOUNT)
22225         local test_pool=$TESTNAME
22226
22227         pool_add $test_pool || error "pool_add failed"
22228         pool_add_targets $test_pool 0 $(($OSTCOUNT - 1)) 1 ||
22229                 error "pool_add_targets failed"
22230
22231         save_layout_restore_at_exit $MOUNT
22232
22233         # parent set default stripe count only, child will stripe from both
22234         # parent and fs default
22235         $LFS setstripe -c 1 -i 1 -S $((def_stripe_size * 2)) -p $test_pool $MOUNT ||
22236                 error "setstripe $MOUNT failed"
22237         $LFS mkdir -c $MDSCOUNT $DIR/$tdir || error "mkdir $tdir failed"
22238         $LFS setstripe -c $OSTCOUNT $DIR/$tdir || error "setstripe $tdir failed"
22239         for i in $(seq 10); do
22240                 local f=$DIR/$tdir/$tfile.$i
22241                 touch $f || error "touch failed"
22242                 local count=$($LFS getstripe -c $f)
22243                 [ $count -eq $OSTCOUNT ] ||
22244                         error "$f stripe count $count != $OSTCOUNT"
22245                 local offset=$($LFS getstripe -i $f)
22246                 [ $offset -eq 1 ] || error "$f stripe offset $offset != 1"
22247                 local size=$($LFS getstripe -S $f)
22248                 [ $size -eq $((def_stripe_size * 2)) ] ||
22249                         error "$f stripe size $size != $((def_stripe_size * 2))"
22250                 local pool=$($LFS getstripe -p $f)
22251                 [ $pool == $test_pool ] || error "$f pool $pool != $test_pool"
22252         done
22253
22254         # change fs default striping, delete parent default striping, now child
22255         # will stripe from new fs default striping only
22256         $LFS setstripe -c 1 -S $def_stripe_size -i 0 $MOUNT ||
22257                 error "change $MOUNT default stripe failed"
22258         $LFS setstripe -c 0 $DIR/$tdir ||
22259                 error "delete $tdir default stripe failed"
22260         for i in $(seq 11 20); do
22261                 local f=$DIR/$tdir/$tfile.$i
22262                 touch $f || error "touch $f failed"
22263                 local count=$($LFS getstripe -c $f)
22264                 [ $count -eq 1 ] || error "$f stripe count $count != 1"
22265                 local offset=$($LFS getstripe -i $f)
22266                 [ $offset -eq 0 ] || error "$f stripe offset $offset != 0"
22267                 local size=$($LFS getstripe -S $f)
22268                 [ $size -eq $def_stripe_size ] ||
22269                         error "$f stripe size $size != $def_stripe_size"
22270                 local pool=$($LFS getstripe -p $f)
22271                 [ $pool == $test_pool ] || error "$f pool $pool isn't set"
22272         done
22273
22274         unlinkmany $DIR/$tdir/$tfile. 1 20
22275
22276         local f=$DIR/$tdir/$tfile
22277         pool_remove_all_targets $test_pool $f
22278         pool_remove $test_pool $f
22279 }
22280 run_test 406 "DNE support fs default striping"
22281
22282 test_407() {
22283         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22284         [[ $MDS1_VERSION -lt $(version_code 2.8.55) ]] &&
22285                 skip "Need MDS version at least 2.8.55"
22286         remote_mds_nodsh && skip "remote MDS with nodsh"
22287
22288         $LFS mkdir -i 0 -c 1 $DIR/$tdir.0 ||
22289                 error "$LFS mkdir -i 0 -c 1 $tdir.0 failed"
22290         $LFS mkdir -i 1 -c 1 $DIR/$tdir.1 ||
22291                 error "$LFS mkdir -i 1 -c 1 $tdir.1 failed"
22292         touch $DIR/$tdir.0/$tfile.0 || error "touch $tdir.0/$tfile.0 failed"
22293
22294         #define OBD_FAIL_DT_TXN_STOP    0x2019
22295         for idx in $(seq $MDSCOUNT); do
22296                 do_facet mds$idx "lctl set_param fail_loc=0x2019"
22297         done
22298         $LFS mkdir -c 2 $DIR/$tdir && error "$LFS mkdir -c 2 $tdir should fail"
22299         mv $DIR/$tdir.0/$tfile.0 $DIR/$tdir.1/$tfile.1 &&
22300                 error "mv $tdir.0/$tfile.0 $tdir.1/$tfile.1 should fail"
22301         true
22302 }
22303 run_test 407 "transaction fail should cause operation fail"
22304
22305 test_408() {
22306         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1 oflag=direct
22307
22308         #define OBD_FAIL_OSC_BRW_PREP_REQ2        0x40a
22309         lctl set_param fail_loc=0x8000040a
22310         # let ll_prepare_partial_page() fail
22311         dd if=/dev/zero of=$DIR/$tfile bs=2048 count=1 conv=notrunc || true
22312
22313         rm -f $DIR/$tfile
22314
22315         # create at least 100 unused inodes so that
22316         # shrink_icache_memory(0) should not return 0
22317         touch $DIR/$tfile-{0..100}
22318         rm -f $DIR/$tfile-{0..100}
22319         sync
22320
22321         echo 2 > /proc/sys/vm/drop_caches
22322 }
22323 run_test 408 "drop_caches should not hang due to page leaks"
22324
22325 test_409()
22326 {
22327         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
22328
22329         mkdir -p $DIR/$tdir || error "(0) Fail to mkdir"
22330         $LFS mkdir -i 1 -c 2 $DIR/$tdir/foo || error "(1) Fail to mkdir"
22331         touch $DIR/$tdir/guard || error "(2) Fail to create"
22332
22333         local PREFIX=$(str_repeat 'A' 128)
22334         echo "Create 1K hard links start at $(date)"
22335         createmany -l $DIR/$tdir/guard $DIR/$tdir/foo/${PREFIX}_ 1000 ||
22336                 error "(3) Fail to hard link"
22337
22338         echo "Links count should be right although linkEA overflow"
22339         stat $DIR/$tdir/guard || error "(4) Fail to stat"
22340         local linkcount=$(stat --format=%h $DIR/$tdir/guard)
22341         [ $linkcount -eq 1001 ] ||
22342                 error "(5) Unexpected hard links count: $linkcount"
22343
22344         echo "List all links start at $(date)"
22345         ls -l $DIR/$tdir/foo > /dev/null ||
22346                 error "(6) Fail to list $DIR/$tdir/foo"
22347
22348         echo "Unlink hard links start at $(date)"
22349         unlinkmany $DIR/$tdir/foo/${PREFIX}_ 1000 ||
22350                 error "(7) Fail to unlink"
22351         echo "Unlink hard links finished at $(date)"
22352 }
22353 run_test 409 "Large amount of cross-MDTs hard links on the same file"
22354
22355 test_410()
22356 {
22357         [[ $CLIENT_VERSION -lt $(version_code 2.9.59) ]] &&
22358                 skip "Need client version at least 2.9.59"
22359
22360         # Create a file, and stat it from the kernel
22361         local testfile=$DIR/$tfile
22362         touch $testfile
22363
22364         local run_id=$RANDOM
22365         local my_ino=$(stat --format "%i" $testfile)
22366
22367         # Try to insert the module. This will always fail as the
22368         # module is designed to not be inserted.
22369         insmod $LUSTRE/tests/kernel/kinode.ko run_id=$run_id fname=$testfile \
22370             &> /dev/null
22371
22372         # Anything but success is a test failure
22373         dmesg | grep -q \
22374             "lustre_kinode_$run_id: inode numbers are identical: $my_ino" ||
22375             error "no inode match"
22376 }
22377 run_test 410 "Test inode number returned from kernel thread"
22378
22379 cleanup_test411_cgroup() {
22380         trap 0
22381         rmdir "$1"
22382 }
22383
22384 test_411() {
22385         local cg_basedir=/sys/fs/cgroup/memory
22386         # LU-9966
22387         test -f "$cg_basedir/memory.kmem.limit_in_bytes" ||
22388                 skip "no setup for cgroup"
22389
22390         dd if=/dev/zero of=$DIR/$tfile bs=1M count=100 conv=fsync ||
22391                 error "test file creation failed"
22392         cancel_lru_locks osc
22393
22394         # Create a very small memory cgroup to force a slab allocation error
22395         local cgdir=$cg_basedir/osc_slab_alloc
22396         mkdir $cgdir || error "cgroup mkdir '$cgdir' failed"
22397         trap "cleanup_test411_cgroup $cgdir" EXIT
22398         echo 2M > $cgdir/memory.kmem.limit_in_bytes
22399         echo 1M > $cgdir/memory.limit_in_bytes
22400
22401         # Should not LBUG, just be killed by oom-killer
22402         # dd will return 0 even allocation failure in some environment.
22403         # So don't check return value
22404         sh -c "echo \$$ > $cgdir/tasks && dd if=$DIR/$tfile of=/dev/null"
22405         cleanup_test411_cgroup $cgdir
22406
22407         return 0
22408 }
22409 run_test 411 "Slab allocation error with cgroup does not LBUG"
22410
22411 test_412() {
22412         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22413         if [ $MDS1_VERSION -lt $(version_code 2.10.55) ]; then
22414                 skip "Need server version at least 2.10.55"
22415         fi
22416
22417         $LFS mkdir -i $((MDSCOUNT - 1)),$((MDSCOUNT - 2)) $DIR/$tdir ||
22418                 error "mkdir failed"
22419         $LFS getdirstripe $DIR/$tdir
22420         local stripe_index=$($LFS getdirstripe -i $DIR/$tdir)
22421         [ $stripe_index -eq $((MDSCOUNT - 1)) ] ||
22422                 error "expect $((MDSCOUT - 1)) get $stripe_index"
22423         local stripe_count=$($LFS getdirstripe -T $DIR/$tdir)
22424         [ $stripe_count -eq 2 ] ||
22425                 error "expect 2 get $stripe_count"
22426 }
22427 run_test 412 "mkdir on specific MDTs"
22428
22429 test_qos_mkdir() {
22430         local mkdir_cmd=$1
22431         local stripe_count=$2
22432         local mdts=$(comma_list $(mdts_nodes))
22433
22434         local testdir
22435         local lmv_qos_prio_free
22436         local lmv_qos_threshold_rr
22437         local lmv_qos_maxage
22438         local lod_qos_prio_free
22439         local lod_qos_threshold_rr
22440         local lod_qos_maxage
22441         local count
22442         local i
22443
22444         lmv_qos_prio_free=$($LCTL get_param -n lmv.*.qos_prio_free | head -n1)
22445         lmv_qos_prio_free=${lmv_qos_prio_free%%%}
22446         lmv_qos_threshold_rr=$($LCTL get_param -n lmv.*.qos_threshold_rr |
22447                 head -n1)
22448         lmv_qos_threshold_rr=${lmv_qos_threshold_rr%%%}
22449         lmv_qos_maxage=$($LCTL get_param -n lmv.*.qos_maxage)
22450         stack_trap "$LCTL set_param \
22451                 lmv.*.qos_prio_free=$lmv_qos_prio_free > /dev/null" EXIT
22452         stack_trap "$LCTL set_param \
22453                 lmv.*.qos_threshold_rr=$lmv_qos_threshold_rr > /dev/null" EXIT
22454         stack_trap "$LCTL set_param \
22455                 lmv.*.qos_maxage=$lmv_qos_maxage > /dev/null" EXIT
22456
22457         lod_qos_prio_free=$(do_facet mds1 $LCTL get_param -n \
22458                 lod.$FSNAME-MDT0000-mdtlov.mdt_qos_prio_free | head -n1)
22459         lod_qos_prio_free=${lod_qos_prio_free%%%}
22460         lod_qos_threshold_rr=$(do_facet mds1 $LCTL get_param -n \
22461                 lod.$FSNAME-MDT0000-mdtlov.mdt_qos_threshold_rr | head -n1)
22462         lod_qos_threshold_rr=${lod_qos_threshold_rr%%%}
22463         lod_qos_maxage=$(do_facet mds1 $LCTL get_param -n \
22464                 lod.$FSNAME-MDT0000-mdtlov.qos_maxage | awk '{ print $1 }')
22465         stack_trap "do_nodes $mdts $LCTL set_param \
22466                 lod.*.mdt_qos_prio_free=$lod_qos_prio_free > /dev/null" EXIT
22467         stack_trap "do_nodes $mdts $LCTL set_param \
22468                 lod.*.mdt_qos_threshold_rr=$lod_qos_threshold_rr > /dev/null" \
22469                 EXIT
22470         stack_trap "do_nodes $mdts $LCTL set_param \
22471                 lod.*.mdt_qos_maxage=$lod_qos_maxage > /dev/null" EXIT
22472
22473         echo
22474         echo "Mkdir (stripe_count $stripe_count) roundrobin:"
22475
22476         $LCTL set_param lmv.*.qos_threshold_rr=100 > /dev/null
22477         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_threshold_rr=100 > /dev/null
22478
22479         testdir=$DIR/$tdir-s$stripe_count/rr
22480
22481         for i in $(seq $((100 * MDSCOUNT))); do
22482                 eval $mkdir_cmd $testdir/subdir$i ||
22483                         error "$mkdir_cmd subdir$i failed"
22484         done
22485
22486         for i in $(seq $MDSCOUNT); do
22487                 count=$($LFS getdirstripe -i $testdir/* |
22488                                 grep ^$((i - 1))$ | wc -l)
22489                 echo "$count directories created on MDT$((i - 1))"
22490                 [ $count -eq 100 ] || error "subdirs are not evenly distributed"
22491
22492                 if [ $stripe_count -gt 1 ]; then
22493                         count=$($LFS getdirstripe $testdir/* |
22494                                 grep -P "^\s+$((i - 1))\t" | wc -l)
22495                         echo "$count stripes created on MDT$((i - 1))"
22496                         # deviation should < 5% of average
22497                         [ $count -lt $((95 * stripe_count)) ] ||
22498                         [ $count -gt $((105 * stripe_count)) ] &&
22499                                 error "stripes are not evenly distributed"
22500                 fi
22501         done
22502
22503         $LCTL set_param lmv.*.qos_threshold_rr=$lmv_qos_threshold_rr > /dev/null
22504         do_nodes $mdts $LCTL set_param \
22505                 lod.*.mdt_qos_threshold_rr=$lod_qos_threshold_rr > /dev/null
22506
22507         echo
22508         echo "Check for uneven MDTs: "
22509
22510         local ffree
22511         local bavail
22512         local max
22513         local min
22514         local max_index
22515         local min_index
22516         local tmp
22517
22518         ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.filesfree))
22519         bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.kbytesavail))
22520         bsize=$(lctl get_param -n mdc.*MDT0000*.blocksize)
22521
22522         max=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
22523         min=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
22524         max_index=0
22525         min_index=0
22526         for ((i = 1; i < ${#ffree[@]}; i++)); do
22527                 tmp=$(((${ffree[i]} >> 8) * (${bavail[i]} * bsize >> 16)))
22528                 if [ $tmp -gt $max ]; then
22529                         max=$tmp
22530                         max_index=$i
22531                 fi
22532                 if [ $tmp -lt $min ]; then
22533                         min=$tmp
22534                         min_index=$i
22535                 fi
22536         done
22537
22538         [ ${ffree[min_index]} -eq 0 ] &&
22539                 skip "no free files in MDT$min_index"
22540         [ ${ffree[min_index]} -gt 100000000 ] &&
22541                 skip "too much free files in MDT$min_index"
22542
22543         # Check if we need to generate uneven MDTs
22544         local threshold=50
22545         local diff=$(((max - min) * 100 / min))
22546         local value="$(generate_string 1024)"
22547
22548         while [ $diff -lt $threshold ]; do
22549                 # generate uneven MDTs, create till $threshold% diff
22550                 echo -n "weight diff=$diff% must be > $threshold% ..."
22551                 count=$((${ffree[min_index]} / 10))
22552                 # 50 sec per 10000 files in vm
22553                 [ $count -gt 40000 ] && [ "$SLOW" = "no" ] &&
22554                         skip "$count files to create"
22555                 echo "Fill MDT$min_index with $count files"
22556                 [ -d $DIR/$tdir-MDT$min_index ] ||
22557                         $LFS mkdir -i $min_index $DIR/$tdir-MDT$min_index ||
22558                         error "mkdir $tdir-MDT$min_index failed"
22559                 for i in $(seq $count); do
22560                         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE \
22561                                 $DIR/$tdir-MDT$min_index/f$j_$i > /dev/null ||
22562                                 error "create f$j_$i failed"
22563                         setfattr -n user.413b -v $value \
22564                                 $DIR/$tdir-MDT$min_index/f$j_$i ||
22565                                 error "setfattr f$j_$i failed"
22566                 done
22567
22568                 ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-*.filesfree))
22569                 bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-*.kbytesavail))
22570                 max=$(((${ffree[max_index]} >> 8) * \
22571                         (${bavail[max_index]} * bsize >> 16)))
22572                 min=$(((${ffree[min_index]} >> 8) * \
22573                         (${bavail[min_index]} * bsize >> 16)))
22574                 diff=$(((max - min) * 100 / min))
22575         done
22576
22577         echo "MDT filesfree available: ${ffree[@]}"
22578         echo "MDT blocks available: ${bavail[@]}"
22579         echo "weight diff=$diff%"
22580
22581         echo
22582         echo "Mkdir (stripe_count $stripe_count) with balanced space usage:"
22583
22584         $LCTL set_param lmv.*.qos_prio_free=100 > /dev/null
22585         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_prio_free=100 > /dev/null
22586         # decrease statfs age, so that it can be updated in time
22587         $LCTL set_param lmv.*.qos_maxage=1 > /dev/null
22588         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_maxage=1 > /dev/null
22589
22590         sleep 1
22591
22592         testdir=$DIR/$tdir-s$stripe_count/qos
22593
22594         for i in $(seq $((100 * MDSCOUNT))); do
22595                 eval $mkdir_cmd $testdir/subdir$i ||
22596                         error "$mkdir_cmd subdir$i failed"
22597         done
22598
22599         for i in $(seq $MDSCOUNT); do
22600                 count=$($LFS getdirstripe -i $testdir/* | grep ^$((i - 1))$ |
22601                         wc -l)
22602                 echo "$count directories created on MDT$((i - 1))"
22603
22604                 if [ $stripe_count -gt 1 ]; then
22605                         count=$($LFS getdirstripe $testdir/* |
22606                                 grep -P "^\s+$((i - 1))\t" | wc -l)
22607                         echo "$count stripes created on MDT$((i - 1))"
22608                 fi
22609         done
22610
22611         max=$($LFS getdirstripe -i $testdir/* | grep ^$max_index$ | wc -l)
22612         min=$($LFS getdirstripe -i $testdir/* | grep ^$min_index$ | wc -l)
22613
22614         # D-value should > 10% of averge
22615         [ $((max - min)) -lt 10 ] &&
22616                 error "subdirs shouldn't be evenly distributed"
22617
22618         # ditto
22619         if [ $stripe_count -gt 1 ]; then
22620                 max=$($LFS getdirstripe $testdir/* |
22621                         grep -P "^\s+$max_index\t" | wc -l)
22622                 min=$($LFS getdirstripe $testdir/* |
22623                         grep -P "^\s+$min_index\t" | wc -l)
22624                 [ $((max - min)) -le $((10 * stripe_count)) ] &&
22625                         error "stripes shouldn't be evenly distributed"|| true
22626         fi
22627 }
22628
22629 test_413a() {
22630         [ $MDSCOUNT -lt 2 ] &&
22631                 skip "We need at least 2 MDTs for this test"
22632
22633         [ $MDS1_VERSION -lt $(version_code 2.12.52) ] &&
22634                 skip "Need server version at least 2.12.52"
22635
22636         local stripe_count
22637
22638         for stripe_count in $(seq 1 $((MDSCOUNT - 1))); do
22639                 mkdir $DIR/$tdir-s$stripe_count || error "mkdir failed"
22640                 mkdir $DIR/$tdir-s$stripe_count/rr || error "mkdir failed"
22641                 mkdir $DIR/$tdir-s$stripe_count/qos || error "mkdir failed"
22642                 test_qos_mkdir "$LFS mkdir -c $stripe_count" $stripe_count
22643         done
22644 }
22645 run_test 413a "QoS mkdir with 'lfs mkdir -i -1'"
22646
22647 test_413b() {
22648         [ $MDSCOUNT -lt 2 ] &&
22649                 skip "We need at least 2 MDTs for this test"
22650
22651         [ $MDS1_VERSION -lt $(version_code 2.12.52) ] &&
22652                 skip "Need server version at least 2.12.52"
22653
22654         local stripe_count
22655
22656         for stripe_count in $(seq 1 $((MDSCOUNT - 1))); do
22657                 mkdir $DIR/$tdir-s$stripe_count || error "mkdir failed"
22658                 mkdir $DIR/$tdir-s$stripe_count/rr || error "mkdir failed"
22659                 mkdir $DIR/$tdir-s$stripe_count/qos || error "mkdir failed"
22660                 $LFS setdirstripe -D -c $stripe_count \
22661                         $DIR/$tdir-s$stripe_count/rr ||
22662                         error "setdirstripe failed"
22663                 $LFS setdirstripe -D -c $stripe_count \
22664                         $DIR/$tdir-s$stripe_count/qos ||
22665                         error "setdirstripe failed"
22666                 test_qos_mkdir "mkdir" $stripe_count
22667         done
22668 }
22669 run_test 413b "QoS mkdir under dir whose default LMV starting MDT offset is -1"
22670
22671 test_414() {
22672 #define OBD_FAIL_PTLRPC_BULK_ATTACH      0x521
22673         $LCTL set_param fail_loc=0x80000521
22674         dd if=/dev/zero of=$DIR/$tfile bs=2M count=1 oflag=sync
22675         rm -f $DIR/$tfile
22676 }
22677 run_test 414 "simulate ENOMEM in ptlrpc_register_bulk()"
22678
22679 test_415() {
22680         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22681         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
22682                 skip "Need server version at least 2.11.52"
22683
22684         # LU-11102
22685         local total
22686         local setattr_pid
22687         local start_time
22688         local end_time
22689         local duration
22690
22691         total=500
22692         # this test may be slow on ZFS
22693         [ "$mds1_FSTYPE" == "zfs" ] && total=100
22694
22695         # though this test is designed for striped directory, let's test normal
22696         # directory too since lock is always saved as CoS lock.
22697         test_mkdir $DIR/$tdir || error "mkdir $tdir"
22698         createmany -o $DIR/$tdir/$tfile. $total || error "createmany"
22699
22700         (
22701                 while true; do
22702                         touch $DIR/$tdir
22703                 done
22704         ) &
22705         setattr_pid=$!
22706
22707         start_time=$(date +%s)
22708         for i in $(seq $total); do
22709                 mrename $DIR/$tdir/$tfile.$i $DIR/$tdir/$tfile-new.$i \
22710                         > /dev/null
22711         done
22712         end_time=$(date +%s)
22713         duration=$((end_time - start_time))
22714
22715         kill -9 $setattr_pid
22716
22717         echo "rename $total files took $duration sec"
22718         [ $duration -lt 100 ] || error "rename took $duration sec"
22719 }
22720 run_test 415 "lock revoke is not missing"
22721
22722 test_416() {
22723         [ $MDS1_VERSION -lt $(version_code 2.11.55) ] &&
22724                 skip "Need server version at least 2.11.55"
22725
22726         # define OBD_FAIL_OSD_TXN_START    0x19a
22727         do_facet mds1 lctl set_param fail_loc=0x19a
22728
22729         lfs mkdir -c $MDSCOUNT $DIR/$tdir
22730
22731         true
22732 }
22733 run_test 416 "transaction start failure won't cause system hung"
22734
22735 cleanup_417() {
22736         trap 0
22737         do_nodes $(comma_list $(mdts_nodes)) \
22738                 "$LCTL set_param -n mdt.*MDT*.enable_dir_migration=1"
22739         do_nodes $(comma_list $(mdts_nodes)) \
22740                 "$LCTL set_param -n mdt.*MDT*.enable_remote_dir=1"
22741         do_nodes $(comma_list $(mdts_nodes)) \
22742                 "$LCTL set_param -n mdt.*MDT*.enable_striped_dir=1"
22743 }
22744
22745 test_417() {
22746         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
22747         [[ $MDS1_VERSION -lt $(version_code 2.11.56) ]] &&
22748                 skip "Need MDS version at least 2.11.56"
22749
22750         trap cleanup_417 RETURN EXIT
22751
22752         $LFS mkdir -i 1 $DIR/$tdir.1 || error "create remote dir $tdir.1 failed"
22753         do_nodes $(comma_list $(mdts_nodes)) \
22754                 "$LCTL set_param -n mdt.*MDT*.enable_dir_migration=0"
22755         $LFS migrate -m 0 $DIR/$tdir.1 &&
22756                 error "migrate dir $tdir.1 should fail"
22757
22758         do_nodes $(comma_list $(mdts_nodes)) \
22759                 "$LCTL set_param -n mdt.*MDT*.enable_remote_dir=0"
22760         $LFS mkdir -i 1 $DIR/$tdir.2 &&
22761                 error "create remote dir $tdir.2 should fail"
22762
22763         do_nodes $(comma_list $(mdts_nodes)) \
22764                 "$LCTL set_param -n mdt.*MDT*.enable_striped_dir=0"
22765         $LFS mkdir -c 2 $DIR/$tdir.3 &&
22766                 error "create striped dir $tdir.3 should fail"
22767         true
22768 }
22769 run_test 417 "disable remote dir, striped dir and dir migration"
22770
22771 # Checks that the outputs of df [-i] and lfs df [-i] match
22772 #
22773 # usage: check_lfs_df <blocks | inodes> <mountpoint>
22774 check_lfs_df() {
22775         local dir=$2
22776         local inodes
22777         local df_out
22778         local lfs_df_out
22779         local count
22780         local passed=false
22781
22782         # blocks or inodes
22783         [ "$1" == "blocks" ] && inodes= || inodes="-i"
22784
22785         for count in {1..100}; do
22786                 cancel_lru_locks
22787                 sync; sleep 0.2
22788
22789                 # read the lines of interest
22790                 df_out=($(df -P $inodes $dir | tail -n +2)) ||
22791                         error "df $inodes $dir | tail -n +2 failed"
22792                 lfs_df_out=($($LFS df $inodes $dir | grep summary:)) ||
22793                         error "lfs df $inodes $dir | grep summary: failed"
22794
22795                 # skip first substrings of each output as they are different
22796                 # "<NID>:/<fsname>" for df, "filesystem_summary:" for lfs df
22797                 # compare the two outputs
22798                 passed=true
22799                 for i in {1..5}; do
22800                         [ "${df_out[i]}" != "${lfs_df_out[i]}" ] && passed=false
22801                 done
22802                 $passed && break
22803         done
22804
22805         if ! $passed; then
22806                 df -P $inodes $dir
22807                 echo
22808                 lfs df $inodes $dir
22809                 error "df and lfs df $1 output mismatch: "      \
22810                       "df ${inodes}: ${df_out[*]}, "            \
22811                       "lfs df ${inodes}: ${lfs_df_out[*]}"
22812         fi
22813 }
22814
22815 test_418() {
22816         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22817
22818         local dir=$DIR/$tdir
22819         local numfiles=$((RANDOM % 4096 + 2))
22820         local numblocks=$((RANDOM % 256 + 1))
22821
22822         wait_delete_completed
22823         test_mkdir $dir
22824
22825         # check block output
22826         check_lfs_df blocks $dir
22827         # check inode output
22828         check_lfs_df inodes $dir
22829
22830         # create a single file and retest
22831         echo "Creating a single file and testing"
22832         createmany -o $dir/$tfile- 1 &>/dev/null ||
22833                 error "creating 1 file in $dir failed"
22834         check_lfs_df blocks $dir
22835         check_lfs_df inodes $dir
22836
22837         # create a random number of files
22838         echo "Creating $((numfiles - 1)) files and testing"
22839         createmany -o $dir/$tfile- 1 $((numfiles - 1)) &>/dev/null ||
22840                 error "creating $((numfiles - 1)) files in $dir failed"
22841
22842         # write a random number of blocks to the first test file
22843         echo "Writing $numblocks 4K blocks and testing"
22844         dd if=/dev/urandom of=$dir/${tfile}-0 bs=4K conv=fsync \
22845                 count=$numblocks &>/dev/null ||
22846                 error "dd to $dir/${tfile}-0 failed"
22847
22848         # retest
22849         check_lfs_df blocks $dir
22850         check_lfs_df inodes $dir
22851
22852         unlinkmany $dir/$tfile- $numfiles &>/dev/null ||
22853                 error "unlinking $numfiles files in $dir failed"
22854 }
22855 run_test 418 "df and lfs df outputs match"
22856
22857 test_419()
22858 {
22859         local dir=$DIR/$tdir
22860
22861         mkdir -p $dir
22862         touch $dir/file
22863
22864         cancel_lru_locks mdc
22865
22866         #OBD_FAIL_LLITE_OPEN_BY_NAME    0x1410
22867         $LCTL set_param fail_loc=0x1410
22868         cat $dir/file
22869         $LCTL set_param fail_loc=0
22870         rm -rf $dir
22871 }
22872 run_test 419 "Verify open file by name doesn't crash kernel"
22873
22874 test_420()
22875 {
22876         [[ $MDS1_VERSION -ge $(version_code 2.12.53) ]] ||
22877                 skip "Need MDS version at least 2.12.53"
22878
22879         local SAVE_UMASK=$(umask)
22880         local dir=$DIR/$tdir
22881         local uname=$(getent passwd $RUNAS_ID | cut -d: -f1)
22882
22883         mkdir -p $dir
22884         umask 0000
22885         mkdir -m03777 $dir/testdir
22886         ls -dn $dir/testdir
22887         # Need to remove trailing '.' when SELinux is enabled
22888         local dirperms=$(ls -dn $dir/testdir |
22889                          awk '{ sub(/\.$/, "", $1); print $1}')
22890         [ $dirperms == "drwxrwsrwt" ] ||
22891                 error "incorrect perms on $dir/testdir"
22892
22893         su - $uname -c "PATH=$LUSTRE/tests:\$PATH; \
22894                 openfile -f O_RDONLY:O_CREAT -m 02755 $dir/testdir/testfile"
22895         ls -n $dir/testdir/testfile
22896         local fileperms=$(ls -n $dir/testdir/testfile |
22897                           awk '{ sub(/\.$/, "", $1); print $1}')
22898         [ $fileperms == "-rwxr-xr-x" ] ||
22899                 error "incorrect perms on $dir/testdir/testfile"
22900
22901         umask $SAVE_UMASK
22902 }
22903 run_test 420 "clear SGID bit on non-directories for non-members"
22904
22905 test_421a() {
22906         local cnt
22907         local fid1
22908         local fid2
22909
22910         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
22911                 skip "Need MDS version at least 2.12.54"
22912
22913         test_mkdir $DIR/$tdir
22914         createmany -o $DIR/$tdir/f 3
22915         cnt=$(ls -1 $DIR/$tdir | wc -l)
22916         [ $cnt != 3 ] && error "unexpected #files: $cnt"
22917
22918         fid1=$(lfs path2fid $DIR/$tdir/f1)
22919         fid2=$(lfs path2fid $DIR/$tdir/f2)
22920         $LFS rmfid $DIR $fid1 $fid2 || error "rmfid failed"
22921
22922         stat $DIR/$tdir/f1 && error "f1 still visible on the client"
22923         stat $DIR/$tdir/f2 && error "f2 still visible on the client"
22924
22925         cnt=$(ls -1 $DIR/$tdir | wc -l)
22926         [ $cnt == 1 ] || error "unexpected #files after: $cnt"
22927
22928         rm -f $DIR/$tdir/f3 || error "can't remove f3"
22929         createmany -o $DIR/$tdir/f 3
22930         cnt=$(ls -1 $DIR/$tdir | wc -l)
22931         [ $cnt != 3 ] && error "unexpected #files: $cnt"
22932
22933         fid1=$(lfs path2fid $DIR/$tdir/f1)
22934         fid2=$(lfs path2fid $DIR/$tdir/f2)
22935         echo "remove using fsname $FSNAME"
22936         $LFS rmfid $FSNAME $fid1 $fid2 || error "rmfid with fsname failed"
22937
22938         cnt=$(ls -1 $DIR/$tdir | wc -l)
22939         [ $cnt == 1 ] || error "unexpected #files after: $cnt"
22940 }
22941 run_test 421a "simple rm by fid"
22942
22943 test_421b() {
22944         local cnt
22945         local FID1
22946         local FID2
22947
22948         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
22949                 skip "Need MDS version at least 2.12.54"
22950
22951         test_mkdir $DIR/$tdir
22952         createmany -o $DIR/$tdir/f 3
22953         multiop_bg_pause $DIR/$tdir/f1 o_c || error "multiop failed to start"
22954         MULTIPID=$!
22955
22956         FID1=$(lfs path2fid $DIR/$tdir/f1)
22957         FID2=$(lfs path2fid $DIR/$tdir/f2)
22958         $LFS rmfid $DIR $FID1 $FID2 && error "rmfid didn't fail"
22959
22960         kill -USR1 $MULTIPID
22961         wait
22962
22963         cnt=$(ls $DIR/$tdir | wc -l)
22964         [ $cnt == 2 ] || error "unexpected #files after: $cnt"
22965 }
22966 run_test 421b "rm by fid on open file"
22967
22968 test_421c() {
22969         local cnt
22970         local FIDS
22971
22972         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
22973                 skip "Need MDS version at least 2.12.54"
22974
22975         test_mkdir $DIR/$tdir
22976         createmany -o $DIR/$tdir/f 3
22977         touch $DIR/$tdir/$tfile
22978         createmany -l$DIR/$tdir/$tfile $DIR/$tdir/h 180
22979         cnt=$(ls -1 $DIR/$tdir | wc -l)
22980         [ $cnt != 184 ] && error "unexpected #files: $cnt"
22981
22982         FID1=$(lfs path2fid $DIR/$tdir/$tfile)
22983         $LFS rmfid $DIR $FID1 || error "rmfid failed"
22984
22985         cnt=$(ls $DIR/$tdir | wc -l)
22986         [ $cnt == 3 ] || error "unexpected #files after: $cnt"
22987 }
22988 run_test 421c "rm by fid against hardlinked files"
22989
22990 test_421d() {
22991         local cnt
22992         local FIDS
22993
22994         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
22995                 skip "Need MDS version at least 2.12.54"
22996
22997         test_mkdir $DIR/$tdir
22998         createmany -o $DIR/$tdir/f 4097
22999         cnt=$(ls -1 $DIR/$tdir | wc -l)
23000         [ $cnt != 4097 ] && error "unexpected #files: $cnt"
23001
23002         FIDS=$(lfs path2fid $DIR/$tdir/f* | sed "s/[/][^:]*://g")
23003         $LFS rmfid $DIR $FIDS || error "rmfid failed"
23004
23005         cnt=$(ls $DIR/$tdir | wc -l)
23006         rm -rf $DIR/$tdir
23007         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
23008 }
23009 run_test 421d "rmfid en masse"
23010
23011 test_421e() {
23012         local cnt
23013         local FID
23014
23015         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
23016         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
23017                 skip "Need MDS version at least 2.12.54"
23018
23019         mkdir -p $DIR/$tdir
23020         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
23021         createmany -o $DIR/$tdir/striped_dir/f 512
23022         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
23023         [ $cnt != 512 ] && error "unexpected #files: $cnt"
23024
23025         FIDS=$(lfs path2fid $DIR/$tdir/striped_dir/f* |
23026                 sed "s/[/][^:]*://g")
23027         $LFS rmfid $DIR $FIDS || error "rmfid failed"
23028
23029         cnt=$(ls $DIR/$tdir/striped_dir | wc -l)
23030         rm -rf $DIR/$tdir
23031         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
23032 }
23033 run_test 421e "rmfid in DNE"
23034
23035 test_421f() {
23036         local cnt
23037         local FID
23038
23039         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
23040                 skip "Need MDS version at least 2.12.54"
23041
23042         test_mkdir $DIR/$tdir
23043         touch $DIR/$tdir/f
23044         cnt=$(ls -1 $DIR/$tdir | wc -l)
23045         [ $cnt != 1 ] && error "unexpected #files: $cnt"
23046
23047         FID=$(lfs path2fid $DIR/$tdir/f)
23048         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail (1)"
23049         # rmfid should fail
23050         cnt=$(ls -1 $DIR/$tdir | wc -l)
23051         [ $cnt != 1 ] && error "unexpected #files after (2): $cnt"
23052
23053         chmod a+rw $DIR/$tdir
23054         ls -la $DIR/$tdir
23055         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail (2)"
23056         # rmfid should fail
23057         cnt=$(ls -1 $DIR/$tdir | wc -l)
23058         [ $cnt != 1 ] && error "unexpected #files after (3): $cnt"
23059
23060         rm -f $DIR/$tdir/f
23061         $RUNAS touch $DIR/$tdir/f
23062         FID=$(lfs path2fid $DIR/$tdir/f)
23063         echo "rmfid as root"
23064         $LFS rmfid $DIR $FID || error "rmfid as root failed"
23065         cnt=$(ls -1 $DIR/$tdir | wc -l)
23066         [ $cnt == 0 ] || error "unexpected #files after (4): $cnt"
23067
23068         rm -f $DIR/$tdir/f
23069         $RUNAS touch $DIR/$tdir/f
23070         cnt=$(ls -1 $DIR/$tdir | wc -l)
23071         [ $cnt != 1 ] && error "unexpected #files (4): $cnt"
23072         FID=$(lfs path2fid $DIR/$tdir/f)
23073         # rmfid w/o user_fid2path mount option should fail
23074         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail(3)"
23075         cnt=$(ls -1 $DIR/$tdir | wc -l)
23076         [ $cnt == 1 ] || error "unexpected #files after (5): $cnt"
23077
23078         umount_client $MOUNT || error "failed to umount client"
23079         mount_client $MOUNT "$MOUNT_OPTS,user_fid2path" ||
23080                 error "failed to mount client'"
23081
23082         $RUNAS $LFS rmfid $DIR $FID || error "rmfid failed"
23083         # rmfid should succeed
23084         cnt=$(ls -1 $DIR/$tdir | wc -l)
23085         [ $cnt == 0 ] || error "unexpected #files after (6): $cnt"
23086
23087         # rmfid shouldn't allow to remove files due to dir's permission
23088         chmod a+rwx $DIR/$tdir
23089         touch $DIR/$tdir/f
23090         ls -la $DIR/$tdir
23091         FID=$(lfs path2fid $DIR/$tdir/f)
23092         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail"
23093
23094         umount_client $MOUNT || error "failed to umount client"
23095         mount_client $MOUNT "$MOUNT_OPTS" ||
23096                 error "failed to mount client'"
23097
23098 }
23099 run_test 421f "rmfid checks permissions"
23100
23101 test_421g() {
23102         local cnt
23103         local FIDS
23104
23105         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
23106         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
23107                 skip "Need MDS version at least 2.12.54"
23108
23109         mkdir -p $DIR/$tdir
23110         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
23111         createmany -o $DIR/$tdir/striped_dir/f 512
23112         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
23113         [ $cnt != 512 ] && error "unexpected #files: $cnt"
23114
23115         FIDS=$(lfs path2fid $DIR/$tdir/striped_dir/f* |
23116                 sed "s/[/][^:]*://g")
23117
23118         rm -f $DIR/$tdir/striped_dir/f1*
23119         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
23120         removed=$((512 - cnt))
23121
23122         # few files have been just removed, so we expect
23123         # rmfid to fail on their fids
23124         errors=$($LFS rmfid $DIR $FIDS 2>&1 | wc -l)
23125         [ $removed != $errors ] && error "$errors != $removed"
23126
23127         cnt=$(ls $DIR/$tdir/striped_dir | wc -l)
23128         rm -rf $DIR/$tdir
23129         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
23130 }
23131 run_test 421g "rmfid to return errors properly"
23132
23133 test_422() {
23134         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d1
23135         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d2
23136         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d3
23137         dd if=/dev/zero of=$DIR/$tdir/d1/file1 bs=1k count=1
23138         dd if=/dev/zero of=$DIR/$tdir/d2/file1 bs=1k count=1
23139
23140         local amc=$(at_max_get client)
23141         local amo=$(at_max_get mds1)
23142         local timeout=`lctl get_param -n timeout`
23143
23144         at_max_set 0 client
23145         at_max_set 0 mds1
23146
23147 #define OBD_FAIL_PTLRPC_PAUSE_REQ        0x50a
23148         do_facet mds1 $LCTL set_param fail_loc=0x8000050a \
23149                         fail_val=$(((2*timeout + 10)*1000))
23150         touch $DIR/$tdir/d3/file &
23151         sleep 2
23152 #define OBD_FAIL_TGT_REPLY_DATA_RACE     0x722
23153         do_facet mds1 $LCTL set_param fail_loc=0x80000722 \
23154                         fail_val=$((2*timeout + 5))
23155         mv $DIR/$tdir/d1/file1 $DIR/$tdir/d1/file2 &
23156         local pid=$!
23157         sleep 1
23158         kill -9 $pid
23159         sleep $((2 * timeout))
23160         echo kill $pid
23161         kill -9 $pid
23162         lctl mark touch
23163         touch $DIR/$tdir/d2/file3
23164         touch $DIR/$tdir/d2/file4
23165         touch $DIR/$tdir/d2/file5
23166
23167         wait
23168         at_max_set $amc client
23169         at_max_set $amo mds1
23170
23171         # LU-12838 - verify the ptlrpc thread watchdog is not always throttled
23172         do_facet mds1 "dmesg | grep 'Dumping the stack trace for debugging'" ||
23173                 error "Watchdog is always throttled"
23174 }
23175 run_test 422 "kill a process with RPC in progress"
23176
23177 stat_test() {
23178     df -h $MOUNT &
23179     df -h $MOUNT &
23180     df -h $MOUNT &
23181     df -h $MOUNT &
23182     df -h $MOUNT &
23183     df -h $MOUNT &
23184 }
23185
23186 test_423() {
23187     local _stats
23188     # ensure statfs cache is expired
23189     sleep 2;
23190
23191     _stats=$(stat_test | grep $MOUNT | sort -u | wc -l)
23192     [[ ${_stats} -ne 1 ]] && error "statfs wrong"
23193
23194     return 0
23195 }
23196 run_test 423 "statfs should return a right data"
23197
23198 test_424() {
23199 #define OBD_FAIL_PTLRPC_BULK_REPLY_ATTACH      0x522 | OBD_FAIL_ONCE
23200         $LCTL set_param fail_loc=0x80000522
23201         dd if=/dev/zero of=$DIR/$tfile bs=2M count=1 oflag=sync
23202         rm -f $DIR/$tfile
23203 }
23204 run_test 424 "simulate ENOMEM in ptl_send_rpc bulk reply ME attach"
23205
23206 prep_801() {
23207         [[ $MDS1_VERSION -lt $(version_code 2.9.55) ]] ||
23208         [[ $OST1_VERSION -lt $(version_code 2.9.55) ]] &&
23209                 skip "Need server version at least 2.9.55"
23210
23211         start_full_debug_logging
23212 }
23213
23214 post_801() {
23215         stop_full_debug_logging
23216 }
23217
23218 barrier_stat() {
23219         if [ $MGS_VERSION -le $(version_code 2.10.0) ]; then
23220                 local st=$(do_facet mgs $LCTL barrier_stat $FSNAME |
23221                            awk '/The barrier for/ { print $7 }')
23222                 echo $st
23223         else
23224                 local st=$(do_facet mgs $LCTL barrier_stat -s $FSNAME)
23225                 echo \'$st\'
23226         fi
23227 }
23228
23229 barrier_expired() {
23230         local expired
23231
23232         if [ $MGS_VERSION -le $(version_code 2.10.0) ]; then
23233                 expired=$(do_facet mgs $LCTL barrier_stat $FSNAME |
23234                           awk '/will be expired/ { print $7 }')
23235         else
23236                 expired=$(do_facet mgs $LCTL barrier_stat -t $FSNAME)
23237         fi
23238
23239         echo $expired
23240 }
23241
23242 test_801a() {
23243         prep_801
23244
23245         echo "Start barrier_freeze at: $(date)"
23246         #define OBD_FAIL_BARRIER_DELAY          0x2202
23247         do_facet mgs $LCTL set_param fail_val=5 fail_loc=0x2202
23248         # Do not reduce barrier time - See LU-11873
23249         do_facet mgs $LCTL barrier_freeze $FSNAME 20 &
23250
23251         sleep 2
23252         local b_status=$(barrier_stat)
23253         echo "Got barrier status at: $(date)"
23254         [ "$b_status" = "'freezing_p1'" ] ||
23255                 error "(1) unexpected barrier status $b_status"
23256
23257         do_facet mgs $LCTL set_param fail_val=0 fail_loc=0
23258         wait
23259         b_status=$(barrier_stat)
23260         [ "$b_status" = "'frozen'" ] ||
23261                 error "(2) unexpected barrier status $b_status"
23262
23263         local expired=$(barrier_expired)
23264         echo "sleep $((expired + 3)) seconds, then the barrier will be expired"
23265         sleep $((expired + 3))
23266
23267         b_status=$(barrier_stat)
23268         [ "$b_status" = "'expired'" ] ||
23269                 error "(3) unexpected barrier status $b_status"
23270
23271         # Do not reduce barrier time - See LU-11873
23272         do_facet mgs $LCTL barrier_freeze $FSNAME 20 ||
23273                 error "(4) fail to freeze barrier"
23274
23275         b_status=$(barrier_stat)
23276         [ "$b_status" = "'frozen'" ] ||
23277                 error "(5) unexpected barrier status $b_status"
23278
23279         echo "Start barrier_thaw at: $(date)"
23280         #define OBD_FAIL_BARRIER_DELAY          0x2202
23281         do_facet mgs $LCTL set_param fail_val=5 fail_loc=0x2202
23282         do_facet mgs $LCTL barrier_thaw $FSNAME &
23283
23284         sleep 2
23285         b_status=$(barrier_stat)
23286         echo "Got barrier status at: $(date)"
23287         [ "$b_status" = "'thawing'" ] ||
23288                 error "(6) unexpected barrier status $b_status"
23289
23290         do_facet mgs $LCTL set_param fail_val=0 fail_loc=0
23291         wait
23292         b_status=$(barrier_stat)
23293         [ "$b_status" = "'thawed'" ] ||
23294                 error "(7) unexpected barrier status $b_status"
23295
23296         #define OBD_FAIL_BARRIER_FAILURE        0x2203
23297         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2203
23298         do_facet mgs $LCTL barrier_freeze $FSNAME
23299
23300         b_status=$(barrier_stat)
23301         [ "$b_status" = "'failed'" ] ||
23302                 error "(8) unexpected barrier status $b_status"
23303
23304         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
23305         do_facet mgs $LCTL barrier_thaw $FSNAME
23306
23307         post_801
23308 }
23309 run_test 801a "write barrier user interfaces and stat machine"
23310
23311 test_801b() {
23312         prep_801
23313
23314         mkdir $DIR/$tdir || error "(1) fail to mkdir"
23315         createmany -d $DIR/$tdir/d 6 || "(2) fail to mkdir"
23316         touch $DIR/$tdir/d2/f10 || error "(3) fail to touch"
23317         touch $DIR/$tdir/d3/f11 || error "(4) fail to touch"
23318         touch $DIR/$tdir/d4/f12 || error "(5) fail to touch"
23319
23320         cancel_lru_locks mdc
23321
23322         # 180 seconds should be long enough
23323         do_facet mgs $LCTL barrier_freeze $FSNAME 180
23324
23325         local b_status=$(barrier_stat)
23326         [ "$b_status" = "'frozen'" ] ||
23327                 error "(6) unexpected barrier status $b_status"
23328
23329         mkdir $DIR/$tdir/d0/d10 &
23330         mkdir_pid=$!
23331
23332         touch $DIR/$tdir/d1/f13 &
23333         touch_pid=$!
23334
23335         ln $DIR/$tdir/d2/f10 $DIR/$tdir/d2/f14 &
23336         ln_pid=$!
23337
23338         mv $DIR/$tdir/d3/f11 $DIR/$tdir/d3/f15 &
23339         mv_pid=$!
23340
23341         rm -f $DIR/$tdir/d4/f12 &
23342         rm_pid=$!
23343
23344         stat $DIR/$tdir/d5 || error "(7) stat should succeed"
23345
23346         # To guarantee taht the 'stat' is not blocked
23347         b_status=$(barrier_stat)
23348         [ "$b_status" = "'frozen'" ] ||
23349                 error "(8) unexpected barrier status $b_status"
23350
23351         # let above commands to run at background
23352         sleep 5
23353
23354         ps -p $mkdir_pid || error "(9) mkdir should be blocked"
23355         ps -p $touch_pid || error "(10) touch should be blocked"
23356         ps -p $ln_pid || error "(11) link should be blocked"
23357         ps -p $mv_pid || error "(12) rename should be blocked"
23358         ps -p $rm_pid || error "(13) unlink should be blocked"
23359
23360         b_status=$(barrier_stat)
23361         [ "$b_status" = "'frozen'" ] ||
23362                 error "(14) unexpected barrier status $b_status"
23363
23364         do_facet mgs $LCTL barrier_thaw $FSNAME
23365         b_status=$(barrier_stat)
23366         [ "$b_status" = "'thawed'" ] ||
23367                 error "(15) unexpected barrier status $b_status"
23368
23369         wait $mkdir_pid || error "(16) mkdir should succeed"
23370         wait $touch_pid || error "(17) touch should succeed"
23371         wait $ln_pid || error "(18) link should succeed"
23372         wait $mv_pid || error "(19) rename should succeed"
23373         wait $rm_pid || error "(20) unlink should succeed"
23374
23375         post_801
23376 }
23377 run_test 801b "modification will be blocked by write barrier"
23378
23379 test_801c() {
23380         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
23381
23382         prep_801
23383
23384         stop mds2 || error "(1) Fail to stop mds2"
23385
23386         do_facet mgs $LCTL barrier_freeze $FSNAME 30
23387
23388         local b_status=$(barrier_stat)
23389         [ "$b_status" = "'expired'" ] || [ "$b_status" = "'failed'" ] || {
23390                 do_facet mgs $LCTL barrier_thaw $FSNAME
23391                 error "(2) unexpected barrier status $b_status"
23392         }
23393
23394         do_facet mgs $LCTL barrier_rescan $FSNAME ||
23395                 error "(3) Fail to rescan barrier bitmap"
23396
23397         # Do not reduce barrier time - See LU-11873
23398         do_facet mgs $LCTL barrier_freeze $FSNAME 20
23399
23400         b_status=$(barrier_stat)
23401         [ "$b_status" = "'frozen'" ] ||
23402                 error "(4) unexpected barrier status $b_status"
23403
23404         do_facet mgs $LCTL barrier_thaw $FSNAME
23405         b_status=$(barrier_stat)
23406         [ "$b_status" = "'thawed'" ] ||
23407                 error "(5) unexpected barrier status $b_status"
23408
23409         local devname=$(mdsdevname 2)
23410
23411         start mds2 $devname $MDS_MOUNT_OPTS || error "(6) Fail to start mds2"
23412
23413         do_facet mgs $LCTL barrier_rescan $FSNAME ||
23414                 error "(7) Fail to rescan barrier bitmap"
23415
23416         post_801
23417 }
23418 run_test 801c "rescan barrier bitmap"
23419
23420 saved_MGS_MOUNT_OPTS=$MGS_MOUNT_OPTS
23421 saved_MDS_MOUNT_OPTS=$MDS_MOUNT_OPTS
23422 saved_OST_MOUNT_OPTS=$OST_MOUNT_OPTS
23423 saved_MOUNT_OPTS=$MOUNT_OPTS
23424
23425 cleanup_802a() {
23426         trap 0
23427
23428         stopall
23429         MGS_MOUNT_OPTS=$saved_MGS_MOUNT_OPTS
23430         MDS_MOUNT_OPTS=$saved_MDS_MOUNT_OPTS
23431         OST_MOUNT_OPTS=$saved_OST_MOUNT_OPTS
23432         MOUNT_OPTS=$saved_MOUNT_OPTS
23433         setupall
23434 }
23435
23436 test_802a() {
23437         [[ $mds1_FSTYPE = zfs ]] || skip "ZFS specific test"
23438         [[ $MDS1_VERSION -lt $(version_code 2.9.55) ]] ||
23439         [[ $OST1_VERSION -lt $(version_code 2.9.55) ]] &&
23440                 skip "Need server version at least 2.9.55"
23441
23442         [[ $ENABLE_QUOTA ]] && skip "Quota enabled for read-only test"
23443
23444         mkdir $DIR/$tdir || error "(1) fail to mkdir"
23445
23446         cp $LUSTRE/tests/test-framework.sh $DIR/$tdir/ ||
23447                 error "(2) Fail to copy"
23448
23449         trap cleanup_802a EXIT
23450
23451         # sync by force before remount as readonly
23452         sync; sync_all_data; sleep 3; sync_all_data
23453
23454         stopall
23455
23456         MGS_MOUNT_OPTS=$(csa_add "$MGS_MOUNT_OPTS" -o rdonly_dev)
23457         MDS_MOUNT_OPTS=$(csa_add "$MDS_MOUNT_OPTS" -o rdonly_dev)
23458         OST_MOUNT_OPTS=$(csa_add "$OST_MOUNT_OPTS" -o rdonly_dev)
23459
23460         echo "Mount the server as read only"
23461         setupall server_only || error "(3) Fail to start servers"
23462
23463         echo "Mount client without ro should fail"
23464         mount_client $MOUNT &&
23465                 error "(4) Mount client without 'ro' should fail"
23466
23467         echo "Mount client with ro should succeed"
23468         MOUNT_OPTS=$(csa_add "$MOUNT_OPTS" -o ro)
23469         mount_client $MOUNT ||
23470                 error "(5) Mount client with 'ro' should succeed"
23471
23472         echo "Modify should be refused"
23473         touch $DIR/$tdir/guard && error "(6) Touch should fail under ro mode"
23474
23475         echo "Read should be allowed"
23476         diff $LUSTRE/tests/test-framework.sh $DIR/$tdir/test-framework.sh ||
23477                 error "(7) Read should succeed under ro mode"
23478
23479         cleanup_802a
23480 }
23481 run_test 802a "simulate readonly device"
23482
23483 test_802b() {
23484         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23485         remote_mds_nodsh && skip "remote MDS with nodsh"
23486
23487         do_facet $SINGLEMDS $LCTL get_param mdt.*.readonly ||
23488                 skip "readonly option not available"
23489
23490         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "(1) fail to mkdir"
23491
23492         cp $LUSTRE/tests/test-framework.sh $DIR/$tdir/ ||
23493                 error "(2) Fail to copy"
23494
23495         # write back all cached data before setting MDT to readonly
23496         cancel_lru_locks
23497         sync_all_data
23498
23499         do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=1
23500         stack_trap "do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=0" EXIT
23501
23502         echo "Modify should be refused"
23503         touch $DIR/$tdir/guard && error "(6) Touch should fail under ro mode"
23504
23505         echo "Read should be allowed"
23506         diff $LUSTRE/tests/test-framework.sh $DIR/$tdir/test-framework.sh ||
23507                 error "(7) Read should succeed under ro mode"
23508
23509         # disable readonly
23510         do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=0
23511 }
23512 run_test 802b "be able to set MDTs to readonly"
23513
23514 test_803() {
23515         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
23516         [ $MDS1_VERSION -lt $(version_code 2.10.54) ] &&
23517                 skip "MDS needs to be newer than 2.10.54"
23518
23519         mkdir -p $DIR/$tdir
23520         # Create some objects on all MDTs to trigger related logs objects
23521         for idx in $(seq $MDSCOUNT); do
23522                 $LFS mkdir -c $MDSCOUNT -i $((idx % $MDSCOUNT)) \
23523                         $DIR/$tdir/dir${idx} ||
23524                         error "Fail to create $DIR/$tdir/dir${idx}"
23525         done
23526
23527         sync; sleep 3
23528         wait_delete_completed # ensure old test cleanups are finished
23529         echo "before create:"
23530         $LFS df -i $MOUNT
23531         local before_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
23532
23533         for i in {1..10}; do
23534                 $LFS mkdir -c 1 -i 1 $DIR/$tdir/foo$i ||
23535                         error "Fail to create $DIR/$tdir/foo$i"
23536         done
23537
23538         sync; sleep 3
23539         echo "after create:"
23540         $LFS df -i $MOUNT
23541         local after_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
23542
23543         # allow for an llog to be cleaned up during the test
23544         [ $after_used -ge $((before_used + 10 - 1)) ] ||
23545                 error "before ($before_used) + 10 > after ($after_used)"
23546
23547         for i in {1..10}; do
23548                 rm -rf $DIR/$tdir/foo$i ||
23549                         error "Fail to remove $DIR/$tdir/foo$i"
23550         done
23551
23552         sleep 3 # avoid MDT return cached statfs
23553         wait_delete_completed
23554         echo "after unlink:"
23555         $LFS df -i $MOUNT
23556         after_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
23557
23558         # allow for an llog to be created during the test
23559         [ $after_used -le $((before_used + 1)) ] ||
23560                 error "after ($after_used) > before ($before_used) + 1"
23561 }
23562 run_test 803 "verify agent object for remote object"
23563
23564 test_804() {
23565         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
23566         [ $MDS1_VERSION -lt $(version_code 2.10.54) ] &&
23567                 skip "MDS needs to be newer than 2.10.54"
23568         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
23569
23570         mkdir -p $DIR/$tdir
23571         $LFS mkdir -c 1 -i 1 $DIR/$tdir/dir0 ||
23572                 error "Fail to create $DIR/$tdir/dir0"
23573
23574         local fid=$($LFS path2fid $DIR/$tdir/dir0)
23575         local dev=$(mdsdevname 2)
23576
23577         do_facet mds2 "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
23578                 grep ${fid} || error "NOT found agent entry for dir0"
23579
23580         $LFS mkdir -c $MDSCOUNT -i 0 $DIR/$tdir/dir1 ||
23581                 error "Fail to create $DIR/$tdir/dir1"
23582
23583         touch $DIR/$tdir/dir1/foo0 ||
23584                 error "Fail to create $DIR/$tdir/dir1/foo0"
23585         fid=$($LFS path2fid $DIR/$tdir/dir1/foo0)
23586         local rc=0
23587
23588         for idx in $(seq $MDSCOUNT); do
23589                 dev=$(mdsdevname $idx)
23590                 do_facet mds${idx} \
23591                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
23592                         grep ${fid} && rc=$idx
23593         done
23594
23595         mv $DIR/$tdir/dir1/foo0 $DIR/$tdir/dir1/foo1 ||
23596                 error "Fail to rename foo0 to foo1"
23597         if [ $rc -eq 0 ]; then
23598                 for idx in $(seq $MDSCOUNT); do
23599                         dev=$(mdsdevname $idx)
23600                         do_facet mds${idx} \
23601                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
23602                         grep ${fid} && rc=$idx
23603                 done
23604         fi
23605
23606         mv $DIR/$tdir/dir1/foo1 $DIR/$tdir/dir1/foo2 ||
23607                 error "Fail to rename foo1 to foo2"
23608         if [ $rc -eq 0 ]; then
23609                 for idx in $(seq $MDSCOUNT); do
23610                         dev=$(mdsdevname $idx)
23611                         do_facet mds${idx} \
23612                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
23613                         grep ${fid} && rc=$idx
23614                 done
23615         fi
23616
23617         [ $rc -ne 0 ] || error "NOT found agent entry for foo"
23618
23619         ln $DIR/$tdir/dir1/foo2 $DIR/$tdir/dir0/guard ||
23620                 error "Fail to link to $DIR/$tdir/dir1/foo2"
23621         mv $DIR/$tdir/dir1/foo2 $DIR/$tdir/dir1/foo0 ||
23622                 error "Fail to rename foo2 to foo0"
23623         unlink $DIR/$tdir/dir1/foo0 ||
23624                 error "Fail to unlink $DIR/$tdir/dir1/foo0"
23625         rm -rf $DIR/$tdir/dir0 ||
23626                 error "Fail to rm $DIR/$tdir/dir0"
23627
23628         for idx in $(seq $MDSCOUNT); do
23629                 dev=$(mdsdevname $idx)
23630                 rc=0
23631
23632                 stop mds${idx}
23633                 run_e2fsck $(facet_active_host mds$idx) $dev -n ||
23634                         rc=$?
23635                 start mds${idx} $dev $MDS_MOUNT_OPTS ||
23636                         error "mount mds$idx failed"
23637                 df $MOUNT > /dev/null 2>&1
23638
23639                 # e2fsck should not return error
23640                 [ $rc -eq 0 ] ||
23641                         error "e2fsck detected error on MDT${idx}: rc=$rc"
23642         done
23643 }
23644 run_test 804 "verify agent entry for remote entry"
23645
23646 cleanup_805() {
23647         do_facet $SINGLEMDS zfs set quota=$old $fsset
23648         unlinkmany $DIR/$tdir/f- 1000000
23649         trap 0
23650 }
23651
23652 test_805() {
23653         local zfs_version=$(do_facet mds1 cat /sys/module/zfs/version)
23654         [ "$mds1_FSTYPE" != "zfs" ] && skip "ZFS specific test"
23655         [ $(version_code $zfs_version) -lt $(version_code 0.7.2) ] &&
23656                 skip "netfree not implemented before 0.7"
23657         [[ $MDS1_VERSION -ge $(version_code 2.10.57) ]] ||
23658                 skip "Need MDS version at least 2.10.57"
23659
23660         local fsset
23661         local freekb
23662         local usedkb
23663         local old
23664         local quota
23665         local pref="osd-zfs.$FSNAME-MDT0000."
23666
23667         # limit available space on MDS dataset to meet nospace issue
23668         # quickly. then ZFS 0.7.2 can use reserved space if asked
23669         # properly (using netfree flag in osd_declare_destroy()
23670         fsset=$(do_facet $SINGLEMDS lctl get_param -n $pref.mntdev)
23671         old=$(do_facet $SINGLEMDS zfs get -H quota $fsset | \
23672                 gawk '{print $3}')
23673         freekb=$(do_facet $SINGLEMDS lctl get_param -n $pref.kbytesfree)
23674         usedkb=$(do_facet $SINGLEMDS lctl get_param -n $pref.kbytestotal)
23675         let "usedkb=usedkb-freekb"
23676         let "freekb=freekb/2"
23677         if let "freekb > 5000"; then
23678                 let "freekb=5000"
23679         fi
23680         do_facet $SINGLEMDS zfs set quota=$(((usedkb+freekb)*1024)) $fsset
23681         trap cleanup_805 EXIT
23682         mkdir $DIR/$tdir
23683         $LFS setstripe -E 1M -c2 -E 4M -c2 -E -1 -c2 $DIR/$tdir ||
23684                 error "Can't set PFL layout"
23685         createmany -m $DIR/$tdir/f- 1000000 && error "ENOSPC wasn't met"
23686         rm -rf $DIR/$tdir || error "not able to remove"
23687         do_facet $SINGLEMDS zfs set quota=$old $fsset
23688         trap 0
23689 }
23690 run_test 805 "ZFS can remove from full fs"
23691
23692 # Size-on-MDS test
23693 check_lsom_data()
23694 {
23695         local file=$1
23696         local size=$($LFS getsom -s $file)
23697         local expect=$(stat -c %s $file)
23698
23699         [[ $size == $expect ]] ||
23700                 error "$file expected size: $expect, got: $size"
23701
23702         local blocks=$($LFS getsom -b $file)
23703         expect=$(stat -c %b $file)
23704         [[ $blocks == $expect ]] ||
23705                 error "$file expected blocks: $expect, got: $blocks"
23706 }
23707
23708 check_lsom_size()
23709 {
23710         local size=$($LFS getsom -s $1)
23711         local expect=$2
23712
23713         [[ $size == $expect ]] ||
23714                 error "$file expected size: $expect, got: $size"
23715 }
23716
23717 test_806() {
23718         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
23719                 skip "Need MDS version at least 2.11.52"
23720
23721         local bs=1048576
23722
23723         touch $DIR/$tfile || error "touch $tfile failed"
23724
23725         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
23726         save_lustre_params client "llite.*.xattr_cache" > $save
23727         lctl set_param llite.*.xattr_cache=0
23728         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
23729
23730         # single-threaded write
23731         echo "Test SOM for single-threaded write"
23732         dd if=/dev/zero of=$DIR/$tfile bs=$bs count=1 ||
23733                 error "write $tfile failed"
23734         check_lsom_size $DIR/$tfile $bs
23735
23736         local num=32
23737         local size=$(($num * $bs))
23738         local offset=0
23739         local i
23740
23741         echo "Test SOM for single client multi-threaded($num) write"
23742         $TRUNCATE $DIR/$tfile 0
23743         for ((i = 0; i < $num; i++)); do
23744                 $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
23745                 local pids[$i]=$!
23746                 offset=$((offset + $bs))
23747         done
23748         for (( i=0; i < $num; i++ )); do
23749                 wait ${pids[$i]}
23750         done
23751         check_lsom_size $DIR/$tfile $size
23752
23753         $TRUNCATE $DIR/$tfile 0
23754         for ((i = 0; i < $num; i++)); do
23755                 offset=$((offset - $bs))
23756                 $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
23757                 local pids[$i]=$!
23758         done
23759         for (( i=0; i < $num; i++ )); do
23760                 wait ${pids[$i]}
23761         done
23762         check_lsom_size $DIR/$tfile $size
23763
23764         # multi-client writes
23765         num=$(get_node_count ${CLIENTS//,/ })
23766         size=$(($num * $bs))
23767         offset=0
23768         i=0
23769
23770         echo "Test SOM for multi-client ($num) writes"
23771         $TRUNCATE $DIR/$tfile 0
23772         for client in ${CLIENTS//,/ }; do
23773                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
23774                 local pids[$i]=$!
23775                 i=$((i + 1))
23776                 offset=$((offset + $bs))
23777         done
23778         for (( i=0; i < $num; i++ )); do
23779                 wait ${pids[$i]}
23780         done
23781         check_lsom_size $DIR/$tfile $offset
23782
23783         i=0
23784         $TRUNCATE $DIR/$tfile 0
23785         for client in ${CLIENTS//,/ }; do
23786                 offset=$((offset - $bs))
23787                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
23788                 local pids[$i]=$!
23789                 i=$((i + 1))
23790         done
23791         for (( i=0; i < $num; i++ )); do
23792                 wait ${pids[$i]}
23793         done
23794         check_lsom_size $DIR/$tfile $size
23795
23796         # verify truncate
23797         echo "Test SOM for truncate"
23798         $TRUNCATE $DIR/$tfile 1048576
23799         check_lsom_size $DIR/$tfile 1048576
23800         $TRUNCATE $DIR/$tfile 1234
23801         check_lsom_size $DIR/$tfile 1234
23802
23803         # verify SOM blocks count
23804         echo "Verify SOM block count"
23805         $TRUNCATE $DIR/$tfile 0
23806         $MULTIOP $DIR/$tfile oO_TRUNC:O_RDWR:w1048576YSc ||
23807                 error "failed to write file $tfile"
23808         check_lsom_data $DIR/$tfile
23809 }
23810 run_test 806 "Verify Lazy Size on MDS"
23811
23812 test_807() {
23813         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
23814         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
23815                 skip "Need MDS version at least 2.11.52"
23816
23817         # Registration step
23818         changelog_register || error "changelog_register failed"
23819         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
23820         changelog_users $SINGLEMDS | grep -q $cl_user ||
23821                 error "User $cl_user not found in changelog_users"
23822
23823         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
23824         save_lustre_params client "llite.*.xattr_cache" > $save
23825         lctl set_param llite.*.xattr_cache=0
23826         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
23827
23828         rm -rf $DIR/$tdir || error "rm $tdir failed"
23829         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
23830         touch $DIR/$tdir/trunc || error "touch $tdir/trunc failed"
23831         $TRUNCATE $DIR/$tdir/trunc 1024 || error "truncate $tdir/trunc failed"
23832         $TRUNCATE $DIR/$tdir/trunc 1048576 ||
23833                 error "truncate $tdir/trunc failed"
23834
23835         local bs=1048576
23836         dd if=/dev/zero of=$DIR/$tdir/single_dd bs=$bs count=1 conv=fsync ||
23837                 error "write $tfile failed"
23838
23839         # multi-client wirtes
23840         local num=$(get_node_count ${CLIENTS//,/ })
23841         local offset=0
23842         local i=0
23843
23844         echo "Test SOM for multi-client ($num) writes"
23845         touch $DIR/$tfile || error "touch $tfile failed"
23846         $TRUNCATE $DIR/$tfile 0
23847         for client in ${CLIENTS//,/ }; do
23848                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
23849                 local pids[$i]=$!
23850                 i=$((i + 1))
23851                 offset=$((offset + $bs))
23852         done
23853         for (( i=0; i < $num; i++ )); do
23854                 wait ${pids[$i]}
23855         done
23856
23857         do_rpc_nodes "$CLIENTS" cancel_lru_locks osc
23858         do_nodes "$CLIENTS" "sync ; sleep 5 ; sync"
23859         $LSOM_SYNC -u $cl_user -m $FSNAME-MDT0000 $MOUNT
23860         check_lsom_data $DIR/$tdir/trunc
23861         check_lsom_data $DIR/$tdir/single_dd
23862         check_lsom_data $DIR/$tfile
23863
23864         rm -rf $DIR/$tdir
23865         # Deregistration step
23866         changelog_deregister || error "changelog_deregister failed"
23867 }
23868 run_test 807 "verify LSOM syncing tool"
23869
23870 check_som_nologged()
23871 {
23872         local lines=$($LFS changelog $FSNAME-MDT0000 |
23873                 grep 'x=trusted.som' | wc -l)
23874         [ $lines -ne 0 ] && error "trusted.som xattr is logged in Changelogs"
23875 }
23876
23877 test_808() {
23878         [ $MDS1_VERSION -lt $(version_code 2.11.55) ] &&
23879                 skip "Need MDS version at least 2.11.55"
23880
23881         # Registration step
23882         changelog_register || error "changelog_register failed"
23883
23884         touch $DIR/$tfile || error "touch $tfile failed"
23885         check_som_nologged
23886
23887         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=1 ||
23888                 error "write $tfile failed"
23889         check_som_nologged
23890
23891         $TRUNCATE $DIR/$tfile 1234
23892         check_som_nologged
23893
23894         $TRUNCATE $DIR/$tfile 1048576
23895         check_som_nologged
23896
23897         # Deregistration step
23898         changelog_deregister || error "changelog_deregister failed"
23899 }
23900 run_test 808 "Check trusted.som xattr not logged in Changelogs"
23901
23902 check_som_nodata()
23903 {
23904         $LFS getsom $1
23905         [[ $? -eq 61 ]] || error "DoM-only file $1 has SOM xattr"
23906 }
23907
23908 test_809() {
23909         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
23910                 skip "Need MDS version at least 2.11.56"
23911
23912         $LFS setstripe -E 1M -L mdt $DIR/$tfile ||
23913                 error "failed to create DoM-only file $DIR/$tfile"
23914         touch $DIR/$tfile || error "touch $tfile failed"
23915         check_som_nodata $DIR/$tfile
23916
23917         dd if=/dev/zero of=$DIR/$tfile bs=2048 count=1 ||
23918                 error "write $tfile failed"
23919         check_som_nodata $DIR/$tfile
23920
23921         $TRUNCATE $DIR/$tfile 1234
23922         check_som_nodata $DIR/$tfile
23923
23924         $TRUNCATE $DIR/$tfile 4097
23925         check_som_nodata $DIR/$file
23926 }
23927 run_test 809 "Verify no SOM xattr store for DoM-only files"
23928
23929 test_810() {
23930         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23931         $GSS && skip_env "could not run with gss"
23932         [[ $OST1_VERSION -gt $(version_code 2.12.58) ]] ||
23933                 skip "OST < 2.12.58 doesn't align checksum"
23934
23935         set_checksums 1
23936         stack_trap "set_checksums $ORIG_CSUM" EXIT
23937         stack_trap "set_checksum_type $ORIG_CSUM_TYPE" EXIT
23938
23939         local csum
23940         local before
23941         local after
23942         for csum in $CKSUM_TYPES; do
23943                 #define OBD_FAIL_OSC_NO_GRANT   0x411
23944                 $LCTL set_param osc.*.checksum_type=$csum fail_loc=0x411
23945                 for i in "10240 0" "10000 0" "4000 1" "500 1"; do
23946                         eval set -- $i
23947                         dd if=/dev/urandom of=$DIR/$tfile bs=$1 count=2 seek=$2
23948                         before=$(md5sum $DIR/$tfile)
23949                         $LCTL set_param ldlm.namespaces.*osc*.lru_size=clear
23950                         after=$(md5sum $DIR/$tfile)
23951                         [ "$before" == "$after" ] ||
23952                                 error "$csum: $before != $after bs=$1 seek=$2"
23953                 done
23954         done
23955 }
23956 run_test 810 "partial page writes on ZFS (LU-11663)"
23957
23958 test_812a() {
23959         [ $OST1_VERSION -lt $(version_code 2.12.51) ] &&
23960                 skip "OST < 2.12.51 doesn't support this fail_loc"
23961         [ "$SHARED_KEY" = true ] &&
23962                 skip "OSC connections never go IDLE with Shared-Keys enabled"
23963
23964         $LFS setstripe -c 1 -i 0 $DIR/$tfile
23965         # ensure ost1 is connected
23966         stat $DIR/$tfile >/dev/null || error "can't stat"
23967         wait_osc_import_state client ost1 FULL
23968         # no locks, no reqs to let the connection idle
23969         cancel_lru_locks osc
23970
23971         # delay OST_DISCONNECT on OST1 to put OSC into intermediate state
23972 #define OBD_FAIL_OST_DISCONNECT_DELAY    0x245
23973         do_facet ost1 "$LCTL set_param fail_loc=0x245 fail_val=8"
23974         wait_osc_import_state client ost1 CONNECTING
23975         do_facet ost1 "$LCTL set_param fail_loc=0 fail_val=0"
23976
23977         stat $DIR/$tfile >/dev/null || error "can't stat file"
23978 }
23979 run_test 812a "do not drop reqs generated when imp is going to idle (LU-11951)"
23980
23981 test_812b() { # LU-12378
23982         [ $OST1_VERSION -lt $(version_code 2.12.51) ] &&
23983                 skip "OST < 2.12.51 doesn't support this fail_loc"
23984         [ "$SHARED_KEY" = true ] &&
23985                 skip "OSC connections never go IDLE with Shared-Keys enabled"
23986
23987         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "setstripe failed"
23988         # ensure ost1 is connected
23989         stat $DIR/$tfile >/dev/null || error "can't stat"
23990         wait_osc_import_state client ost1 FULL
23991         # no locks, no reqs to let the connection idle
23992         cancel_lru_locks osc
23993
23994         # delay OST_DISCONNECT on OST1 to put OSC into intermediate state
23995 #define OBD_FAIL_OST_DISCONNECT_DELAY    0x245
23996         do_facet ost1 "$LCTL set_param fail_loc=0x245 fail_val=8"
23997         wait_osc_import_state client ost1 CONNECTING
23998         do_facet ost1 "$LCTL set_param fail_loc=0 fail_val=0"
23999
24000         $LFS quota -u 0 $DIR/ || error "lfs quota should succeed"
24001         wait_osc_import_state client ost1 IDLE
24002 }
24003 run_test 812b "do not drop no resend request for idle connect"
24004
24005 test_813() {
24006         local file_heat_sav=$($LCTL get_param -n llite.*.file_heat 2>/dev/null)
24007         [ -z "$file_heat_sav" ] && skip "no file heat support"
24008
24009         local readsample
24010         local writesample
24011         local readbyte
24012         local writebyte
24013         local readsample1
24014         local writesample1
24015         local readbyte1
24016         local writebyte1
24017
24018         local period_second=$($LCTL get_param -n llite.*.heat_period_second)
24019         local decay_pct=$($LCTL get_param -n llite.*.heat_decay_percentage)
24020
24021         $LCTL set_param -n llite.*.file_heat=1
24022         echo "Turn on file heat"
24023         echo "Period second: $period_second, Decay percentage: $decay_pct"
24024
24025         echo "QQQQ" > $DIR/$tfile
24026         echo "QQQQ" > $DIR/$tfile
24027         echo "QQQQ" > $DIR/$tfile
24028         cat $DIR/$tfile > /dev/null
24029         cat $DIR/$tfile > /dev/null
24030         cat $DIR/$tfile > /dev/null
24031         cat $DIR/$tfile > /dev/null
24032
24033         local out=$($LFS heat_get $DIR/$tfile)
24034
24035         $LFS heat_get $DIR/$tfile
24036         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
24037         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
24038         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
24039         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
24040
24041         [ $readsample -le 4 ] || error "read sample ($readsample) is wrong"
24042         [ $writesample -le 3 ] || error "write sample ($writesample) is wrong"
24043         [ $readbyte -le 20 ] || error "read bytes ($readbyte) is wrong"
24044         [ $writebyte -le 15 ] || error "write bytes ($writebyte) is wrong"
24045
24046         sleep $((period_second + 3))
24047         echo "Sleep $((period_second + 3)) seconds..."
24048         # The recursion formula to calculate the heat of the file f is as
24049         # follow:
24050         # Hi+1(f) = (1-P)*Hi(f)+ P*Ci
24051         # Where Hi is the heat value in the period between time points i*I and
24052         # (i+1)*I; Ci is the access count in the period; the symbol P refers
24053         # to the weight of Ci.
24054         out=$($LFS heat_get $DIR/$tfile)
24055         $LFS heat_get $DIR/$tfile
24056         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
24057         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
24058         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
24059         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
24060
24061         [ $(bc <<< "$readsample <= 4 * $decay_pct / 100") -eq 1 ] ||
24062                 error "read sample ($readsample) is wrong"
24063         [ $(bc <<< "$writesample <= 3 * $decay_pct / 100") -eq 1 ] ||
24064                 error "write sample ($writesample) is wrong"
24065         [ $(bc <<< "$readbyte <= 20 * $decay_pct / 100") -eq 1 ] ||
24066                 error "read bytes ($readbyte) is wrong"
24067         [ $(bc <<< "$writebyte <= 15 * $decay_pct / 100") -eq 1 ] ||
24068                 error "write bytes ($writebyte) is wrong"
24069
24070         echo "QQQQ" > $DIR/$tfile
24071         echo "QQQQ" > $DIR/$tfile
24072         echo "QQQQ" > $DIR/$tfile
24073         cat $DIR/$tfile > /dev/null
24074         cat $DIR/$tfile > /dev/null
24075         cat $DIR/$tfile > /dev/null
24076         cat $DIR/$tfile > /dev/null
24077
24078         sleep $((period_second + 3))
24079         echo "Sleep $((period_second + 3)) seconds..."
24080
24081         out=$($LFS heat_get $DIR/$tfile)
24082         $LFS heat_get $DIR/$tfile
24083         readsample1=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
24084         writesample1=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
24085         readbyte1=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
24086         writebyte1=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
24087
24088         [ $(bc <<< "$readsample1 <= ($readsample * (100 - $decay_pct) + \
24089                 4 * $decay_pct) / 100") -eq 1 ] ||
24090                 error "read sample ($readsample1) is wrong"
24091         [ $(bc <<< "$writesample1 <= ($writesample * (100 - $decay_pct) + \
24092                 3 * $decay_pct) / 100") -eq 1 ] ||
24093                 error "write sample ($writesample1) is wrong"
24094         [ $(bc <<< "$readbyte1 <= ($readbyte * (100 - $decay_pct) + \
24095                 20 * $decay_pct) / 100") -eq 1 ] ||
24096                 error "read bytes ($readbyte1) is wrong"
24097         [ $(bc <<< "$writebyte1 <= ($writebyte * (100 - $decay_pct) + \
24098                 15 * $decay_pct) / 100") -eq 1 ] ||
24099                 error "write bytes ($writebyte1) is wrong"
24100
24101         echo "Turn off file heat for the file $DIR/$tfile"
24102         $LFS heat_set -o $DIR/$tfile
24103
24104         echo "QQQQ" > $DIR/$tfile
24105         echo "QQQQ" > $DIR/$tfile
24106         echo "QQQQ" > $DIR/$tfile
24107         cat $DIR/$tfile > /dev/null
24108         cat $DIR/$tfile > /dev/null
24109         cat $DIR/$tfile > /dev/null
24110         cat $DIR/$tfile > /dev/null
24111
24112         out=$($LFS heat_get $DIR/$tfile)
24113         $LFS heat_get $DIR/$tfile
24114         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
24115         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
24116         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
24117         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
24118
24119         [ $readsample -eq 0 ] || error "read sample ($readsample) is wrong"
24120         [ $writesample -eq 0 ] || error "write sample ($writesample) is wrong"
24121         [ $readbyte -eq 0 ] || error "read bytes ($readbyte) is wrong"
24122         [ $writebyte -eq 0 ] || error "write bytes ($writebyte) is wrong"
24123
24124         echo "Trun on file heat for the file $DIR/$tfile"
24125         $LFS heat_set -O $DIR/$tfile
24126
24127         echo "QQQQ" > $DIR/$tfile
24128         echo "QQQQ" > $DIR/$tfile
24129         echo "QQQQ" > $DIR/$tfile
24130         cat $DIR/$tfile > /dev/null
24131         cat $DIR/$tfile > /dev/null
24132         cat $DIR/$tfile > /dev/null
24133         cat $DIR/$tfile > /dev/null
24134
24135         out=$($LFS heat_get $DIR/$tfile)
24136         $LFS heat_get $DIR/$tfile
24137         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
24138         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
24139         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
24140         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
24141
24142         [ $readsample -gt 0 ] || error "read sample ($readsample) is wrong"
24143         [ $writesample -gt 0 ] || error "write sample ($writesample) is wrong"
24144         [ $readbyte -gt 0 ] || error "read bytes ($readbyte) is wrong"
24145         [ $writebyte -gt 0 ] || error "write bytes ($writebyte) is wrong"
24146
24147         $LFS heat_set -c $DIR/$tfile
24148         $LCTL set_param -n llite.*.file_heat=0
24149         echo "Turn off file heat support for the Lustre filesystem"
24150
24151         echo "QQQQ" > $DIR/$tfile
24152         echo "QQQQ" > $DIR/$tfile
24153         echo "QQQQ" > $DIR/$tfile
24154         cat $DIR/$tfile > /dev/null
24155         cat $DIR/$tfile > /dev/null
24156         cat $DIR/$tfile > /dev/null
24157         cat $DIR/$tfile > /dev/null
24158
24159         out=$($LFS heat_get $DIR/$tfile)
24160         $LFS heat_get $DIR/$tfile
24161         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
24162         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
24163         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
24164         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
24165
24166         [ $readsample -eq 0 ] || error "read sample ($readsample) is wrong"
24167         [ $writesample -eq 0 ] || error "write sample ($writesample) is wrong"
24168         [ $readbyte -eq 0 ] || error "read bytes ($readbyte) is wrong"
24169         [ $writebyte -eq 0 ] || error "write bytes ($writebyte) is wrong"
24170
24171         $LCTL set_param -n llite.*.file_heat=$file_heat_sav
24172         rm -f $DIR/$tfile
24173 }
24174 run_test 813 "File heat verfication"
24175
24176 test_814()
24177 {
24178         dd of=$DIR/$tfile seek=128 bs=1k < /dev/null
24179         echo -n y >> $DIR/$tfile
24180         cp --sparse=always $DIR/$tfile $DIR/${tfile}.cp || error "copy failed"
24181         diff $DIR/$tfile $DIR/${tfile}.cp || error "files should be same"
24182 }
24183 run_test 814 "sparse cp works as expected (LU-12361)"
24184
24185 test_815()
24186 {
24187         writeme -b 100 $DIR/$tfile || error "write 100 bytes failed"
24188         writeme -b 0 $DIR/$tfile || error "write 0 byte failed"
24189 }
24190 run_test 815 "zero byte tiny write doesn't hang (LU-12382)"
24191
24192 test_816() {
24193         [ "$SHARED_KEY" = true ] &&
24194                 skip "OSC connections never go IDLE with Shared-Keys enabled"
24195
24196         $LFS setstripe -c 1 -i 0 $DIR/$tfile
24197         # ensure ost1 is connected
24198         stat $DIR/$tfile >/dev/null || error "can't stat"
24199         wait_osc_import_state client ost1 FULL
24200         # no locks, no reqs to let the connection idle
24201         cancel_lru_locks osc
24202         lru_resize_disable osc
24203         local before
24204         local now
24205         before=$($LCTL get_param -n \
24206                  ldlm.namespaces.$FSNAME-OST0000-osc-[^M]*.lru_size)
24207
24208         wait_osc_import_state client ost1 IDLE
24209         dd if=/dev/null of=$DIR/$tfile bs=1k count=1 conv=sync
24210         now=$($LCTL get_param -n \
24211               ldlm.namespaces.$FSNAME-OST0000-osc-[^M]*.lru_size)
24212         [ $before == $now ] || error "lru_size changed $before != $now"
24213 }
24214 run_test 816 "do not reset lru_resize on idle reconnect"
24215
24216 cleanup_817() {
24217         umount $tmpdir
24218         exportfs -u localhost:$DIR/nfsexp
24219         rm -rf $DIR/nfsexp
24220 }
24221
24222 test_817() {
24223         systemctl restart nfs-server.service || skip "failed to restart nfsd"
24224
24225         mkdir -p $DIR/nfsexp
24226         exportfs -orw,no_root_squash localhost:$DIR/nfsexp ||
24227                 error "failed to export nfs"
24228
24229         tmpdir=$(mktemp -d /tmp/nfs-XXXXXX)
24230         stack_trap cleanup_817 EXIT
24231
24232         mount -t nfs -orw localhost:$DIR/nfsexp $tmpdir ||
24233                 error "failed to mount nfs to $tmpdir"
24234
24235         cp /bin/true $tmpdir
24236         $DIR/nfsexp/true || error "failed to execute 'true' command"
24237 }
24238 run_test 817 "nfsd won't cache write lock for exec file"
24239
24240 test_818() {
24241         mkdir $DIR/$tdir
24242         $LFS setstripe -c1 -i0 $DIR/$tfile
24243         $LFS setstripe -c1 -i1 $DIR/$tfile
24244         stop $SINGLEMDS
24245         #define OBD_FAIL_OSP_CANT_PROCESS_LLOG          0x2105
24246         do_facet $SINGLEMDS lctl set_param fail_loc=0x80002105
24247         start $SINGLEMDS $(mdsdevname ${SINGLEMDS//mds/}) $MDS_MOUNT_OPTS ||
24248                 error "start $SINGLEMDS failed"
24249         rm -rf $DIR/$tdir
24250 }
24251 run_test 818 "unlink with failed llog"
24252
24253 test_819a() {
24254         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
24255         cancel_lru_locks osc
24256         #define OBD_FAIL_OST_2BIG_NIOBUF                0x248
24257         do_facet $SINGLEMDS lctl set_param fail_loc=0x80000248
24258         dd if=$DIR/$tfile of=/dev/null bs=1M count=1
24259         rm -f $TDIR/$tfile
24260 }
24261 run_test 819a "too big niobuf in read"
24262
24263 test_819b() {
24264         #define OBD_FAIL_OST_2BIG_NIOBUF                0x248
24265         do_facet $SINGLEMDS lctl set_param fail_loc=0x80000248
24266         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
24267         cancel_lru_locks osc
24268         sleep 1
24269         rm -f $TDIR/$tfile
24270 }
24271 run_test 819b "too big niobuf in write"
24272
24273
24274 function test_820_start_ost() {
24275         sleep 5
24276
24277         for num in $(seq $OSTCOUNT); do
24278                 start ost$num $(ostdevname $num) $OST_MOUNT_OPTS
24279         done
24280 }
24281
24282 test_820() {
24283         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
24284
24285         mkdir $DIR/$tdir
24286         umount_client $MOUNT || error "umount failed"
24287         for num in $(seq $OSTCOUNT); do
24288                 stop ost$num
24289         done
24290
24291         # mount client with no active OSTs
24292         # so that the client can't initialize max LOV EA size
24293         # from OSC notifications
24294         mount_client $MOUNT || error "mount failed"
24295         # delay OST starting to keep this 0 max EA size for a while
24296         test_820_start_ost &
24297
24298         # create a directory on MDS2
24299         test_mkdir -i 1 -c1 $DIR/$tdir/mds2 ||
24300                 error "Failed to create directory"
24301         # open intent should update default EA size
24302         # see mdc_update_max_ea_from_body()
24303         # notice this is the very first RPC to MDS2
24304         cp /etc/services $DIR/$tdir/mds2 ||
24305                 error "Failed to copy files to mds$n"
24306 }
24307 run_test 820 "update max EA from open intent"
24308
24309 #
24310 # tests that do cleanup/setup should be run at the end
24311 #
24312
24313 test_900() {
24314         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24315         local ls
24316
24317         #define OBD_FAIL_MGC_PAUSE_PROCESS_LOG   0x903
24318         $LCTL set_param fail_loc=0x903
24319
24320         cancel_lru_locks MGC
24321
24322         FAIL_ON_ERROR=true cleanup
24323         FAIL_ON_ERROR=true setup
24324 }
24325 run_test 900 "umount should not race with any mgc requeue thread"
24326
24327 # LUS-6253/LU-11185
24328 test_901() {
24329         local oldc
24330         local newc
24331         local olds
24332         local news
24333         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24334
24335         # some get_param have a bug to handle dot in param name
24336         cancel_lru_locks MGC
24337         oldc=$($LCTL get_param -n 'ldlm.namespaces.MGC*.lock_count')
24338         olds=$(do_facet mgs $LCTL get_param -n 'ldlm.namespaces.MGS*.lock_count')
24339         umount_client $MOUNT || error "umount failed"
24340         mount_client $MOUNT || error "mount failed"
24341         cancel_lru_locks MGC
24342         newc=$($LCTL get_param -n 'ldlm.namespaces.MGC*.lock_count')
24343         news=$(do_facet mgs $LCTL get_param -n 'ldlm.namespaces.MGS*.lock_count')
24344
24345         [ $oldc -lt $newc ] && error "mgc lock leak ($oldc != $newc)"
24346         [ $olds -lt $news ] && error "mgs lock leak ($olds != $news)"
24347
24348         return 0
24349 }
24350 run_test 901 "don't leak a mgc lock on client umount"
24351
24352 # LU-13377
24353 test_902() {
24354         [ $CLIENT_VERSION -lt $(version_code 2.13.52) ] &&
24355                 skip "client does not have LU-13377 fix"
24356         #define OBD_FAIL_LLITE_SHORT_COMMIT 0x1415
24357         $LCTL set_param fail_loc=0x1415
24358         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
24359         cancel_lru_locks osc
24360         rm -f $DIR/$tfile
24361 }
24362 run_test 902 "test short write doesn't hang lustre"
24363
24364 complete $SECONDS
24365 [ -f $EXT2_DEV ] && rm $EXT2_DEV || true
24366 check_and_cleanup_lustre
24367 if [ "$I_MOUNTED" != "yes" ]; then
24368         lctl set_param debug="$OLDDEBUG" 2> /dev/null || true
24369 fi
24370 exit_status