Whamcloud - gitweb
LU-14149 llite: fiemap set flags for encrypted files
[fs/lustre-release.git] / lustre / tests / sanity.sh
1 #!/bin/bash
2 #
3 # Run select tests by setting ONLY, or as arguments to the script.
4 # Skip specific tests by setting EXCEPT.
5 #
6 # e.g. ONLY="22 23" or ONLY="`seq 32 39`" or EXCEPT="31"
7 set -e
8
9 ONLY=${ONLY:-"$*"}
10
11 # Check Grants after these tests
12 GRANT_CHECK_LIST="$GRANT_CHECK_LIST 42a 42b 42c 42d 42e 63a 63b 64a 64b 64c 64d"
13
14 OSC=${OSC:-"osc"}
15
16 CC=${CC:-cc}
17 CREATETEST=${CREATETEST:-createtest}
18 LVERIFY=${LVERIFY:-ll_dirstripe_verify}
19 OPENFILE=${OPENFILE:-openfile}
20 OPENUNLINK=${OPENUNLINK:-openunlink}
21 READS=${READS:-"reads"}
22 MUNLINK=${MUNLINK:-munlink}
23 SOCKETSERVER=${SOCKETSERVER:-socketserver}
24 SOCKETCLIENT=${SOCKETCLIENT:-socketclient}
25 MEMHOG=${MEMHOG:-memhog}
26 DIRECTIO=${DIRECTIO:-directio}
27 ACCEPTOR_PORT=${ACCEPTOR_PORT:-988}
28 DEF_STRIPE_COUNT=-1
29 CHECK_GRANT=${CHECK_GRANT:-"yes"}
30 GRANT_CHECK_LIST=${GRANT_CHECK_LIST:-""}
31 export PARALLEL=${PARALLEL:-"no"}
32
33 TRACE=${TRACE:-""}
34 LUSTRE=${LUSTRE:-$(dirname $0)/..}
35 LUSTRE_TESTS_API_DIR=${LUSTRE_TESTS_API_DIR:-${LUSTRE}/tests/clientapi}
36 . $LUSTRE/tests/test-framework.sh
37 init_test_env $@
38
39 init_logging
40
41 ALWAYS_EXCEPT="$SANITY_EXCEPT "
42 # bug number for skipped test: LU-9693 LU-6493 LU-9693
43 ALWAYS_EXCEPT+="               42a     42b     42c "
44 # bug number:    LU-8411 LU-9054
45 ALWAYS_EXCEPT+=" 407     312"
46
47 if $SHARED_KEY; then
48         # bug number:    LU-14181 LU-14181
49         ALWAYS_EXCEPT+=" 64e      64f"
50 fi
51
52 selinux_status=$(getenforce)
53 if [ "$selinux_status" != "Disabled" ]; then
54         # bug number:
55         ALWAYS_EXCEPT+=""
56 fi
57
58 # skip the grant tests for ARM until they are fixed
59 if [[ $(uname -m) = aarch64 ]]; then
60         # bug number:    LU-11596
61         ALWAYS_EXCEPT+=" $GRANT_CHECK_LIST"
62         # bug number:    LU-11671 LU-11667
63         ALWAYS_EXCEPT+=" 45       317"
64         # bug number:    LU-14067 LU-14067
65         ALWAYS_EXCEPT+=" 400a     400b"
66 fi
67
68 # skip nfs tests on kernels >= 4.12.0 until they are fixed
69 if [ $LINUX_VERSION_CODE -ge $(version_code 4.12.0) ]; then
70         # bug number:   LU-12661
71         ALWAYS_EXCEPT+=" 817"
72 fi
73 # skip cgroup tests on RHEL8.1 kernels until they are fixed
74 if (( $LINUX_VERSION_CODE >= $(version_code 4.18.0) &&
75       $LINUX_VERSION_CODE <  $(version_code 5.4.0) )); then
76         # bug number:   LU-13063
77         ALWAYS_EXCEPT+=" 411"
78 fi
79
80 #                                  5          12     8   12  (min)"
81 [ "$SLOW" = "no" ] && EXCEPT_SLOW="27m 64b 68 71 115 135 136 300o"
82
83 if [ "$mds1_FSTYPE" = "zfs" ]; then
84         # bug number for skipped test:
85         ALWAYS_EXCEPT="$ALWAYS_EXCEPT  "
86         #                                               13    (min)"
87         [ "$SLOW" = "no" ] && EXCEPT_SLOW="$EXCEPT_SLOW 51b"
88 fi
89
90 # Get the SLES distro version
91 #
92 # Returns a version string that should only be used in comparing
93 # strings returned by version_code()
94 sles_version_code()
95 {
96         local version=$(grep VERSION_ID /etc/os-release | cut -d'"' -f2)
97
98         # All SuSE Linux versions have one decimal. version_code expects two
99         local sles_version=$version.0
100         version_code $sles_version
101 }
102
103 # Check if we are running on Ubuntu or SLES so we can make decisions on
104 # what tests to run
105 if [ -r /etc/SuSE-release ]; then
106         sles_version=$(sles_version_code)
107         [ $sles_version -lt $(version_code 11.4.0) ] &&
108                 # bug number for skipped test: LU-4341
109                 ALWAYS_EXCEPT="$ALWAYS_EXCEPT  170"
110         [ $sles_version -lt $(version_code 12.0.0) ] &&
111                 # bug number for skipped test: LU-3703
112                 ALWAYS_EXCEPT="$ALWAYS_EXCEPT  234"
113 elif [ -r /etc/os-release ]; then
114         if grep -qi ubuntu /etc/os-release; then
115                 ubuntu_version=$(version_code $(sed -n -e 's/"//g' \
116                                                 -e 's/^VERSION=//p' \
117                                                 /etc/os-release |
118                                                 awk '{ print $1 }'))
119
120                 if [[ $ubuntu_version -gt $(version_code 16.0.0) ]]; then
121                         # bug number for skipped test:
122                         #                LU-10334 LU-10366
123                         ALWAYS_EXCEPT+=" 103a     410"
124                 fi
125         fi
126 fi
127
128 build_test_filter
129 FAIL_ON_ERROR=false
130
131 cleanup() {
132         echo -n "cln.."
133         pgrep ll_sa > /dev/null && { echo "There are ll_sa thread not exit!"; exit 20; }
134         cleanupall ${FORCE} $* || { echo "FAILed to clean up"; exit 20; }
135 }
136 setup() {
137         echo -n "mnt.."
138         load_modules
139         setupall || exit 10
140         echo "done"
141 }
142
143 check_swap_layouts_support()
144 {
145         $LCTL get_param -n llite.*.sbi_flags | grep -q layout ||
146                 skip "Does not support layout lock."
147 }
148
149 check_swap_layout_no_dom()
150 {
151         local FOLDER=$1
152         local SUPP=$(lfs getstripe $FOLDER | grep "pattern:       mdt" | wc -l)
153         [ $SUPP -eq 0 ] || skip "layout swap does not support DOM files so far"
154 }
155
156 check_and_setup_lustre
157 DIR=${DIR:-$MOUNT}
158 assert_DIR
159
160 MAXFREE=${MAXFREE:-$((200000 * $OSTCOUNT))}
161
162 [ -f $DIR/d52a/foo ] && chattr -a $DIR/d52a/foo
163 [ -f $DIR/d52b/foo ] && chattr -i $DIR/d52b/foo
164 rm -rf $DIR/[Rdfs][0-9]*
165
166 # $RUNAS_ID may get set incorrectly somewhere else
167 [ $UID -eq 0 -a $RUNAS_ID -eq 0 ] &&
168         error "\$RUNAS_ID set to 0, but \$UID is also 0!"
169
170 check_runas_id $RUNAS_ID $RUNAS_GID $RUNAS
171
172 if [ "${ONLY}" = "MOUNT" ] ; then
173         echo "Lustre is up, please go on"
174         exit
175 fi
176
177 echo "preparing for tests involving mounts"
178 EXT2_DEV=${EXT2_DEV:-$TMP/SANITY.LOOP}
179 touch $EXT2_DEV
180 mke2fs -j -F $EXT2_DEV 8000 > /dev/null
181 echo # add a newline after mke2fs.
182
183 umask 077
184
185 OLDDEBUG=$(lctl get_param -n debug 2> /dev/null)
186 lctl set_param debug=-1 2> /dev/null || true
187 test_0a() {
188         touch $DIR/$tfile
189         $CHECKSTAT -t file $DIR/$tfile || error "$tfile is not a file"
190         rm $DIR/$tfile
191         $CHECKSTAT -a $DIR/$tfile || error "$tfile was not removed"
192 }
193 run_test 0a "touch; rm ====================="
194
195 test_0b() {
196         chmod 0755 $DIR || error "chmod 0755 $DIR failed"
197         $CHECKSTAT -p 0755 $DIR || error "$DIR permission is not 0755"
198 }
199 run_test 0b "chmod 0755 $DIR ============================="
200
201 test_0c() {
202         $LCTL get_param mdc.*.import | grep "state: FULL" ||
203                 error "import not FULL"
204         $LCTL get_param mdc.*.import | grep "target: $FSNAME-MDT" ||
205                 error "bad target"
206 }
207 run_test 0c "check import proc"
208
209 test_0d() { # LU-3397
210         [ $MGS_VERSION -lt $(version_code 2.10.57) ] &&
211                 skip "proc exports not supported before 2.10.57"
212
213         local mgs_exp="mgs.MGS.exports"
214         local client_uuid=$($LCTL get_param -n mgc.*.uuid)
215         local exp_client_nid
216         local exp_client_version
217         local exp_val
218         local imp_val
219         local temp_imp=$DIR/$tfile.import
220         local temp_exp=$DIR/$tfile.export
221
222         # save mgc import file to $temp_imp
223         $LCTL get_param mgc.*.import | tee $temp_imp
224         # Check if client uuid is found in MGS export
225         for exp_client_nid in $(do_facet mgs $LCTL get_param -N $mgs_exp.*); do
226                 [ $(do_facet mgs $LCTL get_param -n $exp_client_nid.uuid) == \
227                         $client_uuid ] &&
228                         break;
229         done
230         # save mgs export file to $temp_exp
231         do_facet mgs $LCTL get_param $exp_client_nid.export | tee $temp_exp
232
233         # Compare the value of field "connect_flags"
234         imp_val=$(grep "connect_flags" $temp_imp)
235         exp_val=$(grep "connect_flags" $temp_exp)
236         [ "$exp_val" == "$imp_val" ] ||
237                 error "export flags '$exp_val' != import flags '$imp_val'"
238
239         # Compare the value of client version
240         exp_client_version=$(awk '/target_version:/ { print $2 }' $temp_exp)
241         exp_val=$(version_code $exp_client_version)
242         imp_val=$CLIENT_VERSION
243         [ "$exp_val" == "$imp_val" ] ||
244                 error "export client version '$exp_val' != '$imp_val'"
245 }
246 run_test 0d "check export proc ============================="
247
248 test_1() {
249         test_mkdir $DIR/$tdir
250         test_mkdir $DIR/$tdir/d2
251         mkdir $DIR/$tdir/d2 && error "we expect EEXIST, but not returned"
252         $CHECKSTAT -t dir $DIR/$tdir/d2 || error "$tdir/d2 is not a dir"
253         rmdir $DIR/$tdir/d2
254         rmdir $DIR/$tdir
255         $CHECKSTAT -a $DIR/$tdir || error "$tdir was not removed"
256 }
257 run_test 1 "mkdir; remkdir; rmdir"
258
259 test_2() {
260         test_mkdir $DIR/$tdir
261         touch $DIR/$tdir/$tfile || error "touch $tdir/$tfile failed"
262         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "$tdir/$tfile not a file"
263         rm -r $DIR/$tdir
264         $CHECKSTAT -a $DIR/$tdir/$tfile || error "$tdir/$file is not removed"
265 }
266 run_test 2 "mkdir; touch; rmdir; check file"
267
268 test_3() {
269         test_mkdir $DIR/$tdir
270         $CHECKSTAT -t dir $DIR/$tdir || error "$tdir is not a directory"
271         touch $DIR/$tdir/$tfile
272         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "$tdir/$tfile not a file"
273         rm -r $DIR/$tdir
274         $CHECKSTAT -a $DIR/$tdir || error "$tdir is not removed"
275 }
276 run_test 3 "mkdir; touch; rmdir; check dir"
277
278 # LU-4471 - failed rmdir on remote directories still removes directory on MDT0
279 test_4() {
280         test_mkdir -i 1 $DIR/$tdir
281
282         touch $DIR/$tdir/$tfile ||
283                 error "Create file under remote directory failed"
284
285         rmdir $DIR/$tdir &&
286                 error "Expect error removing in-use dir $DIR/$tdir"
287
288         test -d $DIR/$tdir || error "Remote directory disappeared"
289
290         rm -rf $DIR/$tdir || error "remove remote dir error"
291 }
292 run_test 4 "mkdir; touch dir/file; rmdir; checkdir (expect error)"
293
294 test_5() {
295         test_mkdir $DIR/$tdir
296         test_mkdir $DIR/$tdir/d2
297         chmod 0707 $DIR/$tdir/d2 || error "chmod 0707 $tdir/d2 failed"
298         $CHECKSTAT -t dir -p 0707 $DIR/$tdir/d2 || error "$tdir/d2 not mode 707"
299         $CHECKSTAT -t dir $DIR/$tdir/d2 || error "$tdir/d2 is not a directory"
300 }
301 run_test 5 "mkdir .../d5 .../d5/d2; chmod .../d5/d2"
302
303 test_6a() {
304         touch $DIR/$tfile || error "touch $DIR/$tfile failed"
305         chmod 0666 $DIR/$tfile || error "chmod 0666 $tfile failed"
306         $CHECKSTAT -t file -p 0666 -u \#$UID $DIR/$tfile ||
307                 error "$tfile does not have perm 0666 or UID $UID"
308         $RUNAS chmod 0444 $DIR/$tfile && error "chmod $tfile worked on UID $UID"
309         $CHECKSTAT -t file -p 0666 -u \#$UID $DIR/$tfile ||
310                 error "$tfile should be 0666 and owned by UID $UID"
311 }
312 run_test 6a "touch f6a; chmod f6a; $RUNAS chmod f6a (should return error) =="
313
314 test_6c() {
315         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID"
316
317         touch $DIR/$tfile
318         chown $RUNAS_ID $DIR/$tfile || error "chown $RUNAS_ID $file failed"
319         $CHECKSTAT -t file -u \#$RUNAS_ID $DIR/$tfile ||
320                 error "$tfile should be owned by UID $RUNAS_ID"
321         $RUNAS chown $UID $DIR/$tfile && error "chown $UID $file succeeded"
322         $CHECKSTAT -t file -u \#$RUNAS_ID $DIR/$tfile ||
323                 error "$tfile should be owned by UID $RUNAS_ID"
324 }
325 run_test 6c "touch f6c; chown f6c; $RUNAS chown f6c (should return error) =="
326
327 test_6e() {
328         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID"
329
330         touch $DIR/$tfile
331         chgrp $RUNAS_ID $DIR/$tfile || error "chgrp $RUNAS_ID $file failed"
332         $CHECKSTAT -t file -u \#$UID -g \#$RUNAS_ID $DIR/$tfile ||
333                 error "$tfile should be owned by GID $UID"
334         $RUNAS chgrp $UID $DIR/$tfile && error "chgrp $UID $file succeeded"
335         $CHECKSTAT -t file -u \#$UID -g \#$RUNAS_ID $DIR/$tfile ||
336                 error "$tfile should be owned by UID $UID and GID $RUNAS_ID"
337 }
338 run_test 6e "touch+chgrp $tfile; $RUNAS chgrp $tfile (should return error)"
339
340 test_6g() {
341         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID"
342
343         test_mkdir $DIR/$tdir
344         chmod 777 $DIR/$tdir || error "chmod 0777 $tdir failed"
345         $RUNAS mkdir $DIR/$tdir/d || error "mkdir $tdir/d failed"
346         chmod g+s $DIR/$tdir/d || error "chmod g+s $tdir/d failed"
347         test_mkdir $DIR/$tdir/d/subdir
348         $CHECKSTAT -g \#$RUNAS_GID $DIR/$tdir/d/subdir ||
349                 error "$tdir/d/subdir should be GID $RUNAS_GID"
350         if [[ $MDSCOUNT -gt 1 ]]; then
351                 # check remote dir sgid inherite
352                 $LFS mkdir -i 0 $DIR/$tdir.local ||
353                         error "mkdir $tdir.local failed"
354                 chmod g+s $DIR/$tdir.local ||
355                         error "chmod $tdir.local failed"
356                 chgrp $RUNAS_GID $DIR/$tdir.local ||
357                         error "chgrp $tdir.local failed"
358                 $LFS mkdir -i 1 $DIR/$tdir.local/$tdir.remote ||
359                         error "mkdir $tdir.remote failed"
360                 $CHECKSTAT -g \#$RUNAS_GID $DIR/$tdir.local/$tdir.remote ||
361                         error "$tdir.remote should be owned by $UID.$RUNAS_ID"
362                 $CHECKSTAT -p 02755 $DIR/$tdir.local/$tdir.remote ||
363                         error "$tdir.remote should be mode 02755"
364         fi
365 }
366 run_test 6g "verify new dir in sgid dir inherits group"
367
368 test_6h() { # bug 7331
369         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID"
370
371         touch $DIR/$tfile || error "touch failed"
372         chown $RUNAS_ID:$RUNAS_GID $DIR/$tfile || error "initial chown failed"
373         $RUNAS -G$RUNAS_GID chown $RUNAS_ID:0 $DIR/$tfile &&
374                 error "chown $RUNAS_ID:0 $tfile worked as GID $RUNAS_GID"
375         $CHECKSTAT -t file -u \#$RUNAS_ID -g \#$RUNAS_GID $DIR/$tfile ||
376                 error "$tdir/$tfile should be UID $RUNAS_UID GID $RUNAS_GID"
377 }
378 run_test 6h "$RUNAS chown RUNAS_ID.0 .../$tfile (should return error)"
379
380 test_7a() {
381         test_mkdir $DIR/$tdir
382         $MCREATE $DIR/$tdir/$tfile
383         chmod 0666 $DIR/$tdir/$tfile
384         $CHECKSTAT -t file -p 0666 $DIR/$tdir/$tfile ||
385                 error "$tdir/$tfile should be mode 0666"
386 }
387 run_test 7a "mkdir .../d7; mcreate .../d7/f; chmod .../d7/f ===="
388
389 test_7b() {
390         if [ ! -d $DIR/$tdir ]; then
391                 test_mkdir $DIR/$tdir
392         fi
393         $MCREATE $DIR/$tdir/$tfile
394         echo -n foo > $DIR/$tdir/$tfile
395         [ "$(cat $DIR/$tdir/$tfile)" = "foo" ] || error "$tdir/$tfile not 'foo'"
396         $CHECKSTAT -t file -s 3 $DIR/$tdir/$tfile || error "$tfile size not 3"
397 }
398 run_test 7b "mkdir .../d7; mcreate d7/f2; echo foo > d7/f2 ====="
399
400 test_8() {
401         test_mkdir $DIR/$tdir
402         touch $DIR/$tdir/$tfile
403         chmod 0666 $DIR/$tdir/$tfile
404         $CHECKSTAT -t file -p 0666 $DIR/$tdir/$tfile ||
405                 error "$tfile mode not 0666"
406 }
407 run_test 8 "mkdir .../d8; touch .../d8/f; chmod .../d8/f ======="
408
409 test_9() {
410         test_mkdir $DIR/$tdir
411         test_mkdir $DIR/$tdir/d2
412         test_mkdir $DIR/$tdir/d2/d3
413         $CHECKSTAT -t dir $DIR/$tdir/d2/d3 || error "$tdir/d2/d3 not a dir"
414 }
415 run_test 9 "mkdir .../d9 .../d9/d2 .../d9/d2/d3 ================"
416
417 test_10() {
418         test_mkdir $DIR/$tdir
419         test_mkdir $DIR/$tdir/d2
420         touch $DIR/$tdir/d2/$tfile
421         $CHECKSTAT -t file $DIR/$tdir/d2/$tfile ||
422                 error "$tdir/d2/$tfile not a file"
423 }
424 run_test 10 "mkdir .../d10 .../d10/d2; touch .../d10/d2/f ======"
425
426 test_11() {
427         test_mkdir $DIR/$tdir
428         test_mkdir $DIR/$tdir/d2
429         chmod 0666 $DIR/$tdir/d2
430         chmod 0705 $DIR/$tdir/d2
431         $CHECKSTAT -t dir -p 0705 $DIR/$tdir/d2 ||
432                 error "$tdir/d2 mode not 0705"
433 }
434 run_test 11 "mkdir .../d11 d11/d2; chmod .../d11/d2 ============"
435
436 test_12() {
437         test_mkdir $DIR/$tdir
438         touch $DIR/$tdir/$tfile
439         chmod 0666 $DIR/$tdir/$tfile
440         chmod 0654 $DIR/$tdir/$tfile
441         $CHECKSTAT -t file -p 0654 $DIR/$tdir/$tfile ||
442                 error "$tdir/d2 mode not 0654"
443 }
444 run_test 12 "touch .../d12/f; chmod .../d12/f .../d12/f ========"
445
446 test_13() {
447         test_mkdir $DIR/$tdir
448         dd if=/dev/zero of=$DIR/$tdir/$tfile count=10
449         >  $DIR/$tdir/$tfile
450         $CHECKSTAT -t file -s 0 $DIR/$tdir/$tfile ||
451                 error "$tdir/$tfile size not 0 after truncate"
452 }
453 run_test 13 "creat .../d13/f; dd .../d13/f; > .../d13/f ========"
454
455 test_14() {
456         test_mkdir $DIR/$tdir
457         touch $DIR/$tdir/$tfile
458         rm $DIR/$tdir/$tfile
459         $CHECKSTAT -a $DIR/$tdir/$tfile || error "$tdir/$tfile not removed"
460 }
461 run_test 14 "touch .../d14/f; rm .../d14/f; rm .../d14/f ======="
462
463 test_15() {
464         test_mkdir $DIR/$tdir
465         touch $DIR/$tdir/$tfile
466         mv $DIR/$tdir/$tfile $DIR/$tdir/${tfile}_2
467         $CHECKSTAT -t file $DIR/$tdir/${tfile}_2 ||
468                 error "$tdir/${tfile_2} not a file after rename"
469         rm $DIR/$tdir/${tfile}_2 || error "unlink failed after rename"
470 }
471 run_test 15 "touch .../d15/f; mv .../d15/f .../d15/f2 =========="
472
473 test_16() {
474         test_mkdir $DIR/$tdir
475         touch $DIR/$tdir/$tfile
476         rm -rf $DIR/$tdir/$tfile
477         $CHECKSTAT -a $DIR/$tdir/$tfile || error "$tdir/$tfile not removed"
478 }
479 run_test 16 "touch .../d16/f; rm -rf .../d16/f"
480
481 test_17a() {
482         test_mkdir $DIR/$tdir
483         touch $DIR/$tdir/$tfile
484         ln -s $DIR/$tdir/$tfile $DIR/$tdir/l-exist
485         ls -l $DIR/$tdir
486         $CHECKSTAT -l $DIR/$tdir/$tfile $DIR/$tdir/l-exist ||
487                 error "$tdir/l-exist not a symlink"
488         $CHECKSTAT -f -t f $DIR/$tdir/l-exist ||
489                 error "$tdir/l-exist not referencing a file"
490         rm -f $DIR/$tdir/l-exist
491         $CHECKSTAT -a $DIR/$tdir/l-exist || error "$tdir/l-exist not removed"
492 }
493 run_test 17a "symlinks: create, remove (real)"
494
495 test_17b() {
496         test_mkdir $DIR/$tdir
497         ln -s no-such-file $DIR/$tdir/l-dangle
498         ls -l $DIR/$tdir
499         $CHECKSTAT -l no-such-file $DIR/$tdir/l-dangle ||
500                 error "$tdir/l-dangle not referencing no-such-file"
501         $CHECKSTAT -fa $DIR/$tdir/l-dangle ||
502                 error "$tdir/l-dangle not referencing non-existent file"
503         rm -f $DIR/$tdir/l-dangle
504         $CHECKSTAT -a $DIR/$tdir/l-dangle || error "$tdir/l-dangle not removed"
505 }
506 run_test 17b "symlinks: create, remove (dangling)"
507
508 test_17c() { # bug 3440 - don't save failed open RPC for replay
509         test_mkdir $DIR/$tdir
510         ln -s foo $DIR/$tdir/$tfile
511         cat $DIR/$tdir/$tfile && error "opened non-existent symlink" || true
512 }
513 run_test 17c "symlinks: open dangling (should return error)"
514
515 test_17d() {
516         test_mkdir $DIR/$tdir
517         ln -s foo $DIR/$tdir/$tfile
518         touch $DIR/$tdir/$tfile || error "creating to new symlink"
519 }
520 run_test 17d "symlinks: create dangling"
521
522 test_17e() {
523         test_mkdir $DIR/$tdir
524         local foo=$DIR/$tdir/$tfile
525         ln -s $foo $foo || error "create symlink failed"
526         ls -l $foo || error "ls -l failed"
527         ls $foo && error "ls not failed" || true
528 }
529 run_test 17e "symlinks: create recursive symlink (should return error)"
530
531 test_17f() {
532         test_mkdir $DIR/$tdir
533         ln -s 1234567890/2234567890/3234567890/4234567890 $DIR/$tdir/111
534         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890 $DIR/$tdir/222
535         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890/7234567890/8234567890 $DIR/$tdir/333
536         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890/7234567890/8234567890/9234567890/a234567890/b234567890 $DIR/$tdir/444
537         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890/7234567890/8234567890/9234567890/a234567890/b234567890/c234567890/d234567890/f234567890 $DIR/$tdir/555
538         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
539         ls -l  $DIR/$tdir
540 }
541 run_test 17f "symlinks: long and very long symlink name"
542
543 # str_repeat(S, N) generate a string that is string S repeated N times
544 str_repeat() {
545         local s=$1
546         local n=$2
547         local ret=''
548         while [ $((n -= 1)) -ge 0 ]; do
549                 ret=$ret$s
550         done
551         echo $ret
552 }
553
554 # Long symlinks and LU-2241
555 test_17g() {
556         test_mkdir $DIR/$tdir
557         local TESTS="59 60 61 4094 4095"
558
559         # Fix for inode size boundary in 2.1.4
560         [ $MDS1_VERSION -lt $(version_code 2.1.4) ] &&
561                 TESTS="4094 4095"
562
563         # Patch not applied to 2.2 or 2.3 branches
564         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] &&
565         [ $MDS1_VERSION -le $(version_code 2.3.55) ] &&
566                 TESTS="4094 4095"
567
568         for i in $TESTS; do
569                 local SYMNAME=$(str_repeat 'x' $i)
570                 ln -s $SYMNAME $DIR/$tdir/f$i || error "failed $i-char symlink"
571                 readlink $DIR/$tdir/f$i || error "failed $i-char readlink"
572         done
573 }
574 run_test 17g "symlinks: really long symlink name and inode boundaries"
575
576 test_17h() { #bug 17378
577         [ $PARALLEL == "yes" ] && skip "skip parallel run"
578         remote_mds_nodsh && skip "remote MDS with nodsh"
579
580         local mdt_idx
581
582         test_mkdir $DIR/$tdir
583         mdt_idx=$($LFS getdirstripe -i $DIR/$tdir)
584         $LFS setstripe -c -1 $DIR/$tdir
585         #define OBD_FAIL_MDS_LOV_PREP_CREATE 0x141
586         do_facet mds$((mdt_idx + 1)) lctl set_param fail_loc=0x80000141
587         touch $DIR/$tdir/$tfile || true
588 }
589 run_test 17h "create objects: lov_free_memmd() doesn't lbug"
590
591 test_17i() { #bug 20018
592         [ $PARALLEL == "yes" ] && skip "skip parallel run"
593         remote_mds_nodsh && skip "remote MDS with nodsh"
594
595         local foo=$DIR/$tdir/$tfile
596         local mdt_idx
597
598         test_mkdir -c1 $DIR/$tdir
599         mdt_idx=$($LFS getdirstripe -i $DIR/$tdir)
600         ln -s $foo $foo || error "create symlink failed"
601 #define OBD_FAIL_MDS_READLINK_EPROTO     0x143
602         do_facet mds$((mdt_idx + 1)) lctl set_param fail_loc=0x80000143
603         ls -l $foo && error "error not detected"
604         return 0
605 }
606 run_test 17i "don't panic on short symlink (should return error)"
607
608 test_17k() { #bug 22301
609         [ $PARALLEL == "yes" ] && skip "skip parallel run"
610         [[ -z "$(which rsync 2>/dev/null)" ]] &&
611                 skip "no rsync command"
612         rsync --help | grep -q xattr ||
613                 skip_env "$(rsync --version | head -n1) does not support xattrs"
614         test_mkdir $DIR/$tdir
615         test_mkdir $DIR/$tdir.new
616         touch $DIR/$tdir/$tfile
617         ln -s $DIR/$tdir/$tfile $DIR/$tdir/$tfile.lnk
618         rsync -av -X $DIR/$tdir/ $DIR/$tdir.new ||
619                 error "rsync failed with xattrs enabled"
620 }
621 run_test 17k "symlinks: rsync with xattrs enabled"
622
623 test_17l() { # LU-279
624         [[ -z "$(which getfattr 2>/dev/null)" ]] &&
625                 skip "no getfattr command"
626
627         test_mkdir $DIR/$tdir
628         touch $DIR/$tdir/$tfile
629         ln -s $DIR/$tdir/$tfile $DIR/$tdir/$tfile.lnk
630         for path in "$DIR/$tdir" "$DIR/$tdir/$tfile" "$DIR/$tdir/$tfile.lnk"; do
631                 # -h to not follow symlinks. -m '' to list all the xattrs.
632                 # grep to remove first line: '# file: $path'.
633                 for xattr in `getfattr -hm '' $path 2>/dev/null | grep -v '^#'`;
634                 do
635                         lgetxattr_size_check $path $xattr ||
636                                 error "lgetxattr_size_check $path $xattr failed"
637                 done
638         done
639 }
640 run_test 17l "Ensure lgetxattr's returned xattr size is consistent"
641
642 # LU-1540
643 test_17m() {
644         [ $PARALLEL == "yes" ] && skip "skip parallel run"
645         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
646         remote_mds_nodsh && skip "remote MDS with nodsh"
647         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] &&
648         [ $MDS1_VERSION -le $(version_code 2.2.93) ] &&
649                 skip "MDS 2.2.0-2.2.93 do not NUL-terminate symlinks"
650
651         local short_sym="0123456789"
652         local wdir=$DIR/$tdir
653         local i
654
655         test_mkdir $wdir
656         long_sym=$short_sym
657         # create a long symlink file
658         for ((i = 0; i < 4; ++i)); do
659                 long_sym=${long_sym}${long_sym}
660         done
661
662         echo "create 512 short and long symlink files under $wdir"
663         for ((i = 0; i < 256; ++i)); do
664                 ln -sf ${long_sym}"a5a5" $wdir/long-$i
665                 ln -sf ${short_sym}"a5a5" $wdir/short-$i
666         done
667
668         echo "erase them"
669         rm -f $wdir/*
670         sync
671         wait_delete_completed
672
673         echo "recreate the 512 symlink files with a shorter string"
674         for ((i = 0; i < 512; ++i)); do
675                 # rewrite the symlink file with a shorter string
676                 ln -sf ${long_sym} $wdir/long-$i || error "long_sym failed"
677                 ln -sf ${short_sym} $wdir/short-$i || error "short_sym failed"
678         done
679
680         local mds_index=$(($($LFS getstripe -m $wdir) + 1))
681         local devname=$(mdsdevname $mds_index)
682
683         echo "stop and checking mds${mds_index}:"
684         # e2fsck should not return error
685         stop mds${mds_index}
686         run_e2fsck $(facet_active_host mds${mds_index}) $devname -n
687         rc=$?
688
689         start mds${mds_index} $devname $MDS_MOUNT_OPTS ||
690                 error "start mds${mds_index} failed"
691         df $MOUNT > /dev/null 2>&1
692         [ $rc -eq 0 ] ||
693                 error "e2fsck detected error for short/long symlink: rc=$rc"
694         rm -f $wdir/*
695 }
696 run_test 17m "run e2fsck against MDT which contains short/long symlink"
697
698 check_fs_consistency_17n() {
699         local mdt_index
700         local rc=0
701
702         # create/unlink in 17n only change 2 MDTs(MDT1/MDT2),
703         # so it only check MDT1/MDT2 instead of all of MDTs.
704         for mdt_index in 1 2; do
705                 local devname=$(mdsdevname $mdt_index)
706                 # e2fsck should not return error
707                 stop mds${mdt_index}
708                 run_e2fsck $(facet_active_host mds$mdt_index) $devname -n ||
709                         rc=$((rc + $?))
710
711                 start mds${mdt_index} $devname $MDS_MOUNT_OPTS ||
712                         error "mount mds$mdt_index failed"
713                 df $MOUNT > /dev/null 2>&1
714         done
715         return $rc
716 }
717
718 test_17n() {
719         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
720         [ $PARALLEL == "yes" ] && skip "skip parallel run"
721         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
722         remote_mds_nodsh && skip "remote MDS with nodsh"
723         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] &&
724         [ $MDS1_VERSION -le $(version_code 2.2.93) ] &&
725                 skip "MDS 2.2.0-2.2.93 do not NUL-terminate symlinks"
726
727         local i
728
729         test_mkdir $DIR/$tdir
730         for ((i=0; i<10; i++)); do
731                 $LFS mkdir -i1 -c2 $DIR/$tdir/remote_dir_${i} ||
732                         error "create remote dir error $i"
733                 createmany -o $DIR/$tdir/remote_dir_${i}/f 10 ||
734                         error "create files under remote dir failed $i"
735         done
736
737         check_fs_consistency_17n ||
738                 error "e2fsck report error after create files under remote dir"
739
740         for ((i = 0; i < 10; i++)); do
741                 rm -rf $DIR/$tdir/remote_dir_${i} ||
742                         error "destroy remote dir error $i"
743         done
744
745         check_fs_consistency_17n ||
746                 error "e2fsck report error after unlink files under remote dir"
747
748         [ $MDS1_VERSION -lt $(version_code 2.4.50) ] &&
749                 skip "lustre < 2.4.50 does not support migrate mv"
750
751         for ((i = 0; i < 10; i++)); do
752                 mkdir -p $DIR/$tdir/remote_dir_${i}
753                 createmany -o $DIR/$tdir/remote_dir_${i}/f 10 ||
754                         error "create files under remote dir failed $i"
755                 $LFS migrate --mdt-index 1 $DIR/$tdir/remote_dir_${i} ||
756                         error "migrate remote dir error $i"
757         done
758         check_fs_consistency_17n || error "e2fsck report error after migration"
759
760         for ((i = 0; i < 10; i++)); do
761                 rm -rf $DIR/$tdir/remote_dir_${i} ||
762                         error "destroy remote dir error $i"
763         done
764
765         check_fs_consistency_17n || error "e2fsck report error after unlink"
766 }
767 run_test 17n "run e2fsck against master/slave MDT which contains remote dir"
768
769 test_17o() {
770         remote_mds_nodsh && skip "remote MDS with nodsh"
771         [ $MDS1_VERSION -lt $(version_code 2.3.64) ] &&
772                 skip "Need MDS version at least 2.3.64"
773
774         local wdir=$DIR/${tdir}o
775         local mdt_index
776         local rc=0
777
778         test_mkdir $wdir
779         touch $wdir/$tfile
780         mdt_index=$($LFS getstripe -m $wdir/$tfile)
781         mdt_index=$((mdt_index + 1))
782
783         cancel_lru_locks mdc
784         #fail mds will wait the failover finish then set
785         #following fail_loc to avoid interfer the recovery process.
786         fail mds${mdt_index}
787
788         #define OBD_FAIL_OSD_LMA_INCOMPAT 0x194
789         do_facet mds${mdt_index} lctl set_param fail_loc=0x194
790         ls -l $wdir/$tfile && rc=1
791         do_facet mds${mdt_index} lctl set_param fail_loc=0
792         [[ $rc -eq 0 ]] || error "stat file should fail"
793 }
794 run_test 17o "stat file with incompat LMA feature"
795
796 test_18() {
797         touch $DIR/$tfile || error "Failed to touch $DIR/$tfile: $?"
798         ls $DIR || error "Failed to ls $DIR: $?"
799 }
800 run_test 18 "touch .../f ; ls ... =============================="
801
802 test_19a() {
803         touch $DIR/$tfile
804         ls -l $DIR
805         rm $DIR/$tfile
806         $CHECKSTAT -a $DIR/$tfile || error "$tfile was not removed"
807 }
808 run_test 19a "touch .../f19 ; ls -l ... ; rm .../f19 ==========="
809
810 test_19b() {
811         ls -l $DIR/$tfile && error "ls -l $tfile failed"|| true
812 }
813 run_test 19b "ls -l .../f19 (should return error) =============="
814
815 test_19c() {
816         [ $RUNAS_ID -eq $UID ] &&
817                 skip_env "RUNAS_ID = UID = $UID -- skipping"
818
819         $RUNAS touch $DIR/$tfile && error "create non-root file failed" || true
820 }
821 run_test 19c "$RUNAS touch .../f19 (should return error) =="
822
823 test_19d() {
824         cat $DIR/f19 && error || true
825 }
826 run_test 19d "cat .../f19 (should return error) =============="
827
828 test_20() {
829         touch $DIR/$tfile
830         rm $DIR/$tfile
831         touch $DIR/$tfile
832         rm $DIR/$tfile
833         touch $DIR/$tfile
834         rm $DIR/$tfile
835         $CHECKSTAT -a $DIR/$tfile || error "$tfile was not removed"
836 }
837 run_test 20 "touch .../f ; ls -l ..."
838
839 test_21() {
840         test_mkdir $DIR/$tdir
841         [ -f $DIR/$tdir/dangle ] && rm -f $DIR/$tdir/dangle
842         ln -s dangle $DIR/$tdir/link
843         echo foo >> $DIR/$tdir/link
844         cat $DIR/$tdir/dangle
845         $CHECKSTAT -t link $DIR/$tdir/link || error "$tdir/link not a link"
846         $CHECKSTAT -f -t file $DIR/$tdir/link ||
847                 error "$tdir/link not linked to a file"
848 }
849 run_test 21 "write to dangling link"
850
851 test_22() {
852         local wdir=$DIR/$tdir
853         test_mkdir $wdir
854         chown $RUNAS_ID:$RUNAS_GID $wdir
855         (cd $wdir || error "cd $wdir failed";
856                 $RUNAS tar cf - /etc/hosts /etc/sysconfig/network |
857                 $RUNAS tar xf -)
858         ls -lR $wdir/etc || error "ls -lR $wdir/etc failed"
859         $CHECKSTAT -t dir $wdir/etc || error "checkstat -t dir failed"
860         $CHECKSTAT -u \#$RUNAS_ID -g \#$RUNAS_GID $wdir/etc ||
861                 error "checkstat -u failed"
862 }
863 run_test 22 "unpack tar archive as non-root user"
864
865 # was test_23
866 test_23a() {
867         test_mkdir $DIR/$tdir
868         local file=$DIR/$tdir/$tfile
869
870         openfile -f O_CREAT:O_EXCL $file || error "$file create failed"
871         openfile -f O_CREAT:O_EXCL $file &&
872                 error "$file recreate succeeded" || true
873 }
874 run_test 23a "O_CREAT|O_EXCL in subdir"
875
876 test_23b() { # bug 18988
877         test_mkdir $DIR/$tdir
878         local file=$DIR/$tdir/$tfile
879
880         rm -f $file
881         echo foo > $file || error "write filed"
882         echo bar >> $file || error "append filed"
883         $CHECKSTAT -s 8 $file || error "wrong size"
884         rm $file
885 }
886 run_test 23b "O_APPEND check"
887
888 # LU-9409, size with O_APPEND and tiny writes
889 test_23c() {
890         local file=$DIR/$tfile
891
892         # single dd
893         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=8 count=800
894         $CHECKSTAT -s 6400 $file || error "wrong size, expected 6400"
895         rm -f $file
896
897         # racing tiny writes
898         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=8 count=800 &
899         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=8 count=800 &
900         wait
901         $CHECKSTAT -s 12800 $file || error "wrong size, expected 12800"
902         rm -f $file
903
904         #racing tiny & normal writes
905         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=4096 count=4 &
906         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=8 count=100 &
907         wait
908         $CHECKSTAT -s 17184 $file || error "wrong size, expected 17184"
909         rm -f $file
910
911         #racing tiny & normal writes 2, ugly numbers
912         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=4099 count=11 &
913         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=17 count=173 &
914         wait
915         $CHECKSTAT -s 48030 $file || error "wrong size, expected 48030"
916         rm -f $file
917 }
918 run_test 23c "O_APPEND size checks for tiny writes"
919
920 # LU-11069 file offset is correct after appending writes
921 test_23d() {
922         local file=$DIR/$tfile
923         local offset
924
925         echo CentaurHauls > $file
926         offset=$($MULTIOP $file oO_WRONLY:O_APPEND:w13Zp)
927         if ((offset != 26)); then
928                 error "wrong offset, expected 26, got '$offset'"
929         fi
930 }
931 run_test 23d "file offset is correct after appending writes"
932
933 # rename sanity
934 test_24a() {
935         echo '-- same directory rename'
936         test_mkdir $DIR/$tdir
937         touch $DIR/$tdir/$tfile.1
938         mv $DIR/$tdir/$tfile.1 $DIR/$tdir/$tfile.2
939         $CHECKSTAT -t file $DIR/$tdir/$tfile.2 || error "$tfile.2 not a file"
940 }
941 run_test 24a "rename file to non-existent target"
942
943 test_24b() {
944         test_mkdir $DIR/$tdir
945         touch $DIR/$tdir/$tfile.{1,2}
946         mv $DIR/$tdir/$tfile.1 $DIR/$tdir/$tfile.2
947         $CHECKSTAT -a $DIR/$tdir/$tfile.1 || error "$tfile.1 exists"
948         $CHECKSTAT -t file $DIR/$tdir/$tfile.2 || error "$tfile.2 not a file"
949 }
950 run_test 24b "rename file to existing target"
951
952 test_24c() {
953         test_mkdir $DIR/$tdir
954         test_mkdir $DIR/$tdir/d$testnum.1
955         mv $DIR/$tdir/d$testnum.1 $DIR/$tdir/d$testnum.2
956         $CHECKSTAT -a $DIR/$tdir/d$testnum.1 || error "d$testnum.1 exists"
957         $CHECKSTAT -t dir $DIR/$tdir/d$testnum.2 || error "d$testnum.2 not dir"
958 }
959 run_test 24c "rename directory to non-existent target"
960
961 test_24d() {
962         test_mkdir -c1 $DIR/$tdir
963         test_mkdir -c1 $DIR/$tdir/d$testnum.1
964         test_mkdir -c1 $DIR/$tdir/d$testnum.2
965         mrename $DIR/$tdir/d$testnum.1 $DIR/$tdir/d$testnum.2
966         $CHECKSTAT -a $DIR/$tdir/d$testnum.1 || error "d$testnum.1 exists"
967         $CHECKSTAT -t dir $DIR/$tdir/d$testnum.2 || error "d$testnum.2 not dir"
968 }
969 run_test 24d "rename directory to existing target"
970
971 test_24e() {
972         echo '-- cross directory renames --'
973         test_mkdir $DIR/R5a
974         test_mkdir $DIR/R5b
975         touch $DIR/R5a/f
976         mv $DIR/R5a/f $DIR/R5b/g
977         $CHECKSTAT -a $DIR/R5a/f || error "$DIR/R5a/f exists"
978         $CHECKSTAT -t file $DIR/R5b/g || error "$DIR/R5b/g not file type"
979 }
980 run_test 24e "touch .../R5a/f; rename .../R5a/f .../R5b/g ======"
981
982 test_24f() {
983         test_mkdir $DIR/R6a
984         test_mkdir $DIR/R6b
985         touch $DIR/R6a/f $DIR/R6b/g
986         mv $DIR/R6a/f $DIR/R6b/g
987         $CHECKSTAT -a $DIR/R6a/f || error "$DIR/R6a/f exists"
988         $CHECKSTAT -t file $DIR/R6b/g || error "$DIR/R6b/g not file type"
989 }
990 run_test 24f "touch .../R6a/f R6b/g; mv .../R6a/f .../R6b/g ===="
991
992 test_24g() {
993         test_mkdir $DIR/R7a
994         test_mkdir $DIR/R7b
995         test_mkdir $DIR/R7a/d
996         mv $DIR/R7a/d $DIR/R7b/e
997         $CHECKSTAT -a $DIR/R7a/d || error "$DIR/R7a/d exists"
998         $CHECKSTAT -t dir $DIR/R7b/e || error "$DIR/R7b/e not dir type"
999 }
1000 run_test 24g "mkdir .../R7{a,b}/d; mv .../R7a/d .../R7b/e ======"
1001
1002 test_24h() {
1003         test_mkdir -c1 $DIR/R8a
1004         test_mkdir -c1 $DIR/R8b
1005         test_mkdir -c1 $DIR/R8a/d
1006         test_mkdir -c1 $DIR/R8b/e
1007         mrename $DIR/R8a/d $DIR/R8b/e
1008         $CHECKSTAT -a $DIR/R8a/d || error "$DIR/R8a/d exists"
1009         $CHECKSTAT -t dir $DIR/R8b/e || error "$DIR/R8b/e not dir type"
1010 }
1011 run_test 24h "mkdir .../R8{a,b}/{d,e}; rename .../R8a/d .../R8b/e"
1012
1013 test_24i() {
1014         echo "-- rename error cases"
1015         test_mkdir $DIR/R9
1016         test_mkdir $DIR/R9/a
1017         touch $DIR/R9/f
1018         mrename $DIR/R9/f $DIR/R9/a
1019         $CHECKSTAT -t file $DIR/R9/f || error "$DIR/R9/f not file type"
1020         $CHECKSTAT -t dir  $DIR/R9/a || error "$DIR/R9/a not dir type"
1021         $CHECKSTAT -a $DIR/R9/a/f || error "$DIR/R9/a/f exists"
1022 }
1023 run_test 24i "rename file to dir error: touch f ; mkdir a ; rename f a"
1024
1025 test_24j() {
1026         test_mkdir $DIR/R10
1027         mrename $DIR/R10/f $DIR/R10/g
1028         $CHECKSTAT -t dir $DIR/R10 || error "$DIR/R10 not dir type"
1029         $CHECKSTAT -a $DIR/R10/f || error "$DIR/R10/f exists"
1030         $CHECKSTAT -a $DIR/R10/g || error "$DIR/R10/g exists"
1031 }
1032 run_test 24j "source does not exist ============================"
1033
1034 test_24k() {
1035         test_mkdir $DIR/R11a
1036         test_mkdir $DIR/R11a/d
1037         touch $DIR/R11a/f
1038         mv $DIR/R11a/f $DIR/R11a/d
1039         $CHECKSTAT -a $DIR/R11a/f || error "$DIR/R11a/f exists"
1040         $CHECKSTAT -t file $DIR/R11a/d/f || error "$DIR/R11a/d/f not file type"
1041 }
1042 run_test 24k "touch .../R11a/f; mv .../R11a/f .../R11a/d ======="
1043
1044 # bug 2429 - rename foo foo foo creates invalid file
1045 test_24l() {
1046         f="$DIR/f24l"
1047         $MULTIOP $f OcNs || error "rename of ${f} to itself failed"
1048 }
1049 run_test 24l "Renaming a file to itself ========================"
1050
1051 test_24m() {
1052         f="$DIR/f24m"
1053         $MULTIOP $f OcLN ${f}2 ${f}2 || error "link ${f}2 ${f}2 failed"
1054         # on ext3 this does not remove either the source or target files
1055         # though the "expected" operation would be to remove the source
1056         $CHECKSTAT -t file ${f} || error "${f} missing"
1057         $CHECKSTAT -t file ${f}2 || error "${f}2 missing"
1058 }
1059 run_test 24m "Renaming a file to a hard link to itself ========="
1060
1061 test_24n() {
1062     f="$DIR/f24n"
1063     # this stats the old file after it was renamed, so it should fail
1064     touch ${f}
1065     $CHECKSTAT ${f} || error "${f} missing"
1066     mv ${f} ${f}.rename
1067     $CHECKSTAT ${f}.rename || error "${f}.rename missing"
1068     $CHECKSTAT -a ${f} || error "${f} exists"
1069 }
1070 run_test 24n "Statting the old file after renaming (Posix rename 2)"
1071
1072 test_24o() {
1073         test_mkdir $DIR/$tdir
1074         rename_many -s random -v -n 10 $DIR/$tdir
1075 }
1076 run_test 24o "rename of files during htree split"
1077
1078 test_24p() {
1079         test_mkdir $DIR/R12a
1080         test_mkdir $DIR/R12b
1081         DIRINO=`ls -lid $DIR/R12a | awk '{ print $1 }'`
1082         mrename $DIR/R12a $DIR/R12b
1083         $CHECKSTAT -a $DIR/R12a || error "$DIR/R12a exists"
1084         $CHECKSTAT -t dir $DIR/R12b || error "$DIR/R12b not dir type"
1085         DIRINO2=`ls -lid $DIR/R12b | awk '{ print $1 }'`
1086         [ "$DIRINO" = "$DIRINO2" ] || error "R12a $DIRINO != R12b $DIRINO2"
1087 }
1088 run_test 24p "mkdir .../R12{a,b}; rename .../R12a .../R12b"
1089
1090 cleanup_multiop_pause() {
1091         trap 0
1092         kill -USR1 $MULTIPID
1093 }
1094
1095 test_24q() {
1096         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1097
1098         test_mkdir $DIR/R13a
1099         test_mkdir $DIR/R13b
1100         local DIRINO=$(ls -lid $DIR/R13a | awk '{ print $1 }')
1101         multiop_bg_pause $DIR/R13b D_c || error "multiop failed to start"
1102         MULTIPID=$!
1103
1104         trap cleanup_multiop_pause EXIT
1105         mrename $DIR/R13a $DIR/R13b
1106         $CHECKSTAT -a $DIR/R13a || error "R13a still exists"
1107         $CHECKSTAT -t dir $DIR/R13b || error "R13b does not exist"
1108         local DIRINO2=$(ls -lid $DIR/R13b | awk '{ print $1 }')
1109         [ "$DIRINO" = "$DIRINO2" ] || error "R13a $DIRINO != R13b $DIRINO2"
1110         cleanup_multiop_pause
1111         wait $MULTIPID || error "multiop close failed"
1112 }
1113 run_test 24q "mkdir .../R13{a,b}; open R13b rename R13a R13b ==="
1114
1115 test_24r() { #bug 3789
1116         test_mkdir $DIR/R14a
1117         test_mkdir $DIR/R14a/b
1118         mrename $DIR/R14a $DIR/R14a/b && error "rename to subdir worked!"
1119         $CHECKSTAT -t dir $DIR/R14a || error "$DIR/R14a missing"
1120         $CHECKSTAT -t dir $DIR/R14a/b || error "$DIR/R14a/b missing"
1121 }
1122 run_test 24r "mkdir .../R14a/b; rename .../R14a .../R14a/b ====="
1123
1124 test_24s() {
1125         test_mkdir $DIR/R15a
1126         test_mkdir $DIR/R15a/b
1127         test_mkdir $DIR/R15a/b/c
1128         mrename $DIR/R15a $DIR/R15a/b/c && error "rename to sub-subdir worked!"
1129         $CHECKSTAT -t dir $DIR/R15a || error "$DIR/R15a missing"
1130         $CHECKSTAT -t dir $DIR/R15a/b/c || error "$DIR/R15a/b/c missing"
1131 }
1132 run_test 24s "mkdir .../R15a/b/c; rename .../R15a .../R15a/b/c ="
1133 test_24t() {
1134         test_mkdir $DIR/R16a
1135         test_mkdir $DIR/R16a/b
1136         test_mkdir $DIR/R16a/b/c
1137         mrename $DIR/R16a/b/c $DIR/R16a && error "rename to sub-subdir worked!"
1138         $CHECKSTAT -t dir $DIR/R16a || error "$DIR/R16a missing"
1139         $CHECKSTAT -t dir $DIR/R16a/b/c || error "$DIR/R16a/b/c missing"
1140 }
1141 run_test 24t "mkdir .../R16a/b/c; rename .../R16a/b/c .../R16a ="
1142
1143 test_24u() { # bug12192
1144         $MULTIOP $DIR/$tfile C2w$((2048 * 1024))c || error "multiop failed"
1145         $CHECKSTAT -s $((2048 * 1024)) $DIR/$tfile || error "wrong file size"
1146 }
1147 run_test 24u "create stripe file"
1148
1149 simple_cleanup_common() {
1150         local rc=0
1151         trap 0
1152         [ -z "$DIR" ] || [ -z "$tdir" ] && return 0
1153
1154         local start=$SECONDS
1155         rm -rf $DIR/$tdir
1156         rc=$?
1157         wait_delete_completed
1158         echo "cleanup time $((SECONDS - start))"
1159         return $rc
1160 }
1161
1162 max_pages_per_rpc() {
1163         local mdtname="$(printf "MDT%04x" ${1:-0})"
1164         $LCTL get_param -n mdc.*$mdtname*.max_pages_per_rpc
1165 }
1166
1167 test_24v() {
1168         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1169
1170         local nrfiles=${COUNT:-100000}
1171         local fname="$DIR/$tdir/$tfile"
1172
1173         # Performance issue on ZFS see LU-4072 (c.f. LU-2887)
1174         [ "$mds1_FSTYPE" = "zfs" ] && nrfiles=${COUNT:-10000}
1175
1176         test_mkdir "$(dirname $fname)"
1177         # assume MDT0000 has the fewest inodes
1178         local stripes=$($LFS getdirstripe -c $(dirname $fname))
1179         local free_inodes=$(($(mdt_free_inodes 0) * stripes))
1180         [[ $free_inodes -lt $nrfiles ]] && nrfiles=$free_inodes
1181
1182         trap simple_cleanup_common EXIT
1183
1184         createmany -m "$fname" $nrfiles
1185
1186         cancel_lru_locks mdc
1187         lctl set_param mdc.*.stats clear
1188
1189         # was previously test_24D: LU-6101
1190         # readdir() returns correct number of entries after cursor reload
1191         local num_ls=$(ls $DIR/$tdir | wc -l)
1192         local num_uniq=$(ls $DIR/$tdir | sort -u | wc -l)
1193         local num_all=$(ls -a $DIR/$tdir | wc -l)
1194         if [ $num_ls -ne $nrfiles ] || [ $num_uniq -ne $nrfiles ] ||
1195                 [ $num_all -ne $((nrfiles + 2)) ]; then
1196                         error "Expected $nrfiles files, got $num_ls " \
1197                                 "($num_uniq unique $num_all .&..)"
1198         fi
1199         # LU-5 large readdir
1200         # dirent_size = 32 bytes for sizeof(struct lu_dirent) +
1201         #               N bytes for name (len($nrfiles) rounded to 8 bytes) +
1202         #               8 bytes for luda_type (4 bytes rounded to 8 bytes)
1203         # take into account of overhead in lu_dirpage header and end mark in
1204         # each page, plus one in rpc_num calculation.
1205         local dirent_size=$((32 + (${#tfile} | 7) + 1 + 8))
1206         local page_entries=$(((PAGE_SIZE - 24) / dirent_size))
1207         local mdt_idx=$($LFS getdirstripe -i $(dirname $fname))
1208         local rpc_pages=$(max_pages_per_rpc $mdt_idx)
1209         local rpc_max=$((nrfiles / (page_entries * rpc_pages) + stripes))
1210         local mds_readpage=$(calc_stats mdc.*.stats mds_readpage)
1211         echo "readpages: $mds_readpage rpc_max: $rpc_max"
1212         (( $mds_readpage < $rpc_max - 2 || $mds_readpage > $rpc_max + 1)) &&
1213                 error "large readdir doesn't take effect: " \
1214                       "$mds_readpage should be about $rpc_max"
1215
1216         simple_cleanup_common
1217 }
1218 run_test 24v "list large directory (test hash collision, b=17560)"
1219
1220 test_24w() { # bug21506
1221         SZ1=234852
1222         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=4096 || return 1
1223         dd if=/dev/zero bs=$SZ1 count=1 >> $DIR/$tfile || return 2
1224         dd if=$DIR/$tfile of=$DIR/${tfile}_left bs=1M skip=4097 || return 3
1225         SZ2=`ls -l $DIR/${tfile}_left | awk '{print $5}'`
1226         [[ "$SZ1" -eq "$SZ2" ]] ||
1227                 error "Error reading at the end of the file $tfile"
1228 }
1229 run_test 24w "Reading a file larger than 4Gb"
1230
1231 test_24x() {
1232         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
1233         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1234         [[ $MDS1_VERSION -lt $(version_code 2.7.56) ]] &&
1235                 skip "Need MDS version at least 2.7.56"
1236
1237         local MDTIDX=1
1238         local remote_dir=$DIR/$tdir/remote_dir
1239
1240         test_mkdir $DIR/$tdir
1241         $LFS mkdir -i $MDTIDX $remote_dir ||
1242                 error "create remote directory failed"
1243
1244         test_mkdir $DIR/$tdir/src_dir
1245         touch $DIR/$tdir/src_file
1246         test_mkdir $remote_dir/tgt_dir
1247         touch $remote_dir/tgt_file
1248
1249         mrename $DIR/$tdir/src_dir $remote_dir/tgt_dir ||
1250                 error "rename dir cross MDT failed!"
1251
1252         mrename $DIR/$tdir/src_file $remote_dir/tgt_file ||
1253                 error "rename file cross MDT failed!"
1254
1255         touch $DIR/$tdir/ln_file
1256         ln $DIR/$tdir/ln_file $remote_dir/ln_name ||
1257                 error "ln file cross MDT failed"
1258
1259         rm -rf $DIR/$tdir || error "Can not delete directories"
1260 }
1261 run_test 24x "cross MDT rename/link"
1262
1263 test_24y() {
1264         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
1265         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1266
1267         local remote_dir=$DIR/$tdir/remote_dir
1268         local mdtidx=1
1269
1270         test_mkdir $DIR/$tdir
1271         $LFS mkdir -i $mdtidx $remote_dir ||
1272                 error "create remote directory failed"
1273
1274         test_mkdir $remote_dir/src_dir
1275         touch $remote_dir/src_file
1276         test_mkdir $remote_dir/tgt_dir
1277         touch $remote_dir/tgt_file
1278
1279         mrename $remote_dir/src_dir $remote_dir/tgt_dir ||
1280                 error "rename subdir in the same remote dir failed!"
1281
1282         mrename $remote_dir/src_file $remote_dir/tgt_file ||
1283                 error "rename files in the same remote dir failed!"
1284
1285         ln $remote_dir/tgt_file $remote_dir/tgt_file1 ||
1286                 error "link files in the same remote dir failed!"
1287
1288         rm -rf $DIR/$tdir || error "Can not delete directories"
1289 }
1290 run_test 24y "rename/link on the same dir should succeed"
1291
1292 test_24z() {
1293         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
1294         [[ $MDS1_VERSION -lt $(version_code 2.12.51) ]] &&
1295                 skip "Need MDS version at least 2.12.51"
1296
1297         local index
1298
1299         for index in 0 1; do
1300                 $LFS mkdir -i $index $DIR/$tdir.$index || error "mkdir failed"
1301                 touch $DIR/$tdir.0/$tfile.$index || error "touch failed"
1302         done
1303
1304         mv $DIR/$tdir.0/$tfile.0 $DIR/$tdir.1 || error "mv $tfile.0 failed"
1305
1306         index=$($LFS getstripe -m $DIR/$tdir.1/$tfile.0)
1307         [ $index -eq 0 ] || error "$tfile.0 is on MDT$index"
1308
1309         local mdts=$(comma_list $(mdts_nodes))
1310
1311         do_nodes $mdts $LCTL set_param mdt.*.enable_remote_rename=0
1312         stack_trap "do_nodes $mdts $LCTL \
1313                 set_param mdt.*.enable_remote_rename=1" EXIT
1314
1315         mv $DIR/$tdir.0/$tfile.1 $DIR/$tdir.1 || error "mv $tfile.1 failed"
1316
1317         index=$($LFS getstripe -m $DIR/$tdir.1/$tfile.1)
1318         [ $index -eq 1 ] || error "$tfile.1 is on MDT$index"
1319 }
1320 run_test 24z "cross-MDT rename is done as cp"
1321
1322 test_24A() { # LU-3182
1323         local NFILES=5000
1324
1325         rm -rf $DIR/$tdir
1326         test_mkdir $DIR/$tdir
1327         trap simple_cleanup_common EXIT
1328         createmany -m $DIR/$tdir/$tfile $NFILES
1329         local t=$(ls $DIR/$tdir | wc -l)
1330         local u=$(ls $DIR/$tdir | sort -u | wc -l)
1331         local v=$(ls -ai $DIR/$tdir | sort -u | wc -l)
1332         if [ $t -ne $NFILES ] || [ $u -ne $NFILES ] ||
1333            [ $v -ne $((NFILES + 2)) ] ; then
1334                 error "Expected $NFILES files, got $t ($u unique $v .&..)"
1335         fi
1336
1337         simple_cleanup_common || error "Can not delete directories"
1338 }
1339 run_test 24A "readdir() returns correct number of entries."
1340
1341 test_24B() { # LU-4805
1342         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
1343
1344         local count
1345
1346         test_mkdir $DIR/$tdir
1347         $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir ||
1348                 error "create striped dir failed"
1349
1350         count=$(ls -ai $DIR/$tdir/striped_dir | wc -l)
1351         [ $count -eq 2 ] || error "Expected 2, got $count"
1352
1353         touch $DIR/$tdir/striped_dir/a
1354
1355         count=$(ls -ai $DIR/$tdir/striped_dir | wc -l)
1356         [ $count -eq 3 ] || error "Expected 3, got $count"
1357
1358         touch $DIR/$tdir/striped_dir/.f
1359
1360         count=$(ls -ai $DIR/$tdir/striped_dir | wc -l)
1361         [ $count -eq 4 ] || error "Expected 4, got $count"
1362
1363         rm -rf $DIR/$tdir || error "Can not delete directories"
1364 }
1365 run_test 24B "readdir for striped dir return correct number of entries"
1366
1367 test_24C() {
1368         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
1369
1370         mkdir $DIR/$tdir
1371         mkdir $DIR/$tdir/d0
1372         mkdir $DIR/$tdir/d1
1373
1374         $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/d0/striped_dir ||
1375                 error "create striped dir failed"
1376
1377         cd $DIR/$tdir/d0/striped_dir
1378
1379         local d0_ino=$(ls -i -l -a $DIR/$tdir | grep "d0" | awk '{print $1}')
1380         local d1_ino=$(ls -i -l -a $DIR/$tdir | grep "d1" | awk '{print $1}')
1381         local parent_ino=$(ls -i -l -a | grep "\.\." | awk '{print $1}')
1382
1383         [ "$d0_ino" = "$parent_ino" ] ||
1384                 error ".. wrong, expect $d0_ino, get $parent_ino"
1385
1386         mv $DIR/$tdir/d0/striped_dir $DIR/$tdir/d1/ ||
1387                 error "mv striped dir failed"
1388
1389         parent_ino=$(ls -i -l -a | grep "\.\." | awk '{print $1}')
1390
1391         [ "$d1_ino" = "$parent_ino" ] ||
1392                 error ".. wrong after mv, expect $d1_ino, get $parent_ino"
1393 }
1394 run_test 24C "check .. in striped dir"
1395
1396 test_24E() {
1397         [[ $MDSCOUNT -lt 4 ]] && skip_env "needs >= 4 MDTs"
1398         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1399
1400         mkdir -p $DIR/$tdir
1401         mkdir $DIR/$tdir/src_dir
1402         $LFS mkdir -i 1 $DIR/$tdir/src_dir/src_child ||
1403                 error "create remote source failed"
1404
1405         touch $DIR/$tdir/src_dir/src_child/a
1406
1407         $LFS mkdir -i 2 $DIR/$tdir/tgt_dir ||
1408                 error "create remote target dir failed"
1409
1410         $LFS mkdir -i 3 $DIR/$tdir/tgt_dir/tgt_child ||
1411                 error "create remote target child failed"
1412
1413         mrename $DIR/$tdir/src_dir/src_child $DIR/$tdir/tgt_dir/tgt_child ||
1414                 error "rename dir cross MDT failed!"
1415
1416         find $DIR/$tdir
1417
1418         $CHECKSTAT -t dir $DIR/$tdir/src_dir/src_child &&
1419                 error "src_child still exists after rename"
1420
1421         $CHECKSTAT -t file $DIR/$tdir/tgt_dir/tgt_child/a ||
1422                 error "missing file(a) after rename"
1423
1424         rm -rf $DIR/$tdir || error "Can not delete directories"
1425 }
1426 run_test 24E "cross MDT rename/link"
1427
1428 test_24F () {
1429         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return 0
1430
1431         local repeats=1000
1432         [ "$SLOW" = "no" ] && repeats=100
1433
1434         mkdir -p $DIR/$tdir
1435
1436         echo "$repeats repeats"
1437         for ((i = 0; i < repeats; i++)); do
1438                 $LFS mkdir -i0 -c2 $DIR/$tdir/test || error "mkdir fails"
1439                 touch $DIR/$tdir/test/a || error "touch fails"
1440                 mkdir $DIR/$tdir/test/b || error "mkdir fails"
1441                 rm -rf $DIR/$tdir/test || error "rmdir fails"
1442         done
1443
1444         true
1445 }
1446 run_test 24F "hash order vs readdir (LU-11330)"
1447
1448 test_24G () {
1449         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
1450
1451         local ino1
1452         local ino2
1453
1454         $LFS mkdir -i 0 $DIR/$tdir-0 || error "mkdir $tdir-0"
1455         $LFS mkdir -i 1 $DIR/$tdir-1 || error "mkdir $tdir-1"
1456         touch $DIR/$tdir-0/f1 || error "touch f1"
1457         ln -s $DIR/$tdir-0/f1 $DIR/$tdir-0/s1 || error "ln s1"
1458         ino1=$(stat -c%i $DIR/$tdir-0/s1)
1459         mv $DIR/$tdir-0/s1 $DIR/$tdir-1 || error "mv s1"
1460         ino2=$(stat -c%i $DIR/$tdir-1/s1)
1461         [ $ino1 -ne $ino2 ] || error "s1 should be migrated"
1462 }
1463 run_test 24G "migrate symlink in rename"
1464
1465 test_25a() {
1466         echo '== symlink sanity ============================================='
1467
1468         test_mkdir $DIR/d25
1469         ln -s d25 $DIR/s25
1470         touch $DIR/s25/foo ||
1471                 error "File creation in symlinked directory failed"
1472 }
1473 run_test 25a "create file in symlinked directory ==============="
1474
1475 test_25b() {
1476         [ ! -d $DIR/d25 ] && test_25a
1477         $CHECKSTAT -t file $DIR/s25/foo || error "$DIR/s25/foo not file type"
1478 }
1479 run_test 25b "lookup file in symlinked directory ==============="
1480
1481 test_26a() {
1482         test_mkdir $DIR/d26
1483         test_mkdir $DIR/d26/d26-2
1484         ln -s d26/d26-2 $DIR/s26
1485         touch $DIR/s26/foo || error "File creation failed"
1486 }
1487 run_test 26a "multiple component symlink ======================="
1488
1489 test_26b() {
1490         test_mkdir -p $DIR/$tdir/d26-2
1491         ln -s $tdir/d26-2/foo $DIR/s26-2
1492         touch $DIR/s26-2 || error "File creation failed"
1493 }
1494 run_test 26b "multiple component symlink at end of lookup ======"
1495
1496 test_26c() {
1497         test_mkdir $DIR/d26.2
1498         touch $DIR/d26.2/foo
1499         ln -s d26.2 $DIR/s26.2-1
1500         ln -s s26.2-1 $DIR/s26.2-2
1501         ln -s s26.2-2 $DIR/s26.2-3
1502         chmod 0666 $DIR/s26.2-3/foo
1503 }
1504 run_test 26c "chain of symlinks"
1505
1506 # recursive symlinks (bug 439)
1507 test_26d() {
1508         ln -s d26-3/foo $DIR/d26-3
1509 }
1510 run_test 26d "create multiple component recursive symlink"
1511
1512 test_26e() {
1513         [ ! -h $DIR/d26-3 ] && test_26d
1514         rm $DIR/d26-3
1515 }
1516 run_test 26e "unlink multiple component recursive symlink"
1517
1518 # recursive symlinks (bug 7022)
1519 test_26f() {
1520         test_mkdir $DIR/$tdir
1521         test_mkdir $DIR/$tdir/$tfile
1522         cd $DIR/$tdir/$tfile           || error "cd $DIR/$tdir/$tfile failed"
1523         test_mkdir -p lndir/bar1
1524         test_mkdir $DIR/$tdir/$tfile/$tfile
1525         cd $tfile                || error "cd $tfile failed"
1526         ln -s .. dotdot          || error "ln dotdot failed"
1527         ln -s dotdot/lndir lndir || error "ln lndir failed"
1528         cd $DIR/$tdir                 || error "cd $DIR/$tdir failed"
1529         output=`ls $tfile/$tfile/lndir/bar1`
1530         [ "$output" = bar1 ] && error "unexpected output"
1531         rm -r $tfile             || error "rm $tfile failed"
1532         $CHECKSTAT -a $DIR/$tfile || error "$tfile not gone"
1533 }
1534 run_test 26f "rm -r of a directory which has recursive symlink"
1535
1536 test_27a() {
1537         test_mkdir $DIR/$tdir
1538         $LFS getstripe $DIR/$tdir
1539         $LFS setstripe -c 1 $DIR/$tdir/$tfile || error "setstripe failed"
1540         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "checkstat failed"
1541         cp /etc/hosts $DIR/$tdir/$tfile || error "Can't copy to one stripe file"
1542 }
1543 run_test 27a "one stripe file"
1544
1545 test_27b() {
1546         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1547
1548         test_mkdir $DIR/$tdir
1549         $LFS setstripe -c 2 $DIR/$tdir/$tfile || error "setstripe failed"
1550         $LFS getstripe -c $DIR/$tdir/$tfile
1551         [ $($LFS getstripe -c $DIR/$tdir/$tfile) -eq 2 ] ||
1552                 error "two-stripe file doesn't have two stripes"
1553
1554         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
1555 }
1556 run_test 27b "create and write to two stripe file"
1557
1558 # 27c family tests specific striping, setstripe -o
1559 test_27ca() {
1560         [[ $OSTCOUNT -lt 2 ]] && skip_env "skipping 2-stripe test"
1561         test_mkdir -p $DIR/$tdir
1562         local osts="1"
1563
1564         $LFS setstripe -o $osts $DIR/$tdir/$tfile  || error "setstripe failed"
1565         $LFS getstripe -i $DIR/$tdir/$tfile
1566         [ $($LFS getstripe -i $DIR/$tdir/$tfile ) -eq $osts ] ||
1567                 error "stripe not on specified OST"
1568
1569         dd if=/dev/zero of=$DIR/$tdir/$tfile  bs=1M count=4 || error "dd failed"
1570 }
1571 run_test 27ca "one stripe on specified OST"
1572
1573 test_27cb() {
1574         [[ $OSTCOUNT -lt 2 ]] && skip_env "skipping 2-stripe test"
1575         test_mkdir -p $DIR/$tdir
1576         local osts="1,0"
1577         $LFS setstripe -o $osts $DIR/$tdir/$tfile || error "setstripe failed"
1578         local getstripe=$($LFS getstripe $DIR/$tdir/$tfile)
1579         echo "$getstripe"
1580
1581         # Strip getstripe output to a space separated list of OSTs
1582         local getstripe_osts=$(echo "$getstripe" | sed -e '1,/obdidx/d' |\
1583                 awk '{print $1}' | tr '\n' '\ ' | sed -e 's/[[:space:]]*$//')
1584         [ "$getstripe_osts" = "${osts//,/ }" ] ||
1585                 error "stripes not on specified OSTs"
1586
1587         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 || error "dd failed"
1588 }
1589 run_test 27cb "two stripes on specified OSTs"
1590
1591 test_27cc() {
1592         [[ $OSTCOUNT -lt 2 ]] && skip_env "skipping 2-stripe test"
1593         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
1594                 skip "server does not support overstriping"
1595
1596         test_mkdir -p $DIR/$tdir
1597         local osts="0,0"
1598         $LFS setstripe -o $osts $DIR/$tdir/$tfile || error "setstripe failed"
1599         local getstripe=$($LFS getstripe $DIR/$tdir/$tfile)
1600         echo "$getstripe"
1601
1602         # Strip getstripe output to a space separated list of OSTs
1603         local getstripe_osts=$(echo "$getstripe" | sed -e '1,/obdidx/d' |\
1604                 awk '{print $1}' | tr '\n' '\ ' | sed -e 's/[[:space:]]*$//')
1605         [ "$getstripe_osts" = "${osts//,/ }" ] ||
1606                 error "stripes not on specified OSTs"
1607
1608         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 || error "dd failed"
1609 }
1610 run_test 27cc "two stripes on the same OST"
1611
1612 test_27cd() {
1613         [[ $OSTCOUNT -lt 2 ]] && skip_env "skipping 2-stripe test"
1614         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
1615                 skip "server does not support overstriping"
1616         test_mkdir -p $DIR/$tdir
1617         local osts="0,1,1,0"
1618         $LFS setstripe -o $osts $DIR/$tdir/$tfile || error "setstripe failed"
1619         local getstripe=$($LFS getstripe $DIR/$tdir/$tfile)
1620         echo "$getstripe"
1621
1622         # Strip getstripe output to a space separated list of OSTs
1623         local getstripe_osts=$(echo "$getstripe" | sed -e '1,/obdidx/d' |\
1624                 awk '{print $1}' | tr '\n' '\ ' | sed -e 's/[[:space:]]*$//')
1625         [ "$getstripe_osts" = "${osts//,/ }" ] ||
1626                 error "stripes not on specified OSTs"
1627
1628         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 || error "dd failed"
1629 }
1630 run_test 27cd "four stripes on two OSTs"
1631
1632 test_27ce() {
1633         [[ $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
1634                 skip_env "too many osts, skipping"
1635         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
1636                 skip "server does not support overstriping"
1637         # We do one more stripe than we have OSTs
1638         [ $OSTCOUNT -ge 159 ] || large_xattr_enabled ||
1639                 skip_env "ea_inode feature disabled"
1640
1641         test_mkdir -p $DIR/$tdir
1642         local osts=""
1643         for i in $(seq 0 $OSTCOUNT);
1644         do
1645                 osts=$osts"0"
1646                 if [ $i -ne $OSTCOUNT ]; then
1647                         osts=$osts","
1648                 fi
1649         done
1650         $LFS setstripe -o $osts $DIR/$tdir/$tfile || error "setstripe failed"
1651         local getstripe=$($LFS getstripe $DIR/$tdir/$tfile)
1652         echo "$getstripe"
1653
1654         # Strip getstripe output to a space separated list of OSTs
1655         local getstripe_osts=$(echo "$getstripe" | sed -e '1,/obdidx/d' |\
1656                 awk '{print $1}' | tr '\n' '\ ' | sed -e 's/[[:space:]]*$//')
1657         [ "$getstripe_osts" = "${osts//,/ }" ] ||
1658                 error "stripes not on specified OSTs"
1659
1660         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 || error "dd failed"
1661 }
1662 run_test 27ce "more stripes than OSTs with -o"
1663
1664 test_27cf() {
1665         local osp_proc="osp.$FSNAME-OST0000-osc-MDT000*.active"
1666         local pid=0
1667
1668         test_mkdir -p $DIR/$tdir || error "failed to mkdir $DIR/$tdir"
1669         do_facet $SINGLEMDS "$LCTL set_param -n $osp_proc=0"
1670         stack_trap "do_facet $SINGLEMDS $LCTL set_param -n $osp_proc=1" EXIT
1671         wait_update_facet $SINGLEMDS "$LCTL get_param -n $osp_proc | grep 1" ||
1672                 error "failed to set $osp_proc=0"
1673
1674         $LFS setstripe -o 0 $DIR/$tdir/$tfile &
1675         pid=$!
1676         sleep 1
1677         do_facet $SINGLEMDS "$LCTL set_param -n $osp_proc=1"
1678         wait_update_facet $SINGLEMDS "$LCTL get_param -n $osp_proc | grep 0" ||
1679                 error "failed to set $osp_proc=1"
1680         wait $pid
1681         [[ $pid -ne 0 ]] ||
1682                 error "should return error due to $osp_proc=0"
1683 }
1684 run_test 27cf "'setstripe -o' on inactive OSTs should return error"
1685
1686 test_27d() {
1687         test_mkdir $DIR/$tdir
1688         $LFS setstripe -c 0 -i -1 -S 0 $DIR/$tdir/$tfile ||
1689                 error "setstripe failed"
1690         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "checkstat failed"
1691         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
1692 }
1693 run_test 27d "create file with default settings"
1694
1695 test_27e() {
1696         # LU-5839 adds check for existed layout before setting it
1697         [[ $MDS1_VERSION -lt $(version_code 2.7.56) ]] &&
1698                 skip "Need MDS version at least 2.7.56"
1699
1700         test_mkdir $DIR/$tdir
1701         $LFS setstripe -c 2 $DIR/$tdir/$tfile || error "setstripe failed"
1702         $LFS setstripe -c 2 $DIR/$tdir/$tfile && error "setstripe worked twice"
1703         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "checkstat failed"
1704 }
1705 run_test 27e "setstripe existing file (should return error)"
1706
1707 test_27f() {
1708         test_mkdir $DIR/$tdir
1709         $LFS setstripe -S 100 -i 0 -c 1 $DIR/$tdir/$tfile &&
1710                 error "$LFS setstripe $DIR/$tdir/$tfile failed"
1711         $CHECKSTAT -t file $DIR/$tdir/$tfile &&
1712                 error "$CHECKSTAT -t file $DIR/$tdir/$tfile should fail"
1713         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
1714         $LFS getstripe $DIR/$tdir/$tfile || error "$LFS getstripe failed"
1715 }
1716 run_test 27f "setstripe with bad stripe size (should return error)"
1717
1718 test_27g() {
1719         test_mkdir $DIR/$tdir
1720         $MCREATE $DIR/$tdir/$tfile || error "mcreate failed"
1721         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "no stripe info" ||
1722                 error "$DIR/$tdir/$tfile has object"
1723 }
1724 run_test 27g "$LFS getstripe with no objects"
1725
1726 test_27ga() {
1727         test_mkdir $DIR/$tdir
1728         touch $DIR/$tdir/$tfile || error "touch failed"
1729         ln -s bogus $DIR/$tdir/$tfile.2 || error "ln failed"
1730         $LFS getstripe -m $DIR/$tdir/$tfile $DIR/$tdir/$tfile.2
1731         local rc=$?
1732         (( rc == 2 )) || error "getstripe did not return ENOENT"
1733 }
1734 run_test 27ga "$LFS getstripe with missing file (should return error)"
1735
1736 test_27i() {
1737         test_mkdir $DIR/$tdir
1738         touch $DIR/$tdir/$tfile || error "touch failed"
1739         [[ $($LFS getstripe -c $DIR/$tdir/$tfile) -gt 0 ]] ||
1740                 error "missing objects"
1741 }
1742 run_test 27i "$LFS getstripe with some objects"
1743
1744 test_27j() {
1745         test_mkdir $DIR/$tdir
1746         $LFS setstripe -i $OSTCOUNT $DIR/$tdir/$tfile &&
1747                 error "setstripe failed" || true
1748 }
1749 run_test 27j "setstripe with bad stripe offset (should return error)"
1750
1751 test_27k() { # bug 2844
1752         test_mkdir $DIR/$tdir
1753         local file=$DIR/$tdir/$tfile
1754         local ll_max_blksize=$((4 * 1024 * 1024))
1755         $LFS setstripe -S 67108864 $file || error "setstripe failed"
1756         local blksize=$(stat $file | awk '/IO Block:/ { print $7 }')
1757         [ $blksize -le $ll_max_blksize ] || error "1:$blksize > $ll_max_blksize"
1758         dd if=/dev/zero of=$file bs=4k count=1
1759         blksize=$(stat $file | awk '/IO Block:/ { print $7 }')
1760         [ $blksize -le $ll_max_blksize ] || error "2:$blksize > $ll_max_blksize"
1761 }
1762 run_test 27k "limit i_blksize for broken user apps"
1763
1764 test_27l() {
1765         mcreate $DIR/$tfile || error "creating file"
1766         $RUNAS $LFS setstripe -c 1 $DIR/$tfile &&
1767                 error "setstripe should have failed" || true
1768 }
1769 run_test 27l "check setstripe permissions (should return error)"
1770
1771 test_27m() {
1772         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1773
1774         [ -n "$RCLIENTS" -o -n "$MOUNT_2" ] &&
1775                 skip_env "multiple clients -- skipping"
1776
1777         ORIGFREE=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
1778                    head -n1)
1779         if [[ $ORIGFREE -gt $MAXFREE ]]; then
1780                 skip "$ORIGFREE > $MAXFREE skipping out-of-space test on OST0"
1781         fi
1782         trap simple_cleanup_common EXIT
1783         test_mkdir $DIR/$tdir
1784         $LFS setstripe -i 0 -c 1 $DIR/$tdir/$tfile.1
1785         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=1024 count=$MAXFREE &&
1786                 error "dd should fill OST0"
1787         i=2
1788         while $LFS setstripe -i 0 -c 1 $DIR/$tdir/$tfile.$i; do
1789                 i=$((i + 1))
1790                 [ $i -gt 256 ] && break
1791         done
1792         i=$((i + 1))
1793         touch $DIR/$tdir/$tfile.$i
1794         [ $($LFS getstripe $DIR/$tdir/$tfile.$i | grep -A 10 obdidx |
1795             awk '{print $1}'| grep -w "0") ] &&
1796                 error "OST0 was full but new created file still use it"
1797         i=$((i + 1))
1798         touch $DIR/$tdir/$tfile.$i
1799         [ $($LFS getstripe $DIR/$tdir/$tfile.$i | grep -A 10 obdidx |
1800             awk '{print $1}'| grep -w "0") ] &&
1801                 error "OST0 was full but new created file still use it"
1802         simple_cleanup_common
1803 }
1804 run_test 27m "create file while OST0 was full"
1805
1806 # OSCs keep a NOSPC flag that will be reset after ~5s (qos_maxage)
1807 # if the OST isn't full anymore.
1808 reset_enospc() {
1809         local ostidx=${1:-""}
1810         local delay
1811         local ready
1812         local get_prealloc
1813
1814         local list=$(comma_list $(osts_nodes))
1815         [ "$ostidx" ] && list=$(facet_host ost$((ostidx + 1)))
1816
1817         do_nodes $list lctl set_param fail_loc=0
1818         wait_delete_completed   # initiate all OST_DESTROYs from MDS to OST
1819         delay=$(do_facet $SINGLEMDS lctl get_param -n lov.*.qos_maxage |
1820                 awk '{print $1 * 2;exit;}')
1821         get_prealloc="$LCTL get_param -n osc.*MDT*.prealloc_status |
1822                         grep -v \"^0$\""
1823         wait_update_facet $SINGLEMDS "$get_prealloc" "" $delay
1824 }
1825
1826 __exhaust_precreations() {
1827         local OSTIDX=$1
1828         local FAILLOC=$2
1829         local FAILIDX=${3:-$OSTIDX}
1830         local ofacet=ost$((OSTIDX + 1))
1831
1832         test_mkdir -p -c1 $DIR/$tdir
1833         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
1834         local mfacet=mds$((mdtidx + 1))
1835         echo OSTIDX=$OSTIDX MDTIDX=$mdtidx
1836
1837         local OST=$(ostname_from_index $OSTIDX)
1838
1839         # on the mdt's osc
1840         local mdtosc_proc1=$(get_mdtosc_proc_path $mfacet $OST)
1841         local last_id=$(do_facet $mfacet lctl get_param -n \
1842                         osp.$mdtosc_proc1.prealloc_last_id)
1843         local next_id=$(do_facet $mfacet lctl get_param -n \
1844                         osp.$mdtosc_proc1.prealloc_next_id)
1845
1846         local mdtosc_proc2=$(get_mdtosc_proc_path $mfacet)
1847         do_facet $mfacet lctl get_param osp.$mdtosc_proc2.prealloc*
1848
1849         test_mkdir -p $DIR/$tdir/${OST}
1850         $LFS setstripe -i $OSTIDX -c 1 $DIR/$tdir/${OST}
1851 #define OBD_FAIL_OST_ENOSPC              0x215
1852         do_facet $ofacet lctl set_param fail_val=$FAILIDX fail_loc=0x215
1853         echo "Creating to objid $last_id on ost $OST..."
1854         createmany -o $DIR/$tdir/${OST}/f $next_id $((last_id - next_id + 2))
1855         do_facet $mfacet lctl get_param osp.$mdtosc_proc2.prealloc*
1856         do_facet $ofacet lctl set_param fail_loc=$FAILLOC
1857 }
1858
1859 exhaust_precreations() {
1860         __exhaust_precreations $1 $2 $3
1861         sleep_maxage
1862 }
1863
1864 exhaust_all_precreations() {
1865         local i
1866         for (( i=0; i < OSTCOUNT; i++ )) ; do
1867                 __exhaust_precreations $i $1 -1
1868         done
1869         sleep_maxage
1870 }
1871
1872 test_27n() {
1873         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1874         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1875         remote_mds_nodsh && skip "remote MDS with nodsh"
1876         remote_ost_nodsh && skip "remote OST with nodsh"
1877
1878         reset_enospc
1879         rm -f $DIR/$tdir/$tfile
1880         exhaust_precreations 0 0x80000215
1881         $LFS setstripe -c -1 $DIR/$tdir || error "setstripe failed"
1882         touch $DIR/$tdir/$tfile || error "touch failed"
1883         $LFS getstripe $DIR/$tdir/$tfile
1884         reset_enospc
1885 }
1886 run_test 27n "create file with some full OSTs"
1887
1888 test_27o() {
1889         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1890         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1891         remote_mds_nodsh && skip "remote MDS with nodsh"
1892         remote_ost_nodsh && skip "remote OST with nodsh"
1893
1894         reset_enospc
1895         rm -f $DIR/$tdir/$tfile
1896         exhaust_all_precreations 0x215
1897
1898         touch $DIR/$tdir/$tfile && error "able to create $DIR/$tdir/$tfile"
1899
1900         reset_enospc
1901         rm -rf $DIR/$tdir/*
1902 }
1903 run_test 27o "create file with all full OSTs (should error)"
1904
1905 test_27p() {
1906         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1907         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1908         remote_mds_nodsh && skip "remote MDS with nodsh"
1909         remote_ost_nodsh && skip "remote OST with nodsh"
1910
1911         reset_enospc
1912         rm -f $DIR/$tdir/$tfile
1913         test_mkdir $DIR/$tdir
1914
1915         $MCREATE $DIR/$tdir/$tfile || error "mcreate failed"
1916         $TRUNCATE $DIR/$tdir/$tfile 80000000 || error "truncate failed"
1917         $CHECKSTAT -s 80000000 $DIR/$tdir/$tfile || error "checkstat failed"
1918
1919         exhaust_precreations 0 0x80000215
1920         echo foo >> $DIR/$tdir/$tfile || error "append failed"
1921         $CHECKSTAT -s 80000004 $DIR/$tdir/$tfile || error "checkstat failed"
1922         $LFS getstripe $DIR/$tdir/$tfile
1923
1924         reset_enospc
1925 }
1926 run_test 27p "append to a truncated file with some full OSTs"
1927
1928 test_27q() {
1929         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1930         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1931         remote_mds_nodsh && skip "remote MDS with nodsh"
1932         remote_ost_nodsh && skip "remote OST with nodsh"
1933
1934         reset_enospc
1935         rm -f $DIR/$tdir/$tfile
1936
1937         test_mkdir $DIR/$tdir
1938         $MCREATE $DIR/$tdir/$tfile || error "mcreate $DIR/$tdir/$tfile failed"
1939         $TRUNCATE $DIR/$tdir/$tfile 80000000 ||
1940                 error "truncate $DIR/$tdir/$tfile failed"
1941         $CHECKSTAT -s 80000000 $DIR/$tdir/$tfile || error "checkstat failed"
1942
1943         exhaust_all_precreations 0x215
1944
1945         echo foo >> $DIR/$tdir/$tfile && error "append succeeded"
1946         $CHECKSTAT -s 80000000 $DIR/$tdir/$tfile || error "checkstat 2 failed"
1947
1948         reset_enospc
1949 }
1950 run_test 27q "append to truncated file with all OSTs full (should error)"
1951
1952 test_27r() {
1953         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1954         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1955         remote_mds_nodsh && skip "remote MDS with nodsh"
1956         remote_ost_nodsh && skip "remote OST with nodsh"
1957
1958         reset_enospc
1959         rm -f $DIR/$tdir/$tfile
1960         exhaust_precreations 0 0x80000215
1961
1962         $LFS setstripe -i 0 -c 2 $DIR/$tdir/$tfile || error "setstripe failed"
1963
1964         reset_enospc
1965 }
1966 run_test 27r "stripe file with some full OSTs (shouldn't LBUG) ="
1967
1968 test_27s() { # bug 10725
1969         test_mkdir $DIR/$tdir
1970         local stripe_size=$((4096 * 1024 * 1024))       # 2^32
1971         local stripe_count=0
1972         [ $OSTCOUNT -eq 1 ] || stripe_count=2
1973         $LFS setstripe -S $stripe_size -c $stripe_count $DIR/$tdir &&
1974                 error "stripe width >= 2^32 succeeded" || true
1975
1976 }
1977 run_test 27s "lsm_xfersize overflow (should error) (bug 10725)"
1978
1979 test_27t() { # bug 10864
1980         WDIR=$(pwd)
1981         WLFS=$(which lfs)
1982         cd $DIR
1983         touch $tfile
1984         $WLFS getstripe $tfile
1985         cd $WDIR
1986 }
1987 run_test 27t "check that utils parse path correctly"
1988
1989 test_27u() { # bug 4900
1990         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1991         remote_mds_nodsh && skip "remote MDS with nodsh"
1992
1993         local index
1994         local list=$(comma_list $(mdts_nodes))
1995
1996 #define OBD_FAIL_MDS_OSC_PRECREATE      0x139
1997         do_nodes $list $LCTL set_param fail_loc=0x139
1998         test_mkdir -p $DIR/$tdir
1999         trap simple_cleanup_common EXIT
2000         createmany -o $DIR/$tdir/t- 1000
2001         do_nodes $list $LCTL set_param fail_loc=0
2002
2003         TLOG=$TMP/$tfile.getstripe
2004         $LFS getstripe $DIR/$tdir > $TLOG
2005         OBJS=$(awk -vobj=0 '($1 == 0) { obj += 1 } END { print obj; }' $TLOG)
2006         unlinkmany $DIR/$tdir/t- 1000
2007         trap 0
2008         [[ $OBJS -gt 0 ]] &&
2009                 error "$OBJS objects created on OST-0. See $TLOG" ||
2010                 rm -f $TLOG
2011 }
2012 run_test 27u "skip object creation on OSC w/o objects"
2013
2014 test_27v() { # bug 4900
2015         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2016         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2017         remote_mds_nodsh && skip "remote MDS with nodsh"
2018         remote_ost_nodsh && skip "remote OST with nodsh"
2019
2020         exhaust_all_precreations 0x215
2021         reset_enospc
2022
2023         $LFS setstripe -c 1 $DIR/$tdir         # 1 stripe / file
2024
2025         touch $DIR/$tdir/$tfile
2026         #define OBD_FAIL_TGT_DELAY_PRECREATE     0x705
2027         # all except ost1
2028         for (( i=1; i < OSTCOUNT; i++ )); do
2029                 do_facet ost$i lctl set_param fail_loc=0x705
2030         done
2031         local START=`date +%s`
2032         createmany -o $DIR/$tdir/$tfile 32
2033
2034         local FINISH=`date +%s`
2035         local TIMEOUT=`lctl get_param -n timeout`
2036         local PROCESS=$((FINISH - START))
2037         [ $PROCESS -ge $((TIMEOUT / 2)) ] && \
2038                error "$FINISH - $START >= $TIMEOUT / 2"
2039         sleep $((TIMEOUT / 2 - PROCESS))
2040         reset_enospc
2041 }
2042 run_test 27v "skip object creation on slow OST"
2043
2044 test_27w() { # bug 10997
2045         test_mkdir $DIR/$tdir
2046         $LFS setstripe -S 65536 $DIR/$tdir/f0 || error "setstripe failed"
2047         [ $($LFS getstripe -S $DIR/$tdir/f0) -ne 65536 ] &&
2048                 error "stripe size $size != 65536" || true
2049         [ $($LFS getstripe -d $DIR/$tdir | grep -c "stripe_count") -eq 0 ] &&
2050                 error "$LFS getstripe -d $DIR/$tdir no 'stripe_count'" || true
2051 }
2052 run_test 27w "check $LFS setstripe -S and getstrip -d options"
2053
2054 test_27wa() {
2055         [[ $OSTCOUNT -lt 2 ]] &&
2056                 skip_env "skipping multiple stripe count/offset test"
2057
2058         test_mkdir $DIR/$tdir
2059         for i in $(seq 1 $OSTCOUNT); do
2060                 offset=$((i - 1))
2061                 $LFS setstripe -c $i -i $offset $DIR/$tdir/f$i ||
2062                         error "setstripe -c $i -i $offset failed"
2063                 count=$($LFS getstripe -c $DIR/$tdir/f$i)
2064                 index=$($LFS getstripe -i $DIR/$tdir/f$i)
2065                 [ $count -ne $i ] && error "stripe count $count != $i" || true
2066                 [ $index -ne $offset ] &&
2067                         error "stripe offset $index != $offset" || true
2068         done
2069 }
2070 run_test 27wa "check $LFS setstripe -c -i options"
2071
2072 test_27x() {
2073         remote_ost_nodsh && skip "remote OST with nodsh"
2074         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2075         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2076
2077         OFFSET=$(($OSTCOUNT - 1))
2078         OSTIDX=0
2079         local OST=$(ostname_from_index $OSTIDX)
2080
2081         test_mkdir $DIR/$tdir
2082         $LFS setstripe -c 1 $DIR/$tdir  # 1 stripe per file
2083         do_facet ost$((OSTIDX + 1)) lctl set_param -n obdfilter.$OST.degraded 1
2084         sleep_maxage
2085         createmany -o $DIR/$tdir/$tfile $OSTCOUNT
2086         for i in $(seq 0 $OFFSET); do
2087                 [ $($LFS getstripe $DIR/$tdir/$tfile$i | grep -A 10 obdidx |
2088                         awk '{print $1}' | grep -w "$OSTIDX") ] &&
2089                 error "OST0 was degraded but new created file still use it"
2090         done
2091         do_facet ost$((OSTIDX + 1)) lctl set_param -n obdfilter.$OST.degraded 0
2092 }
2093 run_test 27x "create files while OST0 is degraded"
2094
2095 test_27y() {
2096         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2097         remote_mds_nodsh && skip "remote MDS with nodsh"
2098         remote_ost_nodsh && skip "remote OST with nodsh"
2099         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2100
2101         local mdtosc=$(get_mdtosc_proc_path $SINGLEMDS $FSNAME-OST0000)
2102         local last_id=$(do_facet $SINGLEMDS lctl get_param -n \
2103                 osp.$mdtosc.prealloc_last_id)
2104         local next_id=$(do_facet $SINGLEMDS lctl get_param -n \
2105                 osp.$mdtosc.prealloc_next_id)
2106         local fcount=$((last_id - next_id))
2107         [[ $fcount -eq 0 ]] && skip "not enough space on OST0"
2108         [[ $fcount -gt $OSTCOUNT ]] && fcount=$OSTCOUNT
2109
2110         local MDS_OSCS=$(do_facet $SINGLEMDS lctl dl |
2111                          awk '/[oO][sS][cC].*md[ts]/ { print $4 }')
2112         local OST_DEACTIVE_IDX=-1
2113         local OSC
2114         local OSTIDX
2115         local OST
2116
2117         for OSC in $MDS_OSCS; do
2118                 OST=$(osc_to_ost $OSC)
2119                 OSTIDX=$(index_from_ostuuid $OST)
2120                 if [ $OST_DEACTIVE_IDX == -1 ]; then
2121                         OST_DEACTIVE_IDX=$OSTIDX
2122                 fi
2123                 if [ $OSTIDX != $OST_DEACTIVE_IDX ]; then
2124                         echo $OSC "is Deactivated:"
2125                         do_facet $SINGLEMDS lctl --device  %$OSC deactivate
2126                 fi
2127         done
2128
2129         OSTIDX=$(index_from_ostuuid $OST)
2130         test_mkdir $DIR/$tdir
2131         $LFS setstripe -c 1 $DIR/$tdir      # 1 stripe / file
2132
2133         for OSC in $MDS_OSCS; do
2134                 OST=$(osc_to_ost $OSC)
2135                 OSTIDX=$(index_from_ostuuid $OST)
2136                 if [ $OSTIDX == $OST_DEACTIVE_IDX ]; then
2137                         echo $OST "is degraded:"
2138                         do_facet ost$((OSTIDX+1)) lctl set_param -n \
2139                                                 obdfilter.$OST.degraded=1
2140                 fi
2141         done
2142
2143         sleep_maxage
2144         createmany -o $DIR/$tdir/$tfile $fcount
2145
2146         for OSC in $MDS_OSCS; do
2147                 OST=$(osc_to_ost $OSC)
2148                 OSTIDX=$(index_from_ostuuid $OST)
2149                 if [ $OSTIDX == $OST_DEACTIVE_IDX ]; then
2150                         echo $OST "is recovered from degraded:"
2151                         do_facet ost$((OSTIDX+1)) lctl set_param -n \
2152                                                 obdfilter.$OST.degraded=0
2153                 else
2154                         do_facet $SINGLEMDS lctl --device %$OSC activate
2155                 fi
2156         done
2157
2158         # all osp devices get activated, hence -1 stripe count restored
2159         local stripe_count=0
2160
2161         # sleep 2*lod_qos_maxage seconds waiting for lod qos to notice osp
2162         # devices get activated.
2163         sleep_maxage
2164         $LFS setstripe -c -1 $DIR/$tfile
2165         stripe_count=$($LFS getstripe -c $DIR/$tfile)
2166         rm -f $DIR/$tfile
2167         [ $stripe_count -ne $OSTCOUNT ] &&
2168                 error "Of $OSTCOUNT OSTs, only $stripe_count is available"
2169         return 0
2170 }
2171 run_test 27y "create files while OST0 is degraded and the rest inactive"
2172
2173 check_seq_oid()
2174 {
2175         log "check file $1"
2176
2177         lmm_count=$($LFS getstripe -c $1)
2178         lmm_seq=$($LFS getstripe -v $1 | awk '/lmm_seq/ { print $2 }')
2179         lmm_oid=$($LFS getstripe -v $1 | awk '/lmm_object_id/ { print $2 }')
2180
2181         local old_ifs="$IFS"
2182         IFS=$'[:]'
2183         fid=($($LFS path2fid $1))
2184         IFS="$old_ifs"
2185
2186         log "FID seq ${fid[1]}, oid ${fid[2]} ver ${fid[3]}"
2187         log "LOV seq $lmm_seq, oid $lmm_oid, count: $lmm_count"
2188
2189         # compare lmm_seq and lu_fid->f_seq
2190         [ $lmm_seq = ${fid[1]} ] || { error "SEQ mismatch"; return 1; }
2191         # compare lmm_object_id and lu_fid->oid
2192         [ $lmm_oid = ${fid[2]} ] || { error "OID mismatch"; return 2; }
2193
2194         # check the trusted.fid attribute of the OST objects of the file
2195         local have_obdidx=false
2196         local stripe_nr=0
2197         $LFS getstripe $1 | while read obdidx oid hex seq; do
2198                 # skip lines up to and including "obdidx"
2199                 [ -z "$obdidx" ] && break
2200                 [ "$obdidx" = "obdidx" ] && have_obdidx=true && continue
2201                 $have_obdidx || continue
2202
2203                 local ost=$((obdidx + 1))
2204                 local dev=$(ostdevname $ost)
2205                 local oid_hex
2206
2207                 log "want: stripe:$stripe_nr ost:$obdidx oid:$oid/$hex seq:$seq"
2208
2209                 seq=$(echo $seq | sed -e "s/^0x//g")
2210                 if [ $seq == 0 ] || [ $(facet_fstype ost$ost) == zfs ]; then
2211                         oid_hex=$(echo $oid)
2212                 else
2213                         oid_hex=$(echo $hex | sed -e "s/^0x//g")
2214                 fi
2215                 local obj_file="O/$seq/d$((oid %32))/$oid_hex"
2216
2217                 local ff=""
2218                 #
2219                 # Don't unmount/remount the OSTs if we don't need to do that.
2220                 # LU-2577 changes filter_fid to be smaller, so debugfs needs
2221                 # update too, until that use mount/ll_decode_filter_fid/mount.
2222                 # Re-enable when debugfs will understand new filter_fid.
2223                 #
2224                 if [ $(facet_fstype ost$ost) == ldiskfs ]; then
2225                         ff=$(do_facet ost$ost "$DEBUGFS -c -R 'stat $obj_file' \
2226                                 $dev 2>/dev/null" | grep "parent=")
2227                 fi
2228                 if [ -z "$ff" ]; then
2229                         stop ost$ost
2230                         mount_fstype ost$ost
2231                         ff=$(do_facet ost$ost $LL_DECODE_FILTER_FID \
2232                                 $(facet_mntpt ost$ost)/$obj_file)
2233                         unmount_fstype ost$ost
2234                         start ost$ost $dev $OST_MOUNT_OPTS
2235                         clients_up
2236                 fi
2237
2238                 [ -z "$ff" ] && error "$obj_file: no filter_fid info"
2239
2240                 echo "$ff" | sed -e 's#.*objid=#got: objid=#'
2241
2242                 # /mnt/O/0/d23/23: objid=23 seq=0 parent=[0x200000400:0x1e:0x1]
2243                 # fid: objid=23 seq=0 parent=[0x200000400:0x1e:0x0] stripe=1
2244                 #
2245                 # fid: parent=[0x200000400:0x1e:0x0] stripe=1 stripe_count=2 \
2246                 #       stripe_size=1048576 component_id=1 component_start=0 \
2247                 #       component_end=33554432
2248                 local ff_parent=$(sed -e 's/.*parent=.//' <<<$ff)
2249                 local ff_pseq=$(cut -d: -f1 <<<$ff_parent)
2250                 local ff_poid=$(cut -d: -f2 <<<$ff_parent)
2251                 local ff_pstripe
2252                 if grep -q 'stripe=' <<<$ff; then
2253                         ff_pstripe=$(sed -e 's/.*stripe=//' -e 's/ .*//' <<<$ff)
2254                 else
2255                         # $LL_DECODE_FILTER_FID does not print "stripe="; look
2256                         # into f_ver in this case.  See comment on ff_parent.
2257                         ff_pstripe=$(cut -d: -f3 <<<$ff_parent | sed -e 's/]//')
2258                 fi
2259
2260                 # compare lmm_seq and filter_fid->ff_parent.f_seq
2261                 [ $ff_pseq = $lmm_seq ] ||
2262                         error "FF parent SEQ $ff_pseq != $lmm_seq"
2263                 # compare lmm_object_id and filter_fid->ff_parent.f_oid
2264                 [ $ff_poid = $lmm_oid ] ||
2265                         error "FF parent OID $ff_poid != $lmm_oid"
2266                 (($ff_pstripe == $stripe_nr)) ||
2267                         error "FF stripe $ff_pstripe != $stripe_nr"
2268
2269                 stripe_nr=$((stripe_nr + 1))
2270                 [ $CLIENT_VERSION -lt $(version_code 2.9.55) ] &&
2271                         continue
2272                 if grep -q 'stripe_count=' <<<$ff; then
2273                         local ff_scnt=$(sed -e 's/.*stripe_count=//' \
2274                                             -e 's/ .*//' <<<$ff)
2275                         [ $lmm_count = $ff_scnt ] ||
2276                                 error "FF stripe count $lmm_count != $ff_scnt"
2277                 fi
2278         done
2279 }
2280
2281 test_27z() {
2282         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2283         remote_ost_nodsh && skip "remote OST with nodsh"
2284
2285         test_mkdir $DIR/$tdir
2286         $LFS setstripe -c 1 -i 0 -S 64k $DIR/$tdir/$tfile-1 ||
2287                 { error "setstripe -c -1 failed"; return 1; }
2288         # We need to send a write to every object to get parent FID info set.
2289         # This _should_ also work for setattr, but does not currently.
2290         # touch $DIR/$tdir/$tfile-1 ||
2291         dd if=/dev/zero of=$DIR/$tdir/$tfile-1 bs=1M count=1 ||
2292                 { error "dd $tfile-1 failed"; return 2; }
2293         $LFS setstripe -c -1 -i $((OSTCOUNT - 1)) -S 1M $DIR/$tdir/$tfile-2 ||
2294                 { error "setstripe -c -1 failed"; return 3; }
2295         dd if=/dev/zero of=$DIR/$tdir/$tfile-2 bs=1M count=$OSTCOUNT ||
2296                 { error "dd $tfile-2 failed"; return 4; }
2297
2298         # make sure write RPCs have been sent to OSTs
2299         sync; sleep 5; sync
2300
2301         check_seq_oid $DIR/$tdir/$tfile-1 || return 5
2302         check_seq_oid $DIR/$tdir/$tfile-2 || return 6
2303 }
2304 run_test 27z "check SEQ/OID on the MDT and OST filesystems"
2305
2306 test_27A() { # b=19102
2307         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2308
2309         save_layout_restore_at_exit $MOUNT
2310         $LFS setstripe -c 0 -i -1 -S 0 $MOUNT
2311         wait_update $HOSTNAME "$LFS getstripe -c $MOUNT | sed 's/  *//g'" "1" 20 ||
2312                 error "stripe count $($LFS getstripe -c $MOUNT) != 1"
2313         local default_size=$($LFS getstripe -S $MOUNT)
2314         local default_offset=$($LFS getstripe -i $MOUNT)
2315         local dsize=$(do_facet $SINGLEMDS \
2316                 "$LCTL get_param -n lod.$(facet_svc $SINGLEMDS)*.stripesize")
2317         [ $default_size -eq $dsize ] ||
2318                 error "stripe size $default_size != $dsize"
2319         [ $default_offset -eq -1 ] ||
2320                 error "stripe offset $default_offset != -1"
2321 }
2322 run_test 27A "check filesystem-wide default LOV EA values"
2323
2324 test_27B() { # LU-2523
2325         test_mkdir $DIR/$tdir
2326         rm -f $DIR/$tdir/f0 $DIR/$tdir/f1
2327         touch $DIR/$tdir/f0
2328         # open f1 with O_LOV_DELAY_CREATE
2329         # rename f0 onto f1
2330         # call setstripe ioctl on open file descriptor for f1
2331         # close
2332         multiop $DIR/$tdir/f1 oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:nB1c \
2333                 $DIR/$tdir/f0
2334
2335         rm -f $DIR/$tdir/f1
2336         # open f1 with O_LOV_DELAY_CREATE
2337         # unlink f1
2338         # call setstripe ioctl on open file descriptor for f1
2339         # close
2340         multiop $DIR/$tdir/f1 oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:uB1c
2341
2342         # Allow multiop to fail in imitation of NFS's busted semantics.
2343         true
2344 }
2345 run_test 27B "call setstripe on open unlinked file/rename victim"
2346
2347 # 27C family tests full striping and overstriping
2348 test_27Ca() { #LU-2871
2349         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2350
2351         declare -a ost_idx
2352         local index
2353         local found
2354         local i
2355         local j
2356
2357         test_mkdir $DIR/$tdir
2358         cd $DIR/$tdir
2359         for i in $(seq 0 $((OSTCOUNT - 1))); do
2360                 # set stripe across all OSTs starting from OST$i
2361                 $LFS setstripe -i $i -c -1 $tfile$i
2362                 # get striping information
2363                 ost_idx=($($LFS getstripe $tfile$i |
2364                          tail -n $((OSTCOUNT + 1)) | awk '{print $1}'))
2365                 echo ${ost_idx[@]}
2366
2367                 # check the layout
2368                 [ ${#ost_idx[@]} -eq $OSTCOUNT ] ||
2369                         error "${#ost_idx[@]} != $OSTCOUNT"
2370
2371                 for index in $(seq 0 $((OSTCOUNT - 1))); do
2372                         found=0
2373                         for j in $(echo ${ost_idx[@]}); do
2374                                 if [ $index -eq $j ]; then
2375                                         found=1
2376                                         break
2377                                 fi
2378                         done
2379                         [ $found = 1 ] ||
2380                                 error "Can not find $index in ${ost_idx[@]}"
2381                 done
2382         done
2383 }
2384 run_test 27Ca "check full striping across all OSTs"
2385
2386 test_27Cb() {
2387         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2388                 skip "server does not support overstriping"
2389         [[ $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
2390                 skip_env "too many osts, skipping"
2391
2392         test_mkdir -p $DIR/$tdir
2393         local setcount=$(($OSTCOUNT * 2))
2394         [ $setcount -ge 160 ] || large_xattr_enabled ||
2395                 skip_env "ea_inode feature disabled"
2396
2397         $LFS setstripe -C $setcount $DIR/$tdir/$tfile ||
2398                 error "setstripe failed"
2399
2400         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2401         [ $count -eq $setcount ] ||
2402                 error "stripe count $count, should be $setcount"
2403
2404         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" ||
2405                 error "overstriped should be set in pattern"
2406
2407         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2408                 error "dd failed"
2409 }
2410 run_test 27Cb "more stripes than OSTs with -C"
2411
2412 test_27Cc() {
2413         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2414                 skip "server does not support overstriping"
2415         [[ $OSTCOUNT -lt 2 ]] && skip_env "need > 1 OST"
2416
2417         test_mkdir -p $DIR/$tdir
2418         local setcount=$(($OSTCOUNT - 1))
2419
2420         [ $setcount -ge 160 ] || large_xattr_enabled ||
2421                 skip_env "ea_inode feature disabled"
2422
2423         $LFS setstripe -C $setcount $DIR/$tdir/$tfile ||
2424                 error "setstripe failed"
2425
2426         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2427         [ $count -eq $setcount ] ||
2428                 error "stripe count $count, should be $setcount"
2429
2430         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" &&
2431                 error "overstriped should not be set in pattern"
2432
2433         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2434                 error "dd failed"
2435 }
2436 run_test 27Cc "fewer stripes than OSTs does not set overstriping"
2437
2438 test_27Cd() {
2439         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2440                 skip "server does not support overstriping"
2441         [[ $OSTCOUNT -lt 2 ]] && skip_env "need > 1 OST"
2442         large_xattr_enabled || skip_env "ea_inode feature disabled"
2443
2444         test_mkdir -p $DIR/$tdir
2445         local setcount=$LOV_MAX_STRIPE_COUNT
2446
2447         $LFS setstripe -C $setcount $DIR/$tdir/$tfile ||
2448                 error "setstripe failed"
2449
2450         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2451         [ $count -eq $setcount ] ||
2452                 error "stripe count $count, should be $setcount"
2453
2454         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" ||
2455                 error "overstriped should be set in pattern"
2456
2457         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2458                 error "dd failed"
2459
2460         rm -f $DIR/$tdir/$tfile || error "Delete $tfile failed"
2461 }
2462 run_test 27Cd "test maximum stripe count"
2463
2464 test_27Ce() {
2465         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2466                 skip "server does not support overstriping"
2467         test_mkdir -p $DIR/$tdir
2468
2469         pool_add $TESTNAME || error "Pool creation failed"
2470         pool_add_targets $TESTNAME 0 || error "pool_add_targets failed"
2471
2472         local setcount=8
2473
2474         $LFS setstripe  -C $setcount -p "$TESTNAME" $DIR/$tdir/$tfile ||
2475                 error "setstripe failed"
2476
2477         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2478         [ $count -eq $setcount ] ||
2479                 error "stripe count $count, should be $setcount"
2480
2481         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" ||
2482                 error "overstriped should be set in pattern"
2483
2484         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2485                 error "dd failed"
2486
2487         rm -f $DIR/$tdir/$tfile || error "Delete $tfile failed"
2488 }
2489 run_test 27Ce "test pool with overstriping"
2490
2491 test_27Cf() {
2492         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2493                 skip "server does not support overstriping"
2494         [[ $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
2495                 skip_env "too many osts, skipping"
2496
2497         test_mkdir -p $DIR/$tdir
2498
2499         local setcount=$(($OSTCOUNT * 2))
2500         [ $setcount -ge 160 ] || large_xattr_enabled ||
2501                 skip_env "ea_inode feature disabled"
2502
2503         $LFS setstripe  -C $setcount $DIR/$tdir/ ||
2504                 error "setstripe failed"
2505
2506         echo 1 > $DIR/$tdir/$tfile
2507
2508         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2509         [ $count -eq $setcount ] ||
2510                 error "stripe count $count, should be $setcount"
2511
2512         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" ||
2513                 error "overstriped should be set in pattern"
2514
2515         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2516                 error "dd failed"
2517
2518         rm -f $DIR/$tdir/$tfile || error "Delete $tfile failed"
2519 }
2520 run_test 27Cf "test default inheritance with overstriping"
2521
2522 test_27D() {
2523         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
2524         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
2525         remote_mds_nodsh && skip "remote MDS with nodsh"
2526
2527         local POOL=${POOL:-testpool}
2528         local first_ost=0
2529         local last_ost=$(($OSTCOUNT - 1))
2530         local ost_step=1
2531         local ost_list=$(seq $first_ost $ost_step $last_ost)
2532         local ost_range="$first_ost $last_ost $ost_step"
2533
2534         test_mkdir $DIR/$tdir
2535         pool_add $POOL || error "pool_add failed"
2536         pool_add_targets $POOL $ost_range || error "pool_add_targets failed"
2537
2538         local skip27D
2539         [ $MDS1_VERSION -lt $(version_code 2.8.55) ] &&
2540                 skip27D+="-s 29"
2541         [ $MDS1_VERSION -lt $(version_code 2.9.55) ] ||
2542                 [ $CLIENT_VERSION -lt $(version_code 2.9.55) ] &&
2543                         skip27D+=" -s 30,31"
2544         [[ ! $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ||
2545           $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
2546                 skip27D+=" -s 32,33"
2547         [[ $MDS_VERSION -lt $(version_code $SEL_VER) ]] &&
2548                 skip27D+=" -s 34"
2549         llapi_layout_test -d$DIR/$tdir -p$POOL -o$OSTCOUNT $skip27D ||
2550                 error "llapi_layout_test failed"
2551
2552         destroy_test_pools || error "destroy test pools failed"
2553 }
2554 run_test 27D "validate llapi_layout API"
2555
2556 # Verify that default_easize is increased from its initial value after
2557 # accessing a widely striped file.
2558 test_27E() {
2559         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
2560         [ $CLIENT_VERSION -lt $(version_code 2.5.57) ] &&
2561                 skip "client does not have LU-3338 fix"
2562
2563         # 72 bytes is the minimum space required to store striping
2564         # information for a file striped across one OST:
2565         # (sizeof(struct lov_user_md_v3) +
2566         #  sizeof(struct lov_user_ost_data_v1))
2567         local min_easize=72
2568         $LCTL set_param -n llite.*.default_easize $min_easize ||
2569                 error "lctl set_param failed"
2570         local easize=$($LCTL get_param -n llite.*.default_easize)
2571
2572         [ $easize -eq $min_easize ] ||
2573                 error "failed to set default_easize"
2574
2575         $LFS setstripe -c $OSTCOUNT $DIR/$tfile ||
2576                 error "setstripe failed"
2577         # In order to ensure stat() call actually talks to MDS we need to
2578         # do something drastic to this file to shake off all lock, e.g.
2579         # rename it (kills lookup lock forcing cache cleaning)
2580         mv $DIR/$tfile $DIR/${tfile}-1
2581         ls -l $DIR/${tfile}-1
2582         rm $DIR/${tfile}-1
2583
2584         easize=$($LCTL get_param -n llite.*.default_easize)
2585
2586         [ $easize -gt $min_easize ] ||
2587                 error "default_easize not updated"
2588 }
2589 run_test 27E "check that default extended attribute size properly increases"
2590
2591 test_27F() { # LU-5346/LU-7975
2592         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2593         [[ $OSTCOUNT -lt 2 ]] && skip "needs >= 2 OSTs"
2594         [[ $MDS1_VERSION -lt $(version_code 2.8.51) ]] &&
2595                 skip "Need MDS version at least 2.8.51"
2596         remote_ost_nodsh && skip "remote OST with nodsh"
2597
2598         test_mkdir $DIR/$tdir
2599         rm -f $DIR/$tdir/f0
2600         $LFS setstripe -c 2 $DIR/$tdir
2601
2602         # stop all OSTs to reproduce situation for LU-7975 ticket
2603         for num in $(seq $OSTCOUNT); do
2604                 stop ost$num
2605         done
2606
2607         # open/create f0 with O_LOV_DELAY_CREATE
2608         # truncate f0 to a non-0 size
2609         # close
2610         multiop $DIR/$tdir/f0 oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:T1050000c
2611
2612         $CHECKSTAT -s 1050000 $DIR/$tdir/f0 || error "checkstat failed"
2613         # open/write it again to force delayed layout creation
2614         cat /etc/hosts > $DIR/$tdir/f0 &
2615         catpid=$!
2616
2617         # restart OSTs
2618         for num in $(seq $OSTCOUNT); do
2619                 start ost$num $(ostdevname $num) $OST_MOUNT_OPTS ||
2620                         error "ost$num failed to start"
2621         done
2622
2623         wait $catpid || error "cat failed"
2624
2625         cmp /etc/hosts $DIR/$tdir/f0 || error "cmp failed"
2626         [[ $($LFS getstripe -c $DIR/$tdir/f0) == 2 ]] ||
2627                 error "wrong stripecount"
2628
2629 }
2630 run_test 27F "Client resend delayed layout creation with non-zero size"
2631
2632 test_27G() { #LU-10629
2633         [ $MDS1_VERSION -lt $(version_code 2.11.51) ] &&
2634                 skip "Need MDS version at least 2.11.51"
2635         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
2636         remote_mds_nodsh && skip "remote MDS with nodsh"
2637         local POOL=${POOL:-testpool}
2638         local ostrange="0 0 1"
2639
2640         test_mkdir $DIR/$tdir
2641         touch $DIR/$tdir/$tfile.nopool
2642         pool_add $POOL || error "pool_add failed"
2643         pool_add_targets $POOL $ostrange || error "pool_add_targets failed"
2644         $LFS setstripe -p $POOL $DIR/$tdir
2645
2646         local pool=$($LFS getstripe -p $DIR/$tdir)
2647
2648         [ "$pool" = "$POOL" ] || error "Striping failed got '$pool' not '$POOL'"
2649         touch $DIR/$tdir/$tfile.default
2650         $LFS setstripe -E 1M --pool $POOL -c 1 -E eof -c 1 $DIR/$tdir/$tfile.pfl
2651         $LFS find $DIR/$tdir -type f --pool $POOL
2652         local found=$($LFS find $DIR/$tdir -type f --pool $POOL | wc -l)
2653         [[ "$found" == "2" ]] ||
2654                 error "found $found != 2 files in '$DIR/$tdir' in '$POOL'"
2655
2656         $LFS setstripe -d $DIR/$tdir
2657
2658         pool=$($LFS getstripe -p -d $DIR/$tdir)
2659
2660         [[ "$pool" != "$POOL" ]] || error "$DIR/$tdir is still '$pool'"
2661 }
2662 run_test 27G "Clear OST pool from stripe"
2663
2664 test_27H() {
2665         [[ $MDS1_VERSION -le $(version_code 2.11.54) ]] &&
2666                 skip "Need MDS version newer than 2.11.54"
2667         [[ $OSTCOUNT -lt 3 ]] && skip_env "needs >= 3 OSTs"
2668         test_mkdir $DIR/$tdir
2669         $LFS setstripe -o 0 -o 2 $DIR/$tdir || error "setstripe failed"
2670         touch $DIR/$tdir/$tfile
2671         $LFS getstripe -c $DIR/$tdir/$tfile
2672         [ $($LFS getstripe -c $DIR/$tdir/$tfile) -eq 2 ] ||
2673                 error "two-stripe file doesn't have two stripes"
2674
2675         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
2676         $LFS getstripe -y $DIR/$tdir/$tfile
2677         (( $($LFS getstripe -y $DIR/$tdir/$tfile |
2678              egrep -c "l_ost_idx: [02]$") == "2" )) ||
2679                 error "expected l_ost_idx: [02]$ not matched"
2680
2681         # make sure ost list has been cleared
2682         local stripesize=$($LFS getstripe -S $DIR/$tdir)
2683         $LFS setstripe -S $((stripesize * 4)) -i 1 \
2684                 -c $((OSTCOUNT - 1)) $DIR/$tdir || error "setstripe"
2685         touch $DIR/$tdir/f3
2686         $LVERIFY $DIR/$tdir $DIR/$tdir/f3 || error "lverify failed"
2687 }
2688 run_test 27H "Set specific OSTs stripe"
2689
2690 test_27I() {
2691         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2692         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2693         [[ $MDS1_VERSION -gt $(version_code 2.12.52) ]] ||
2694                 skip "Need MDS version newer than 2.12.52"
2695         local pool=$TESTNAME
2696         local ostrange="1 1 1"
2697
2698         save_layout_restore_at_exit $MOUNT
2699         $LFS setstripe -c 2 -i 0 $MOUNT
2700         pool_add $pool || error "pool_add failed"
2701         pool_add_targets $pool $ostrange || "pool_add_targets failed"
2702         test_mkdir $DIR/$tdir
2703         $LFS setstripe -p $pool $DIR/$tdir
2704         $MULTIOP $DIR/$tdir/$tfile Oc || error "multiop failed"
2705         $LFS getstripe $DIR/$tdir/$tfile
2706 }
2707 run_test 27I "check that root dir striping does not break parent dir one"
2708
2709 test_27J() {
2710         [[ $MDS1_VERSION -le $(version_code 2.12.51) ]] &&
2711                 skip "Need MDS version newer than 2.12.51"
2712
2713         test_mkdir $DIR/$tdir
2714         local uuid1=$(cat /proc/sys/kernel/random/uuid)
2715         local uuid2=$(cat /proc/sys/kernel/random/uuid)
2716
2717         # create foreign file (raw way)
2718         create_foreign_file -f $DIR/$tdir/$tfile -x "${uuid1}@${uuid2}" \
2719                 -t 1 -F 0xda08 || error "create_foreign_file failed"
2720
2721         # verify foreign file (raw way)
2722         parse_foreign_file -f $DIR/$tdir/$tfile |
2723                 grep "lov_foreign_magic: 0x0BD70BD0" ||
2724                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign magic"
2725         parse_foreign_file -f $DIR/$tdir/$tfile | grep "lov_xattr_size: 89" ||
2726                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign size"
2727         parse_foreign_file -f $DIR/$tdir/$tfile |
2728                 grep "lov_foreign_size: 73" ||
2729                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign size"
2730         parse_foreign_file -f $DIR/$tdir/$tfile |
2731                 grep "lov_foreign_type: 1" ||
2732                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign type"
2733         parse_foreign_file -f $DIR/$tdir/$tfile |
2734                 grep "lov_foreign_flags: 0x0000DA08" ||
2735                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign flags"
2736         local lov=$(parse_foreign_file -f $DIR/$tdir/$tfile |
2737                 grep "lov_foreign_value: 0x" |
2738                 sed -e 's/lov_foreign_value: 0x//')
2739         local lov2=$(echo -n "${uuid1}@${uuid2}" | od -A n -t x1 -w160)
2740         [[ $lov = ${lov2// /} ]] ||
2741                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign value"
2742
2743         # create foreign file (lfs + API)
2744         $LFS setstripe --foreign=daos --flags 0xda08 \
2745                 -x "${uuid1}@${uuid2}" $DIR/$tdir/${tfile}2 ||
2746                 error "$DIR/$tdir/${tfile}2: create failed"
2747
2748         $LFS getstripe -v $DIR/$tdir/${tfile}2 |
2749                 grep "lfm_magic:.*0x0BD70BD0" ||
2750                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign magic"
2751         # lfm_length is LOV EA size - sizeof(lfm_magic) - sizeof(lfm_length)
2752         $LFS getstripe -v $DIR/$tdir/${tfile}2 | grep "lfm_length:.*73" ||
2753                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign size"
2754         $LFS getstripe -v $DIR/$tdir/${tfile}2 | grep "lfm_type:.*daos" ||
2755                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign type"
2756         $LFS getstripe -v $DIR/$tdir/${tfile}2 |
2757                 grep "lfm_flags:.*0x0000DA08" ||
2758                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign flags"
2759         $LFS getstripe $DIR/$tdir/${tfile}2 |
2760                 grep "lfm_value:.*${uuid1}@${uuid2}" ||
2761                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign value"
2762
2763         # modify striping should fail
2764         $LFS setstripe -c 2 $DIR/$tdir/$tfile &&
2765                 error "$DIR/$tdir/$tfile: setstripe should fail"
2766         $LFS setstripe -c 2 $DIR/$tdir/${tfile}2 &&
2767                 error "$DIR/$tdir/${tfile}2: setstripe should fail"
2768
2769         # R/W should fail
2770         cat $DIR/$tdir/$tfile && error "$DIR/$tdir/$tfile: read should fail"
2771         cat $DIR/$tdir/${tfile}2 &&
2772                 error "$DIR/$tdir/${tfile}2: read should fail"
2773         cat /etc/passwd > $DIR/$tdir/$tfile &&
2774                 error "$DIR/$tdir/$tfile: write should fail"
2775         cat /etc/passwd > $DIR/$tdir/${tfile}2 &&
2776                 error "$DIR/$tdir/${tfile}2: write should fail"
2777
2778         # chmod should work
2779         chmod 222 $DIR/$tdir/$tfile ||
2780                 error "$DIR/$tdir/$tfile: chmod failed"
2781         chmod 222 $DIR/$tdir/${tfile}2 ||
2782                 error "$DIR/$tdir/${tfile}2: chmod failed"
2783
2784         # chown should work
2785         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/$tfile ||
2786                 error "$DIR/$tdir/$tfile: chown failed"
2787         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/${tfile}2 ||
2788                 error "$DIR/$tdir/${tfile}2: chown failed"
2789
2790         # rename should work
2791         mv $DIR/$tdir/$tfile $DIR/$tdir/${tfile}.new ||
2792                 error "$DIR/$tdir/$tfile: rename of foreign file has failed"
2793         mv $DIR/$tdir/${tfile}2 $DIR/$tdir/${tfile}2.new ||
2794                 error "$DIR/$tdir/${tfile}2: rename of foreign file has failed"
2795
2796         #remove foreign file
2797         rm $DIR/$tdir/${tfile}.new ||
2798                 error "$DIR/$tdir/${tfile}.new: remove of foreign file has failed"
2799         rm $DIR/$tdir/${tfile}2.new ||
2800                 error "$DIR/$tdir/${tfile}2.new: remove of foreign file has failed"
2801 }
2802 run_test 27J "basic ops on file with foreign LOV"
2803
2804 test_27K() {
2805         [[ $MDS1_VERSION -le $(version_code 2.12.49) ]] &&
2806                 skip "Need MDS version newer than 2.12.49"
2807
2808         test_mkdir $DIR/$tdir
2809         local uuid1=$(cat /proc/sys/kernel/random/uuid)
2810         local uuid2=$(cat /proc/sys/kernel/random/uuid)
2811
2812         # create foreign dir (raw way)
2813         create_foreign_dir -d $DIR/$tdir/$tdir -x "${uuid1}@${uuid2}" -t 1 ||
2814                 error "create_foreign_dir FAILED"
2815
2816         # verify foreign dir (raw way)
2817         parse_foreign_dir -d $DIR/$tdir/$tdir |
2818                 grep "lmv_foreign_magic:.*0xcd50cd0" ||
2819                 error "$DIR/$tdir/$tfile: invalid LMV EA magic"
2820         parse_foreign_dir -d $DIR/$tdir/$tdir | grep "lmv_xattr_size:.*89$" ||
2821                 error "$DIR/$tdir/$tdir: invalid LMV EA size"
2822         parse_foreign_dir -d $DIR/$tdir/$tdir | grep "lmv_foreign_type: 1$" ||
2823                 error "$DIR/$tdir/$tdir: invalid LMV EA type"
2824         parse_foreign_dir -d $DIR/$tdir/$tdir | grep "lmv_foreign_flags: 0$" ||
2825                 error "$DIR/$tdir/$tdir: invalid LMV EA flags"
2826         local lmv=$(parse_foreign_dir -d $DIR/$tdir/$tdir |
2827                 grep "lmv_foreign_value: 0x" |
2828                 sed 's/lmv_foreign_value: 0x//')
2829         local lmv2=$(echo -n "${uuid1}@${uuid2}" | od -A n -t x1 -w160 |
2830                 sed 's/ //g')
2831         [[ $lmv == $lmv2 ]] || error "$DIR/$tdir/$tdir: invalid LMV EA value"
2832
2833         # create foreign dir (lfs + API)
2834         $LFS mkdir --foreign=daos --xattr="${uuid1}@${uuid2}" --flags=0xda05 \
2835                 $DIR/$tdir/${tdir}2 ||
2836                 error "$DIR/$tdir/${tdir}2: create failed"
2837
2838         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 |
2839                 grep "lfm_magic:.*0x0CD50CD0" ||
2840                 error "$DIR/$tdir/${tdir}2: invalid LMV EA magic"
2841         # lfm_length is LMV EA size - sizeof(lfm_magic) - sizeof(lfm_length)
2842         # - sizeof(lfm_type) - sizeof(lfm_flags)
2843         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 | grep "lfm_length:.*73" ||
2844                 error "$DIR/$tdir/${tdir}2: invalid LMV EA size"
2845         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 | grep "lfm_type:.*daos" ||
2846                 error "$DIR/$tdir/${tdir}2: invalid LMV EA type"
2847         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 |
2848                 grep "lfm_flags:.*0x0000DA05" ||
2849                 error "$DIR/$tdir/${tdir}2: invalid LMV EA flags"
2850         $LFS getdirstripe $DIR/$tdir/${tdir}2 |
2851                 grep "lfm_value.*${uuid1}@${uuid2}" ||
2852                 error "$DIR/$tdir/${tdir}2: invalid LMV EA value"
2853
2854         # file create in dir should fail
2855         touch $DIR/$tdir/$tdir/$tfile && "$DIR/$tdir: file create should fail"
2856         touch $DIR/$tdir/${tdir}2/$tfile &&
2857                 "$DIR/${tdir}2: file create should fail"
2858
2859         # chmod should work
2860         chmod 777 $DIR/$tdir/$tdir ||
2861                 error "$DIR/$tdir: chmod failed"
2862         chmod 777 $DIR/$tdir/${tdir}2 ||
2863                 error "$DIR/${tdir}2: chmod failed"
2864
2865         # chown should work
2866         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/$tdir ||
2867                 error "$DIR/$tdir: chown failed"
2868         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/${tdir}2 ||
2869                 error "$DIR/${tdir}2: chown failed"
2870
2871         # rename should work
2872         mv $DIR/$tdir/$tdir $DIR/$tdir/${tdir}.new ||
2873                 error "$DIR/$tdir/$tdir: rename of foreign dir has failed"
2874         mv $DIR/$tdir/${tdir}2 $DIR/$tdir/${tdir}2.new ||
2875                 error "$DIR/$tdir/${tdir}2: rename of foreign dir has failed"
2876
2877         #remove foreign dir
2878         rmdir $DIR/$tdir/${tdir}.new ||
2879                 error "$DIR/$tdir/${tdir}.new: remove of foreign dir has failed"
2880         rmdir $DIR/$tdir/${tdir}2.new ||
2881                 error "$DIR/$tdir/${tdir}2.new: remove of foreign dir has failed"
2882 }
2883 run_test 27K "basic ops on dir with foreign LMV"
2884
2885 test_27L() {
2886         remote_mds_nodsh && skip "remote MDS with nodsh"
2887
2888         local POOL=${POOL:-$TESTNAME}
2889
2890         pool_add $POOL || error "pool_add failed"
2891
2892         lfs pool_list $MOUNT | grep -Fx "${FSNAME}.${POOL}" ||
2893                  error "pool_list does not contain ${FSNAME}.${POOL}:" \
2894                        "$(lfs pool_list $MOUNT | grep -F "${POOL}")"
2895 }
2896 run_test 27L "lfs pool_list gives correct pool name"
2897
2898 test_27M() {
2899         [[ $(lustre_version_code $SINGLEMDS) -lt $(version_code 2.12.57) ]] &&
2900                 skip "Need MDS version >= than 2.12.57"
2901         remote_mds_nodsh && skip "remote MDS with nodsh"
2902         [[ $OSTCOUNT -lt 2 ]] && skip_env "need > 1 OST"
2903
2904         test_mkdir $DIR/$tdir
2905
2906         # Set default striping on directory
2907         $LFS setstripe -C 4 $DIR/$tdir
2908
2909         echo 1 > $DIR/$tdir/${tfile}.1
2910         local count=$($LFS getstripe -c $DIR/$tdir/${tfile}.1)
2911         local setcount=4
2912         [ $count -eq $setcount ] ||
2913                 error "(1) stripe count $count, should be $setcount"
2914
2915         # Capture existing append_stripe_count setting for restore
2916         local orig_count=$(do_facet mds1 $LCTL get_param -n mdd.$FSNAME-MDT0000.append_stripe_count)
2917         local mdts=$(comma_list $(mdts_nodes))
2918         stack_trap "do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=$orig_count" EXIT
2919
2920         local appendcount=$orig_count
2921         echo 1 >> $DIR/$tdir/${tfile}.2_append
2922         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.2_append)
2923         [ $count -eq $appendcount ] ||
2924                 error "(2)stripe count $count, should be $appendcount for append"
2925
2926         # Disable O_APPEND striping, verify it works
2927         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=0
2928
2929         # Should now get the default striping, which is 4
2930         setcount=4
2931         echo 1 >> $DIR/$tdir/${tfile}.3_append
2932         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.3_append)
2933         [ $count -eq $setcount ] ||
2934                 error "(3) stripe count $count, should be $setcount"
2935
2936         # Try changing the stripe count for append files
2937         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=2
2938
2939         # Append striping is now 2 (directory default is still 4)
2940         appendcount=2
2941         echo 1 >> $DIR/$tdir/${tfile}.4_append
2942         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.4_append)
2943         [ $count -eq $appendcount ] ||
2944                 error "(4) stripe count $count, should be $appendcount for append"
2945
2946         # Test append stripe count of -1
2947         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=-1
2948         appendcount=$OSTCOUNT
2949         echo 1 >> $DIR/$tdir/${tfile}.5
2950         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.5)
2951         [ $count -eq $appendcount ] ||
2952                 error "(5) stripe count $count, should be $appendcount for append"
2953
2954         # Set append striping back to default of 1
2955         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=1
2956
2957         # Try a new default striping, PFL + DOM
2958         $LFS setstripe -L mdt -E 1M -E -1 -c 2 $DIR/$tdir
2959
2960         # Create normal DOM file, DOM returns stripe count == 0
2961         setcount=0
2962         touch $DIR/$tdir/${tfile}.6
2963         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.6)
2964         [ $count -eq $setcount ] ||
2965                 error "(6) stripe count $count, should be $setcount"
2966
2967         # Show
2968         appendcount=1
2969         echo 1 >> $DIR/$tdir/${tfile}.7_append
2970         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.7_append)
2971         [ $count -eq $appendcount ] ||
2972                 error "(7) stripe count $count, should be $appendcount for append"
2973
2974         # Clean up DOM layout
2975         $LFS setstripe -d $DIR/$tdir
2976
2977         # Now test that append striping works when layout is from root
2978         $LFS setstripe -c 2 $MOUNT
2979         # Make a special directory for this
2980         mkdir $DIR/${tdir}/${tdir}.2
2981         stack_trap "$LFS setstripe -d $MOUNT" EXIT
2982
2983         # Verify for normal file
2984         setcount=2
2985         echo 1 > $DIR/${tdir}/${tdir}.2/${tfile}.8
2986         count=$($LFS getstripe -c $DIR/$tdir/${tdir}.2/${tfile}.8)
2987         [ $count -eq $setcount ] ||
2988                 error "(8) stripe count $count, should be $setcount"
2989
2990         appendcount=1
2991         echo 1 >> $DIR/${tdir}/${tdir}.2/${tfile}.9_append
2992         count=$($LFS getstripe -c $DIR/${tdir}/${tdir}.2/${tfile}.9_append)
2993         [ $count -eq $appendcount ] ||
2994                 error "(9) stripe count $count, should be $appendcount for append"
2995
2996         # Now test O_APPEND striping with pools
2997         do_nodes $mdts $LCTL set_param mdd.*.append_pool="$TESTNAME"
2998         stack_trap "do_nodes $mdts $LCTL set_param mdd.*.append_pool='none'" EXIT
2999
3000         # Create the pool
3001         pool_add $TESTNAME || error "pool creation failed"
3002         pool_add_targets $TESTNAME 0 1 || error "Pool add targets failed"
3003
3004         echo 1 >> $DIR/$tdir/${tfile}.10_append
3005
3006         pool=$($LFS getstripe -p $DIR/$tdir/${tfile}.10_append)
3007         [ "$pool" = "$TESTNAME" ] || error "(10) incorrect pool: $pool"
3008
3009         # Check that count is still correct
3010         appendcount=1
3011         echo 1 >> $DIR/$tdir/${tfile}.11_append
3012         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.11_append)
3013         [ $count -eq $appendcount ] ||
3014                 error "(11) stripe count $count, should be $appendcount for append"
3015
3016         # Disable O_APPEND stripe count, verify pool works separately
3017         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=0
3018
3019         echo 1 >> $DIR/$tdir/${tfile}.12_append
3020
3021         pool=$($LFS getstripe -p $DIR/$tdir/${tfile}.12_append)
3022         [ "$pool" = "$TESTNAME" ] || error "(12) incorrect pool: $pool"
3023
3024         # Remove pool setting, verify it's not applied
3025         do_nodes $mdts $LCTL set_param mdd.*.append_pool='none'
3026
3027         echo 1 >> $DIR/$tdir/${tfile}.13_append
3028
3029         pool=$($LFS getstripe -p $DIR/$tdir/${tfile}.13_append)
3030         [ "$pool" = "" ] || error "(13) pool found: $pool"
3031 }
3032 run_test 27M "test O_APPEND striping"
3033
3034 test_27N() {
3035         combined_mgs_mds && skip "needs separate MGS/MDT"
3036
3037         pool_add $TESTNAME || error "pool_add failed"
3038         do_facet mgs "$LCTL pool_list $FSNAME" |
3039                 grep -Fx "${FSNAME}.${TESTNAME}" ||
3040                 error "lctl pool_list on MGS failed"
3041 }
3042 run_test 27N "lctl pool_list on separate MGS gives correct pool name"
3043
3044 # createtest also checks that device nodes are created and
3045 # then visible correctly (#2091)
3046 test_28() { # bug 2091
3047         test_mkdir $DIR/d28
3048         $CREATETEST $DIR/d28/ct || error "createtest failed"
3049 }
3050 run_test 28 "create/mknod/mkdir with bad file types ============"
3051
3052 test_29() {
3053         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3054
3055         sync; sleep 1; sync # flush out any dirty pages from previous tests
3056         cancel_lru_locks
3057         test_mkdir $DIR/d29
3058         touch $DIR/d29/foo
3059         log 'first d29'
3060         ls -l $DIR/d29
3061
3062         declare -i LOCKCOUNTORIG=0
3063         for lock_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_count); do
3064                 let LOCKCOUNTORIG=$LOCKCOUNTORIG+$lock_count
3065         done
3066         [ $LOCKCOUNTORIG -eq 0 ] && error "No mdc lock count" && return 1
3067
3068         declare -i LOCKUNUSEDCOUNTORIG=0
3069         for unused_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_unused_count); do
3070                 let LOCKUNUSEDCOUNTORIG=$LOCKUNUSEDCOUNTORIG+$unused_count
3071         done
3072
3073         log 'second d29'
3074         ls -l $DIR/d29
3075         log 'done'
3076
3077         declare -i LOCKCOUNTCURRENT=0
3078         for lock_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_count); do
3079                 let LOCKCOUNTCURRENT=$LOCKCOUNTCURRENT+$lock_count
3080         done
3081
3082         declare -i LOCKUNUSEDCOUNTCURRENT=0
3083         for unused_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_unused_count); do
3084                 let LOCKUNUSEDCOUNTCURRENT=$LOCKUNUSEDCOUNTCURRENT+$unused_count
3085         done
3086
3087         if [[ $LOCKCOUNTCURRENT -gt $LOCKCOUNTORIG ]]; then
3088                 $LCTL set_param -n ldlm.dump_namespaces ""
3089                 error "CURRENT: $LOCKCOUNTCURRENT > $LOCKCOUNTORIG"
3090                 $LCTL dk | sort -k4 -t: > $TMP/test_29.dk
3091                 log "dumped log to $TMP/test_29.dk (bug 5793)"
3092                 return 2
3093         fi
3094         if [[ $LOCKUNUSEDCOUNTCURRENT -gt $LOCKUNUSEDCOUNTORIG ]]; then
3095                 error "UNUSED: $LOCKUNUSEDCOUNTCURRENT > $LOCKUNUSEDCOUNTORIG"
3096                 $LCTL dk | sort -k4 -t: > $TMP/test_29.dk
3097                 log "dumped log to $TMP/test_29.dk (bug 5793)"
3098                 return 3
3099         fi
3100 }
3101 run_test 29 "IT_GETATTR regression  ============================"
3102
3103 test_30a() { # was test_30
3104         cp $(which ls) $DIR || cp /bin/ls $DIR
3105         $DIR/ls / || error "Can't execute binary from lustre"
3106         rm $DIR/ls
3107 }
3108 run_test 30a "execute binary from Lustre (execve) =============="
3109
3110 test_30b() {
3111         cp `which ls` $DIR || cp /bin/ls $DIR
3112         chmod go+rx $DIR/ls
3113         $RUNAS $DIR/ls / || error "Can't execute binary from lustre as non-root"
3114         rm $DIR/ls
3115 }
3116 run_test 30b "execute binary from Lustre as non-root ==========="
3117
3118 test_30c() { # b=22376
3119         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3120
3121         cp $(which ls) $DIR || cp /bin/ls $DIR
3122         chmod a-rw $DIR/ls
3123         cancel_lru_locks mdc
3124         cancel_lru_locks osc
3125         $RUNAS $DIR/ls / || error "Can't execute binary from lustre"
3126         rm -f $DIR/ls
3127 }
3128 run_test 30c "execute binary from Lustre without read perms ===="
3129
3130 test_30d() {
3131         cp $(which dd) $DIR || error "failed to copy dd to $DIR/dd"
3132
3133         for i in {1..10}; do
3134                 $DIR/dd bs=1M count=128 if=/dev/zero of=$DIR/$tfile &
3135                 local PID=$!
3136                 sleep 1
3137                 $LCTL set_param ldlm.namespaces.*MDT*.lru_size=clear
3138                 wait $PID || error "executing dd from Lustre failed"
3139                 rm -f $DIR/$tfile
3140         done
3141
3142         rm -f $DIR/dd
3143 }
3144 run_test 30d "execute binary from Lustre while clear locks"
3145
3146 test_31a() {
3147         $OPENUNLINK $DIR/f31 $DIR/f31 || error "openunlink failed"
3148         $CHECKSTAT -a $DIR/f31 || error "$DIR/f31 exists"
3149 }
3150 run_test 31a "open-unlink file =================================="
3151
3152 test_31b() {
3153         touch $DIR/f31 || error "touch $DIR/f31 failed"
3154         ln $DIR/f31 $DIR/f31b || error "ln failed"
3155         $MULTIOP $DIR/f31b Ouc || error "multiop failed"
3156         $CHECKSTAT -t file $DIR/f31 || error "$DIR/f31 not file type"
3157 }
3158 run_test 31b "unlink file with multiple links while open ======="
3159
3160 test_31c() {
3161         touch $DIR/f31 || error "touch $DIR/f31 failed"
3162         ln $DIR/f31 $DIR/f31c || error "ln failed"
3163         multiop_bg_pause $DIR/f31 O_uc ||
3164                 error "multiop_bg_pause for $DIR/f31 failed"
3165         MULTIPID=$!
3166         $MULTIOP $DIR/f31c Ouc
3167         kill -USR1 $MULTIPID
3168         wait $MULTIPID
3169 }
3170 run_test 31c "open-unlink file with multiple links ============="
3171
3172 test_31d() {
3173         opendirunlink $DIR/d31d $DIR/d31d || error "opendirunlink failed"
3174         $CHECKSTAT -a $DIR/d31d || error "$DIR/d31d exists"
3175 }
3176 run_test 31d "remove of open directory ========================="
3177
3178 test_31e() { # bug 2904
3179         openfilleddirunlink $DIR/d31e || error "openfilleddirunlink failed"
3180 }
3181 run_test 31e "remove of open non-empty directory ==============="
3182
3183 test_31f() { # bug 4554
3184         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3185
3186         set -vx
3187         test_mkdir $DIR/d31f
3188         $LFS setstripe -S 1048576 -c 1 $DIR/d31f
3189         cp /etc/hosts $DIR/d31f
3190         ls -l $DIR/d31f
3191         $LFS getstripe $DIR/d31f/hosts
3192         multiop_bg_pause $DIR/d31f D_c || return 1
3193         MULTIPID=$!
3194
3195         rm -rv $DIR/d31f || error "first of $DIR/d31f"
3196         test_mkdir $DIR/d31f
3197         $LFS setstripe -S 1048576 -c 1 $DIR/d31f
3198         cp /etc/hosts $DIR/d31f
3199         ls -l $DIR/d31f
3200         $LFS getstripe $DIR/d31f/hosts
3201         multiop_bg_pause $DIR/d31f D_c || return 1
3202         MULTIPID2=$!
3203
3204         kill -USR1 $MULTIPID || error "first opendir $MULTIPID not running"
3205         wait $MULTIPID || error "first opendir $MULTIPID failed"
3206
3207         sleep 6
3208
3209         kill -USR1 $MULTIPID2 || error "second opendir $MULTIPID not running"
3210         wait $MULTIPID2 || error "second opendir $MULTIPID2 failed"
3211         set +vx
3212 }
3213 run_test 31f "remove of open directory with open-unlink file ==="
3214
3215 test_31g() {
3216         echo "-- cross directory link --"
3217         test_mkdir -c1 $DIR/${tdir}ga
3218         test_mkdir -c1 $DIR/${tdir}gb
3219         touch $DIR/${tdir}ga/f
3220         ln $DIR/${tdir}ga/f $DIR/${tdir}gb/g
3221         $CHECKSTAT -t file $DIR/${tdir}ga/f || error "source"
3222         [ `stat -c%h $DIR/${tdir}ga/f` == '2' ] || error "source nlink"
3223         $CHECKSTAT -t file $DIR/${tdir}gb/g || error "target"
3224         [ `stat -c%h $DIR/${tdir}gb/g` == '2' ] || error "target nlink"
3225 }
3226 run_test 31g "cross directory link==============="
3227
3228 test_31h() {
3229         echo "-- cross directory link --"
3230         test_mkdir -c1 $DIR/${tdir}
3231         test_mkdir -c1 $DIR/${tdir}/dir
3232         touch $DIR/${tdir}/f
3233         ln $DIR/${tdir}/f $DIR/${tdir}/dir/g
3234         $CHECKSTAT -t file $DIR/${tdir}/f || error "source"
3235         [ `stat -c%h $DIR/${tdir}/f` == '2' ] || error "source nlink"
3236         $CHECKSTAT -t file $DIR/${tdir}/dir/g || error "target"
3237         [ `stat -c%h $DIR/${tdir}/dir/g` == '2' ] || error "target nlink"
3238 }
3239 run_test 31h "cross directory link under child==============="
3240
3241 test_31i() {
3242         echo "-- cross directory link --"
3243         test_mkdir -c1 $DIR/$tdir
3244         test_mkdir -c1 $DIR/$tdir/dir
3245         touch $DIR/$tdir/dir/f
3246         ln $DIR/$tdir/dir/f $DIR/$tdir/g
3247         $CHECKSTAT -t file $DIR/$tdir/dir/f || error "source"
3248         [ `stat -c%h $DIR/$tdir/dir/f` == '2' ] || error "source nlink"
3249         $CHECKSTAT -t file $DIR/$tdir/g || error "target"
3250         [ `stat -c%h $DIR/$tdir/g` == '2' ] || error "target nlink"
3251 }
3252 run_test 31i "cross directory link under parent==============="
3253
3254 test_31j() {
3255         test_mkdir -c1 -p $DIR/$tdir
3256         test_mkdir -c1 -p $DIR/$tdir/dir1
3257         ln $DIR/$tdir/dir1 $DIR/$tdir/dir2 && error "ln for dir"
3258         link $DIR/$tdir/dir1 $DIR/$tdir/dir3 && error "link for dir"
3259         mlink $DIR/$tdir/dir1 $DIR/$tdir/dir4 && error "mlink for dir"
3260         mlink $DIR/$tdir/dir1 $DIR/$tdir/dir1 && error "mlink to the same dir"
3261         return 0
3262 }
3263 run_test 31j "link for directory==============="
3264
3265 test_31k() {
3266         test_mkdir -c1 -p $DIR/$tdir
3267         touch $DIR/$tdir/s
3268         touch $DIR/$tdir/exist
3269         mlink $DIR/$tdir/s $DIR/$tdir/t || error "mlink"
3270         mlink $DIR/$tdir/s $DIR/$tdir/exist && error "mlink to exist file"
3271         mlink $DIR/$tdir/s $DIR/$tdir/s && error "mlink to the same file"
3272         mlink $DIR/$tdir/s $DIR/$tdir && error "mlink to parent dir"
3273         mlink $DIR/$tdir $DIR/$tdir/s && error "mlink parent dir to target"
3274         mlink $DIR/$tdir/not-exist $DIR/$tdir/foo && error "mlink non-existing to new"
3275         mlink $DIR/$tdir/not-exist $DIR/$tdir/s && error "mlink non-existing to exist"
3276         return 0
3277 }
3278 run_test 31k "link to file: the same, non-existing, dir==============="
3279
3280 test_31m() {
3281         mkdir $DIR/d31m
3282         touch $DIR/d31m/s
3283         mkdir $DIR/d31m2
3284         touch $DIR/d31m2/exist
3285         mlink $DIR/d31m/s $DIR/d31m2/t || error "mlink"
3286         mlink $DIR/d31m/s $DIR/d31m2/exist && error "mlink to exist file"
3287         mlink $DIR/d31m/s $DIR/d31m2 && error "mlink to parent dir"
3288         mlink $DIR/d31m2 $DIR/d31m/s && error "mlink parent dir to target"
3289         mlink $DIR/d31m/not-exist $DIR/d31m2/foo && error "mlink non-existing to new"
3290         mlink $DIR/d31m/not-exist $DIR/d31m2/s && error "mlink non-existing to exist"
3291         return 0
3292 }
3293 run_test 31m "link to file: the same, non-existing, dir==============="
3294
3295 test_31n() {
3296         touch $DIR/$tfile || error "cannot create '$DIR/$tfile'"
3297         nlink=$(stat --format=%h $DIR/$tfile)
3298         [ ${nlink:--1} -eq 1 ] || error "nlink is $nlink, expected 1"
3299         local fd=$(free_fd)
3300         local cmd="exec $fd<$DIR/$tfile"
3301         eval $cmd
3302         cmd="exec $fd<&-"
3303         trap "eval $cmd" EXIT
3304         nlink=$(stat --dereference --format=%h /proc/self/fd/$fd)
3305         [ ${nlink:--1} -eq 1 ] || error "nlink is $nlink, expected 1"
3306         rm $DIR/$tfile || error "cannot remove '$DIR/$tfile'"
3307         nlink=$(stat --dereference --format=%h /proc/self/fd/$fd)
3308         [ ${nlink:--1} -eq 0 ] || error "nlink is $nlink, expected 0"
3309         eval $cmd
3310 }
3311 run_test 31n "check link count of unlinked file"
3312
3313 link_one() {
3314         local tempfile=$(mktemp $1_XXXXXX)
3315         mlink $tempfile $1 2> /dev/null &&
3316                 echo "$BASHPID: link $tempfile to $1 succeeded"
3317         munlink $tempfile
3318 }
3319
3320 test_31o() { # LU-2901
3321         test_mkdir $DIR/$tdir
3322         for LOOP in $(seq 100); do
3323                 rm -f $DIR/$tdir/$tfile*
3324                 for THREAD in $(seq 8); do
3325                         link_one $DIR/$tdir/$tfile.$LOOP &
3326                 done
3327                 wait
3328                 local LINKS=$(ls -1 $DIR/$tdir | grep -c $tfile.$LOOP)
3329                 [[ $LINKS -gt 1 ]] && ls $DIR/$tdir &&
3330                         error "$LINKS duplicate links to $tfile.$LOOP" &&
3331                         break || true
3332         done
3333 }
3334 run_test 31o "duplicate hard links with same filename"
3335
3336 test_31p() {
3337         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
3338
3339         test_mkdir $DIR/$tdir
3340         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
3341         $LFS setdirstripe -D -c2 -H all_char $DIR/$tdir/striped_dir
3342
3343         opendirunlink $DIR/$tdir/striped_dir/test1 ||
3344                 error "open unlink test1 failed"
3345         opendirunlink $DIR/$tdir/striped_dir/test2 ||
3346                 error "open unlink test2 failed"
3347
3348         $CHECKSTAT -a $DIR/$tdir/striped_dir/test1 ||
3349                 error "test1 still exists"
3350         $CHECKSTAT -a $DIR/$tdir/striped_dir/test2 ||
3351                 error "test2 still exists"
3352 }
3353 run_test 31p "remove of open striped directory"
3354
3355 test_31q() {
3356         [ $MDSCOUNT -lt 3 ] && skip_env "needs >= 3 MDTs"
3357
3358         $LFS mkdir -i 3,1 $DIR/$tdir || error "mkdir failed"
3359         index=$($LFS getdirstripe -i $DIR/$tdir)
3360         [ $index -eq 3 ] || error "first stripe index $index != 3"
3361         index=$($LFS getdirstripe $DIR/$tdir | tail -1 | awk '{print $1}')
3362         [ $index -eq 1 ] || error "second stripe index $index != 1"
3363
3364         # when "-c <stripe_count>" is set, the number of MDTs specified after
3365         # "-i" should equal to the stripe count
3366         $LFS mkdir -i 3,1 -c 3 $DIR/$tdir.2 && error "mkdir should fail" || true
3367 }
3368 run_test 31q "create striped directory on specific MDTs"
3369
3370 cleanup_test32_mount() {
3371         local rc=0
3372         trap 0
3373         local loopdev=$(losetup -a | grep $EXT2_DEV | sed -ne 's/:.*$//p')
3374         $UMOUNT $DIR/$tdir/ext2-mountpoint || rc=$?
3375         losetup -d $loopdev || true
3376         rm -rf $DIR/$tdir
3377         return $rc
3378 }
3379
3380 test_32a() {
3381         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3382
3383         echo "== more mountpoints and symlinks ================="
3384         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3385         trap cleanup_test32_mount EXIT
3386         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3387         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3388                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3389         $CHECKSTAT -t dir $DIR/$tdir/ext2-mountpoint/.. ||
3390                 error "$DIR/$tdir/ext2-mountpoint/.. not dir type"
3391         cleanup_test32_mount
3392 }
3393 run_test 32a "stat d32a/ext2-mountpoint/.. ====================="
3394
3395 test_32b() {
3396         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3397
3398         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3399         trap cleanup_test32_mount EXIT
3400         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3401         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3402                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3403         ls -al $DIR/$tdir/ext2-mountpoint/.. ||
3404                 error "Can't list $DIR/$tdir/ext2-mountpoint/.."
3405         cleanup_test32_mount
3406 }
3407 run_test 32b "open d32b/ext2-mountpoint/.. ====================="
3408
3409 test_32c() {
3410         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3411
3412         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3413         trap cleanup_test32_mount EXIT
3414         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3415         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3416                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3417         test_mkdir -p $DIR/$tdir/d2/test_dir
3418         $CHECKSTAT -t dir $DIR/$tdir/ext2-mountpoint/../d2/test_dir ||
3419                 error "$DIR/$tdir/ext2-mountpoint/../d2/test_dir not dir type"
3420         cleanup_test32_mount
3421 }
3422 run_test 32c "stat d32c/ext2-mountpoint/../d2/test_dir ========="
3423
3424 test_32d() {
3425         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3426
3427         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3428         trap cleanup_test32_mount EXIT
3429         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3430         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3431                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3432         test_mkdir -p $DIR/$tdir/d2/test_dir
3433         ls -al $DIR/$tdir/ext2-mountpoint/../d2/test_dir ||
3434                 error "Can't list $DIR/$tdir/ext2-mountpoint/../d2/test_dir"
3435         cleanup_test32_mount
3436 }
3437 run_test 32d "open d32d/ext2-mountpoint/../d2/test_dir"
3438
3439 test_32e() {
3440         rm -fr $DIR/$tdir
3441         test_mkdir -p $DIR/$tdir/tmp
3442         local tmp_dir=$DIR/$tdir/tmp
3443         ln -s $DIR/$tdir $tmp_dir/symlink11
3444         ln -s $tmp_dir/symlink11 $tmp_dir/../symlink01
3445         $CHECKSTAT -t link $DIR/$tdir/tmp/symlink11 || error "symlink11 bad"
3446         $CHECKSTAT -t link $DIR/$tdir/symlink01 || error "symlink01 bad"
3447 }
3448 run_test 32e "stat d32e/symlink->tmp/symlink->lustre-subdir"
3449
3450 test_32f() {
3451         rm -fr $DIR/$tdir
3452         test_mkdir -p $DIR/$tdir/tmp
3453         local tmp_dir=$DIR/$tdir/tmp
3454         ln -s $DIR/$tdir $tmp_dir/symlink11
3455         ln -s $tmp_dir/symlink11 $tmp_dir/../symlink01
3456         ls $DIR/$tdir/tmp/symlink11  || error "symlink11 bad"
3457         ls $DIR/$tdir/symlink01 || error "symlink01 bad"
3458 }
3459 run_test 32f "open d32f/symlink->tmp/symlink->lustre-subdir"
3460
3461 test_32g() {
3462         local tmp_dir=$DIR/$tdir/tmp
3463         test_mkdir -p $tmp_dir
3464         test_mkdir $DIR/${tdir}2
3465         ln -s $DIR/${tdir}2 $tmp_dir/symlink12
3466         ln -s $tmp_dir/symlink12 $tmp_dir/../symlink02
3467         $CHECKSTAT -t link $tmp_dir/symlink12 || error "symlink12 not a link"
3468         $CHECKSTAT -t link $DIR/$tdir/symlink02 || error "symlink02 not a link"
3469         $CHECKSTAT -t dir -f $tmp_dir/symlink12 || error "symlink12 not a dir"
3470         $CHECKSTAT -t dir -f $DIR/$tdir/symlink02 || error "symlink12 not a dir"
3471 }
3472 run_test 32g "stat d32g/symlink->tmp/symlink->lustre-subdir/${tdir}2"
3473
3474 test_32h() {
3475         rm -fr $DIR/$tdir $DIR/${tdir}2
3476         tmp_dir=$DIR/$tdir/tmp
3477         test_mkdir -p $tmp_dir
3478         test_mkdir $DIR/${tdir}2
3479         ln -s $DIR/${tdir}2 $tmp_dir/symlink12
3480         ln -s $tmp_dir/symlink12 $tmp_dir/../symlink02
3481         ls $tmp_dir/symlink12 || error "listing symlink12"
3482         ls $DIR/$tdir/symlink02  || error "listing symlink02"
3483 }
3484 run_test 32h "open d32h/symlink->tmp/symlink->lustre-subdir/${tdir}2"
3485
3486 test_32i() {
3487         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3488
3489         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3490         trap cleanup_test32_mount EXIT
3491         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3492         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3493                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3494         touch $DIR/$tdir/test_file
3495         $CHECKSTAT -t file $DIR/$tdir/ext2-mountpoint/../test_file ||
3496                 error "$DIR/$tdir/ext2-mountpoint/../test_file not file type"
3497         cleanup_test32_mount
3498 }
3499 run_test 32i "stat d32i/ext2-mountpoint/../test_file ==========="
3500
3501 test_32j() {
3502         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3503
3504         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3505         trap cleanup_test32_mount EXIT
3506         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3507         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3508                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3509         touch $DIR/$tdir/test_file
3510         cat $DIR/$tdir/ext2-mountpoint/../test_file ||
3511                 error "Can't open $DIR/$tdir/ext2-mountpoint/../test_file"
3512         cleanup_test32_mount
3513 }
3514 run_test 32j "open d32j/ext2-mountpoint/../test_file ==========="
3515
3516 test_32k() {
3517         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3518
3519         rm -fr $DIR/$tdir
3520         trap cleanup_test32_mount EXIT
3521         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3522         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3523                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3524         test_mkdir -p $DIR/$tdir/d2
3525         touch $DIR/$tdir/d2/test_file || error "touch failed"
3526         $CHECKSTAT -t file $DIR/$tdir/ext2-mountpoint/../d2/test_file ||
3527                 error "$DIR/$tdir/ext2-mountpoint/../d2/test_file not file type"
3528         cleanup_test32_mount
3529 }
3530 run_test 32k "stat d32k/ext2-mountpoint/../d2/test_file ========"
3531
3532 test_32l() {
3533         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3534
3535         rm -fr $DIR/$tdir
3536         trap cleanup_test32_mount EXIT
3537         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3538         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3539                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3540         test_mkdir -p $DIR/$tdir/d2
3541         touch $DIR/$tdir/d2/test_file || error "touch failed"
3542         cat  $DIR/$tdir/ext2-mountpoint/../d2/test_file ||
3543                 error "Can't open $DIR/$tdir/ext2-mountpoint/../d2/test_file"
3544         cleanup_test32_mount
3545 }
3546 run_test 32l "open d32l/ext2-mountpoint/../d2/test_file ========"
3547
3548 test_32m() {
3549         rm -fr $DIR/d32m
3550         test_mkdir -p $DIR/d32m/tmp
3551         TMP_DIR=$DIR/d32m/tmp
3552         ln -s $DIR $TMP_DIR/symlink11
3553         ln -s $TMP_DIR/symlink11 $TMP_DIR/../symlink01
3554         $CHECKSTAT -t link $DIR/d32m/tmp/symlink11 ||
3555                 error "symlink11 not a link"
3556         $CHECKSTAT -t link $DIR/d32m/symlink01 ||
3557                 error "symlink01 not a link"
3558 }
3559 run_test 32m "stat d32m/symlink->tmp/symlink->lustre-root ======"
3560
3561 test_32n() {
3562         rm -fr $DIR/d32n
3563         test_mkdir -p $DIR/d32n/tmp
3564         TMP_DIR=$DIR/d32n/tmp
3565         ln -s $DIR $TMP_DIR/symlink11
3566         ln -s $TMP_DIR/symlink11 $TMP_DIR/../symlink01
3567         ls -l $DIR/d32n/tmp/symlink11  || error "listing symlink11"
3568         ls -l $DIR/d32n/symlink01 || error "listing symlink01"
3569 }
3570 run_test 32n "open d32n/symlink->tmp/symlink->lustre-root ======"
3571
3572 test_32o() {
3573         touch $DIR/$tfile
3574         test_mkdir -p $DIR/d32o/tmp
3575         TMP_DIR=$DIR/d32o/tmp
3576         ln -s $DIR/$tfile $TMP_DIR/symlink12
3577         ln -s $TMP_DIR/symlink12 $TMP_DIR/../symlink02
3578         $CHECKSTAT -t link $DIR/d32o/tmp/symlink12 ||
3579                 error "symlink12 not a link"
3580         $CHECKSTAT -t link $DIR/d32o/symlink02 || error "symlink02 not a link"
3581         $CHECKSTAT -t file -f $DIR/d32o/tmp/symlink12 ||
3582                 error "$DIR/d32o/tmp/symlink12 not file type"
3583         $CHECKSTAT -t file -f $DIR/d32o/symlink02 ||
3584                 error "$DIR/d32o/symlink02 not file type"
3585 }
3586 run_test 32o "stat d32o/symlink->tmp/symlink->lustre-root/$tfile"
3587
3588 test_32p() {
3589         log 32p_1
3590         rm -fr $DIR/d32p
3591         log 32p_2
3592         rm -f $DIR/$tfile
3593         log 32p_3
3594         touch $DIR/$tfile
3595         log 32p_4
3596         test_mkdir -p $DIR/d32p/tmp
3597         log 32p_5
3598         TMP_DIR=$DIR/d32p/tmp
3599         log 32p_6
3600         ln -s $DIR/$tfile $TMP_DIR/symlink12
3601         log 32p_7
3602         ln -s $TMP_DIR/symlink12 $TMP_DIR/../symlink02
3603         log 32p_8
3604         cat $DIR/d32p/tmp/symlink12 ||
3605                 error "Can't open $DIR/d32p/tmp/symlink12"
3606         log 32p_9
3607         cat $DIR/d32p/symlink02 || error "Can't open $DIR/d32p/symlink02"
3608         log 32p_10
3609 }
3610 run_test 32p "open d32p/symlink->tmp/symlink->lustre-root/$tfile"
3611
3612 test_32q() {
3613         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3614
3615         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3616         trap cleanup_test32_mount EXIT
3617         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3618         touch $DIR/$tdir/ext2-mountpoint/under_the_mount || error "touch failed"
3619         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3620                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3621         ls $DIR/$tdir/ext2-mountpoint | grep "\<under_the_mount\>" && error
3622         cleanup_test32_mount
3623 }
3624 run_test 32q "stat follows mountpoints in Lustre (should return error)"
3625
3626 test_32r() {
3627         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3628
3629         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3630         trap cleanup_test32_mount EXIT
3631         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3632         touch $DIR/$tdir/ext2-mountpoint/under_the_mount || error "touch failed"
3633         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3634                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3635         ls $DIR/$tdir/ext2-mountpoint | grep -q under_the_mount && error || true
3636         cleanup_test32_mount
3637 }
3638 run_test 32r "opendir follows mountpoints in Lustre (should return error)"
3639
3640 test_33aa() {
3641         rm -f $DIR/$tfile
3642         touch $DIR/$tfile
3643         chmod 444 $DIR/$tfile
3644         chown $RUNAS_ID $DIR/$tfile
3645         log 33_1
3646         $RUNAS $OPENFILE -f O_RDWR $DIR/$tfile && error || true
3647         log 33_2
3648 }
3649 run_test 33aa "write file with mode 444 (should return error)"
3650
3651 test_33a() {
3652         rm -fr $DIR/$tdir
3653         test_mkdir $DIR/$tdir
3654         chown $RUNAS_ID $DIR/$tdir
3655         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $DIR/$tdir/$tfile ||
3656                 error "$RUNAS create $tdir/$tfile failed"
3657         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $DIR/$tdir/$tfile &&
3658                 error "open RDWR" || true
3659 }
3660 run_test 33a "test open file(mode=0444) with O_RDWR (should return error)"
3661
3662 test_33b() {
3663         rm -fr $DIR/$tdir
3664         test_mkdir $DIR/$tdir
3665         chown $RUNAS_ID $DIR/$tdir
3666         $RUNAS $OPENFILE -f 1286739555 $DIR/$tdir/$tfile || true
3667 }
3668 run_test 33b "test open file with malformed flags (No panic)"
3669
3670 test_33c() {
3671         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3672         remote_ost_nodsh && skip "remote OST with nodsh"
3673
3674         local ostnum
3675         local ostname
3676         local write_bytes
3677         local all_zeros
3678
3679         all_zeros=:
3680         rm -fr $DIR/$tdir
3681         test_mkdir $DIR/$tdir
3682         # Read: 0, Write: 4, create/destroy: 2/0, stat: 1, punch: 0
3683
3684         sync
3685         for ostnum in $(seq $OSTCOUNT); do
3686                 # test-framework's OST numbering is one-based, while Lustre's
3687                 # is zero-based
3688                 ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
3689                 # Parsing llobdstat's output sucks; we could grep the /proc
3690                 # path, but that's likely to not be as portable as using the
3691                 # llobdstat utility.  So we parse lctl output instead.
3692                 write_bytes=$(do_facet ost$ostnum lctl get_param -n \
3693                         obdfilter/$ostname/stats |
3694                         awk '/^write_bytes/ {print $7}' )
3695                 echo "baseline_write_bytes@$OSTnum/$ostname=$write_bytes"
3696                 if (( ${write_bytes:-0} > 0 ))
3697                 then
3698                         all_zeros=false
3699                         break;
3700                 fi
3701         done
3702
3703         $all_zeros || return 0
3704
3705         # Write four bytes
3706         echo foo > $DIR/$tdir/bar
3707         # Really write them
3708         sync
3709
3710         # Total up write_bytes after writing.  We'd better find non-zeros.
3711         for ostnum in $(seq $OSTCOUNT); do
3712                 ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
3713                 write_bytes=$(do_facet ost$ostnum lctl get_param -n \
3714                         obdfilter/$ostname/stats |
3715                         awk '/^write_bytes/ {print $7}' )
3716                 echo "write_bytes@$OSTnum/$ostname=$write_bytes"
3717                 if (( ${write_bytes:-0} > 0 ))
3718                 then
3719                         all_zeros=false
3720                         break;
3721                 fi
3722         done
3723
3724         if $all_zeros
3725         then
3726                 for ostnum in $(seq $OSTCOUNT); do
3727                         ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
3728                         echo "Check that write_bytes is present in obdfilter/*/stats:"
3729                         do_facet ost$ostnum lctl get_param -n \
3730                                 obdfilter/$ostname/stats
3731                 done
3732                 error "OST not keeping write_bytes stats (b22312)"
3733         fi
3734 }
3735 run_test 33c "test llobdstat and write_bytes"
3736
3737 test_33d() {
3738         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
3739         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3740
3741         local MDTIDX=1
3742         local remote_dir=$DIR/$tdir/remote_dir
3743
3744         test_mkdir $DIR/$tdir
3745         $LFS mkdir -i $MDTIDX $remote_dir ||
3746                 error "create remote directory failed"
3747
3748         touch $remote_dir/$tfile
3749         chmod 444 $remote_dir/$tfile
3750         chown $RUNAS_ID $remote_dir/$tfile
3751
3752         $RUNAS $OPENFILE -f O_RDWR $DIR/$tfile && error || true
3753
3754         chown $RUNAS_ID $remote_dir
3755         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $remote_dir/f33 ||
3756                                         error "create" || true
3757         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $remote_dir/f33 &&
3758                                     error "open RDWR" || true
3759         $RUNAS $OPENFILE -f 1286739555 $remote_dir/f33 || true
3760 }
3761 run_test 33d "openfile with 444 modes and malformed flags under remote dir"
3762
3763 test_33e() {
3764         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
3765
3766         mkdir $DIR/$tdir
3767
3768         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
3769         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
3770         mkdir $DIR/$tdir/local_dir
3771
3772         local s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
3773         local s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
3774         local l_mode=$(stat -c%f $DIR/$tdir/local_dir)
3775
3776         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
3777                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode"
3778
3779         rmdir $DIR/$tdir/* || error "rmdir failed"
3780
3781         umask 777
3782         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
3783         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
3784         mkdir $DIR/$tdir/local_dir
3785
3786         s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
3787         s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
3788         l_mode=$(stat -c%f $DIR/$tdir/local_dir)
3789
3790         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
3791                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode 777"
3792
3793         rmdir $DIR/$tdir/* || error "rmdir(umask 777) failed"
3794
3795         umask 000
3796         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
3797         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
3798         mkdir $DIR/$tdir/local_dir
3799
3800         s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
3801         s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
3802         l_mode=$(stat -c%f $DIR/$tdir/local_dir)
3803
3804         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
3805                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode 0"
3806 }
3807 run_test 33e "mkdir and striped directory should have same mode"
3808
3809 cleanup_33f() {
3810         trap 0
3811         do_facet $SINGLEMDS $LCTL set_param mdt.*.enable_remote_dir_gid=0
3812 }
3813
3814 test_33f() {
3815         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
3816         remote_mds_nodsh && skip "remote MDS with nodsh"
3817
3818         mkdir $DIR/$tdir
3819         chmod go+rwx $DIR/$tdir
3820         do_facet $SINGLEMDS $LCTL set_param mdt.*.enable_remote_dir_gid=-1
3821         trap cleanup_33f EXIT
3822
3823         $RUNAS lfs mkdir -i 0 -c$MDSCOUNT $DIR/$tdir/striped_dir ||
3824                 error "cannot create striped directory"
3825
3826         $RUNAS touch $DIR/$tdir/striped_dir/{0..16} ||
3827                 error "cannot create files in striped directory"
3828
3829         $RUNAS rm $DIR/$tdir/striped_dir/{0..16} ||
3830                 error "cannot remove files in striped directory"
3831
3832         $RUNAS rmdir $DIR/$tdir/striped_dir ||
3833                 error "cannot remove striped directory"
3834
3835         cleanup_33f
3836 }
3837 run_test 33f "nonroot user can create, access, and remove a striped directory"
3838
3839 test_33g() {
3840         mkdir -p $DIR/$tdir/dir2
3841
3842         local err=$($RUNAS mkdir $DIR/$tdir/dir2 2>&1)
3843         echo $err
3844         [[ $err =~ "exists" ]] || error "Not exists error"
3845 }
3846 run_test 33g "nonroot user create already existing root created file"
3847
3848 test_33h() {
3849         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
3850         [ $MDS1_VERSION -lt $(version_code 2.13.50) ] &&
3851                 skip "Need MDS version at least 2.13.50"
3852
3853         test_mkdir -c $MDSCOUNT -H crush $DIR/$tdir ||
3854                 error "mkdir $tdir failed"
3855         touch $DIR/$tdir/$tfile || error "touch $tfile failed"
3856
3857         local index=$($LFS getstripe -m $DIR/$tdir/$tfile)
3858         local index2
3859
3860         for fname in $DIR/$tdir/$tfile.bak \
3861                      $DIR/$tdir/$tfile.SAV \
3862                      $DIR/$tdir/$tfile.orig \
3863                      $DIR/$tdir/$tfile~; do
3864                 touch $fname  || error "touch $fname failed"
3865                 index2=$($LFS getstripe -m $fname)
3866                 [ $index -eq $index2 ] ||
3867                         error "$fname MDT index mismatch $index != $index2"
3868         done
3869
3870         local failed=0
3871         for i in {1..250}; do
3872                 for fname in $(mktemp -u $DIR/$tdir/.$tfile.XXXXXX) \
3873                              $(mktemp $DIR/$tdir/$tfile.XXXXXXXX); do
3874                         touch $fname  || error "touch $fname failed"
3875                         index2=$($LFS getstripe -m $fname)
3876                         if [[ $index != $index2 ]]; then
3877                                 failed=$((failed + 1))
3878                                 echo "$fname MDT index mismatch $index != $index2"
3879                         fi
3880                 done
3881         done
3882         echo "$failed MDT index mismatches"
3883         (( failed < 20 )) || error "MDT index mismatch $failed times"
3884
3885 }
3886 run_test 33h "temp file is located on the same MDT as target"
3887
3888 TEST_34_SIZE=${TEST_34_SIZE:-2000000000000}
3889 test_34a() {
3890         rm -f $DIR/f34
3891         $MCREATE $DIR/f34 || error "mcreate failed"
3892         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
3893                 error "getstripe failed"
3894         $TRUNCATE $DIR/f34 $TEST_34_SIZE || error "truncate failed"
3895         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
3896                 error "getstripe failed"
3897         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
3898                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
3899 }
3900 run_test 34a "truncate file that has not been opened ==========="
3901
3902 test_34b() {
3903         [ ! -f $DIR/f34 ] && test_34a
3904         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
3905                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
3906         $OPENFILE -f O_RDONLY $DIR/f34
3907         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
3908                 error "getstripe failed"
3909         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
3910                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
3911 }
3912 run_test 34b "O_RDONLY opening file doesn't create objects ====="
3913
3914 test_34c() {
3915         [ ! -f $DIR/f34 ] && test_34a
3916         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
3917                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
3918         $OPENFILE -f O_RDWR $DIR/f34
3919         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" &&
3920                 error "$LFS getstripe failed"
3921         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
3922                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
3923 }
3924 run_test 34c "O_RDWR opening file-with-size works =============="
3925
3926 test_34d() {
3927         [ ! -f $DIR/f34 ] && test_34a
3928         dd if=/dev/zero of=$DIR/f34 conv=notrunc bs=4k count=1 ||
3929                 error "dd failed"
3930         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
3931                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
3932         rm $DIR/f34
3933 }
3934 run_test 34d "write to sparse file ============================="
3935
3936 test_34e() {
3937         rm -f $DIR/f34e
3938         $MCREATE $DIR/f34e || error "mcreate failed"
3939         $TRUNCATE $DIR/f34e 1000 || error "truncate failed"
3940         $CHECKSTAT -s 1000 $DIR/f34e ||
3941                 error "Size of $DIR/f34e not equal to 1000 bytes"
3942         $OPENFILE -f O_RDWR $DIR/f34e
3943         $CHECKSTAT -s 1000 $DIR/f34e ||
3944                 error "Size of $DIR/f34e not equal to 1000 bytes"
3945 }
3946 run_test 34e "create objects, some with size and some without =="
3947
3948 test_34f() { # bug 6242, 6243
3949         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3950
3951         SIZE34F=48000
3952         rm -f $DIR/f34f
3953         $MCREATE $DIR/f34f || error "mcreate failed"
3954         $TRUNCATE $DIR/f34f $SIZE34F || error "truncating $DIR/f3f to $SIZE34F"
3955         dd if=$DIR/f34f of=$TMP/f34f
3956         $CHECKSTAT -s $SIZE34F $TMP/f34f || error "$TMP/f34f not $SIZE34F bytes"
3957         dd if=/dev/zero of=$TMP/f34fzero bs=$SIZE34F count=1
3958         cmp $DIR/f34f $TMP/f34fzero || error "$DIR/f34f not all zero"
3959         cmp $TMP/f34f $TMP/f34fzero || error "$TMP/f34f not all zero"
3960         rm $TMP/f34f $TMP/f34fzero $DIR/f34f
3961 }
3962 run_test 34f "read from a file with no objects until EOF ======="
3963
3964 test_34g() {
3965         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3966
3967         dd if=/dev/zero of=$DIR/$tfile bs=1 count=100 seek=$TEST_34_SIZE ||
3968                 error "dd failed"
3969         $TRUNCATE $DIR/$tfile $((TEST_34_SIZE / 2))|| error "truncate failed"
3970         $CHECKSTAT -s $((TEST_34_SIZE / 2)) $DIR/$tfile ||
3971                 error "Size of $DIR/$tfile not equal to $((TEST_34_SIZE / 2))"
3972         cancel_lru_locks osc
3973         $CHECKSTAT -s $((TEST_34_SIZE / 2)) $DIR/$tfile ||
3974                 error "wrong size after lock cancel"
3975
3976         $TRUNCATE $DIR/$tfile $TEST_34_SIZE || error "truncate failed"
3977         $CHECKSTAT -s $TEST_34_SIZE $DIR/$tfile ||
3978                 error "expanding truncate failed"
3979         cancel_lru_locks osc
3980         $CHECKSTAT -s $TEST_34_SIZE $DIR/$tfile ||
3981                 error "wrong expanded size after lock cancel"
3982 }
3983 run_test 34g "truncate long file ==============================="
3984
3985 test_34h() {
3986         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3987
3988         local gid=10
3989         local sz=1000
3990
3991         dd if=/dev/zero of=$DIR/$tfile bs=1M count=10 || error "dd failed"
3992         sync # Flush the cache so that multiop below does not block on cache
3993              # flush when getting the group lock
3994         $MULTIOP $DIR/$tfile OG${gid}T${sz}g${gid}c &
3995         MULTIPID=$!
3996
3997         # Since just timed wait is not good enough, let's do a sync write
3998         # that way we are sure enough time for a roundtrip + processing
3999         # passed + 2 seconds of extra margin.
4000         dd if=/dev/zero of=$DIR/${tfile}-1 bs=$PAGE_SIZE oflag=direct count=1
4001         rm $DIR/${tfile}-1
4002         sleep 2
4003
4004         if [[ `ps h -o comm -p $MULTIPID` == "multiop" ]]; then
4005                 error "Multiop blocked on ftruncate, pid=$MULTIPID"
4006                 kill -9 $MULTIPID
4007         fi
4008         wait $MULTIPID
4009         local nsz=`stat -c %s $DIR/$tfile`
4010         [[ $nsz == $sz ]] || error "New size wrong $nsz != $sz"
4011 }
4012 run_test 34h "ftruncate file under grouplock should not block"
4013
4014 test_35a() {
4015         cp /bin/sh $DIR/f35a
4016         chmod 444 $DIR/f35a
4017         chown $RUNAS_ID $DIR/f35a
4018         $RUNAS $DIR/f35a && error || true
4019         rm $DIR/f35a
4020 }
4021 run_test 35a "exec file with mode 444 (should return and not leak)"
4022
4023 test_36a() {
4024         rm -f $DIR/f36
4025         utime $DIR/f36 || error "utime failed for MDS"
4026 }
4027 run_test 36a "MDS utime check (mknod, utime)"
4028
4029 test_36b() {
4030         echo "" > $DIR/f36
4031         utime $DIR/f36 || error "utime failed for OST"
4032 }
4033 run_test 36b "OST utime check (open, utime)"
4034
4035 test_36c() {
4036         rm -f $DIR/d36/f36
4037         test_mkdir $DIR/d36
4038         chown $RUNAS_ID $DIR/d36
4039         $RUNAS utime $DIR/d36/f36 || error "utime failed for MDS as non-root"
4040 }
4041 run_test 36c "non-root MDS utime check (mknod, utime)"
4042
4043 test_36d() {
4044         [ ! -d $DIR/d36 ] && test_36c
4045         echo "" > $DIR/d36/f36
4046         $RUNAS utime $DIR/d36/f36 || error "utime failed for OST as non-root"
4047 }
4048 run_test 36d "non-root OST utime check (open, utime)"
4049
4050 test_36e() {
4051         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID -- skipping"
4052
4053         test_mkdir $DIR/$tdir
4054         touch $DIR/$tdir/$tfile
4055         $RUNAS utime $DIR/$tdir/$tfile &&
4056                 error "utime worked, expected failure" || true
4057 }
4058 run_test 36e "utime on non-owned file (should return error)"
4059
4060 subr_36fh() {
4061         local fl="$1"
4062         local LANG_SAVE=$LANG
4063         local LC_LANG_SAVE=$LC_LANG
4064         export LANG=C LC_LANG=C # for date language
4065
4066         DATESTR="Dec 20  2000"
4067         test_mkdir $DIR/$tdir
4068         lctl set_param fail_loc=$fl
4069         date; date +%s
4070         cp /etc/hosts $DIR/$tdir/$tfile
4071         sync & # write RPC generated with "current" inode timestamp, but delayed
4072         sleep 1
4073         touch --date="$DATESTR" $DIR/$tdir/$tfile # setattr timestamp in past
4074         LS_BEFORE="`ls -l $DIR/$tdir/$tfile`" # old timestamp from client cache
4075         cancel_lru_locks $OSC
4076         LS_AFTER="`ls -l $DIR/$tdir/$tfile`"  # timestamp from OST object
4077         date; date +%s
4078         [ "$LS_BEFORE" != "$LS_AFTER" ] && \
4079                 echo "BEFORE: $LS_BEFORE" && \
4080                 echo "AFTER : $LS_AFTER" && \
4081                 echo "WANT  : $DATESTR" && \
4082                 error "$DIR/$tdir/$tfile timestamps changed" || true
4083
4084         export LANG=$LANG_SAVE LC_LANG=$LC_LANG_SAVE
4085 }
4086
4087 test_36f() {
4088         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4089
4090         #define OBD_FAIL_OST_BRW_PAUSE_BULK 0x214
4091         subr_36fh "0x80000214"
4092 }
4093 run_test 36f "utime on file racing with OST BRW write =========="
4094
4095 test_36g() {
4096         remote_ost_nodsh && skip "remote OST with nodsh"
4097         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4098         [ $MDS1_VERSION -lt $(version_code 2.12.51) ] &&
4099                 skip "Need MDS version at least 2.12.51"
4100
4101         local fmd_max_age
4102         local fmd
4103         local facet="ost1"
4104         local tgt="obdfilter"
4105
4106         [[ $OSC == "mdc" ]] && tgt="mdt" && facet="mds1"
4107
4108         test_mkdir $DIR/$tdir
4109         fmd_max_age=$(do_facet $facet \
4110                 "lctl get_param -n $tgt.*.tgt_fmd_seconds 2> /dev/null | \
4111                 head -n 1")
4112
4113         echo "FMD max age: ${fmd_max_age}s"
4114         touch $DIR/$tdir/$tfile
4115         fmd=$(do_facet $facet "lctl get_param -n $tgt.*.exports.*.fmd_count" |
4116                 gawk '{cnt=cnt+$1}  END{print cnt}')
4117         echo "FMD before: $fmd"
4118         [[ $fmd == 0 ]] &&
4119                 error "FMD wasn't create by touch"
4120         sleep $((fmd_max_age + 12))
4121         fmd=$(do_facet $facet "lctl get_param -n $tgt.*.exports.*.fmd_count" |
4122                 gawk '{cnt=cnt+$1}  END{print cnt}')
4123         echo "FMD after: $fmd"
4124         [[ $fmd == 0 ]] ||
4125                 error "FMD wasn't expired by ping"
4126 }
4127 run_test 36g "FMD cache expiry ====================="
4128
4129 test_36h() {
4130         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4131
4132         #define OBD_FAIL_OST_BRW_PAUSE_BULK2 0x227
4133         subr_36fh "0x80000227"
4134 }
4135 run_test 36h "utime on file racing with OST BRW write =========="
4136
4137 test_36i() {
4138         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
4139
4140         test_mkdir $DIR/$tdir
4141         $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir
4142
4143         local mtime=$(stat -c%Y $DIR/$tdir/striped_dir)
4144         local new_mtime=$((mtime + 200))
4145
4146         #change Modify time of striped dir
4147         touch -m -d @$new_mtime $DIR/$tdir/striped_dir ||
4148                         error "change mtime failed"
4149
4150         local got=$(stat -c%Y $DIR/$tdir/striped_dir)
4151
4152         [ "$new_mtime" = "$got" ] || error "expect $new_mtime got $got"
4153 }
4154 run_test 36i "change mtime on striped directory"
4155
4156 # test_37 - duplicate with tests 32q 32r
4157
4158 test_38() {
4159         local file=$DIR/$tfile
4160         touch $file
4161         openfile -f O_DIRECTORY $file
4162         local RC=$?
4163         local ENOTDIR=20
4164         [ $RC -eq 0 ] && error "opened file $file with O_DIRECTORY" || true
4165         [ $RC -eq $ENOTDIR ] || error "error $RC should be ENOTDIR ($ENOTDIR)"
4166 }
4167 run_test 38 "open a regular file with O_DIRECTORY should return -ENOTDIR ==="
4168
4169 test_39a() { # was test_39
4170         touch $DIR/$tfile
4171         touch $DIR/${tfile}2
4172 #       ls -l  $DIR/$tfile $DIR/${tfile}2
4173 #       ls -lu  $DIR/$tfile $DIR/${tfile}2
4174 #       ls -lc  $DIR/$tfile $DIR/${tfile}2
4175         sleep 2
4176         $OPENFILE -f O_CREAT:O_TRUNC:O_WRONLY $DIR/${tfile}2
4177         if [ ! $DIR/${tfile}2 -nt $DIR/$tfile ]; then
4178                 echo "mtime"
4179                 ls -l --full-time $DIR/$tfile $DIR/${tfile}2
4180                 echo "atime"
4181                 ls -lu --full-time $DIR/$tfile $DIR/${tfile}2
4182                 echo "ctime"
4183                 ls -lc --full-time $DIR/$tfile $DIR/${tfile}2
4184                 error "O_TRUNC didn't change timestamps"
4185         fi
4186 }
4187 run_test 39a "mtime changed on create"
4188
4189 test_39b() {
4190         test_mkdir -c1 $DIR/$tdir
4191         cp -p /etc/passwd $DIR/$tdir/fopen
4192         cp -p /etc/passwd $DIR/$tdir/flink
4193         cp -p /etc/passwd $DIR/$tdir/funlink
4194         cp -p /etc/passwd $DIR/$tdir/frename
4195         ln $DIR/$tdir/funlink $DIR/$tdir/funlink2
4196
4197         sleep 1
4198         echo "aaaaaa" >> $DIR/$tdir/fopen
4199         echo "aaaaaa" >> $DIR/$tdir/flink
4200         echo "aaaaaa" >> $DIR/$tdir/funlink
4201         echo "aaaaaa" >> $DIR/$tdir/frename
4202
4203         local open_new=`stat -c %Y $DIR/$tdir/fopen`
4204         local link_new=`stat -c %Y $DIR/$tdir/flink`
4205         local unlink_new=`stat -c %Y $DIR/$tdir/funlink`
4206         local rename_new=`stat -c %Y $DIR/$tdir/frename`
4207
4208         cat $DIR/$tdir/fopen > /dev/null
4209         ln $DIR/$tdir/flink $DIR/$tdir/flink2
4210         rm -f $DIR/$tdir/funlink2
4211         mv -f $DIR/$tdir/frename $DIR/$tdir/frename2
4212
4213         for (( i=0; i < 2; i++ )) ; do
4214                 local open_new2=`stat -c %Y $DIR/$tdir/fopen`
4215                 local link_new2=`stat -c %Y $DIR/$tdir/flink`
4216                 local unlink_new2=`stat -c %Y $DIR/$tdir/funlink`
4217                 local rename_new2=`stat -c %Y $DIR/$tdir/frename2`
4218
4219                 [ $open_new2 -eq $open_new ] || error "open file reverses mtime"
4220                 [ $link_new2 -eq $link_new ] || error "link file reverses mtime"
4221                 [ $unlink_new2 -eq $unlink_new ] || error "unlink file reverses mtime"
4222                 [ $rename_new2 -eq $rename_new ] || error "rename file reverses mtime"
4223
4224                 cancel_lru_locks $OSC
4225                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4226         done
4227 }
4228 run_test 39b "mtime change on open, link, unlink, rename  ======"
4229
4230 # this should be set to past
4231 TEST_39_MTIME=`date -d "1 year ago" +%s`
4232
4233 # bug 11063
4234 test_39c() {
4235         touch $DIR1/$tfile
4236         sleep 2
4237         local mtime0=`stat -c %Y $DIR1/$tfile`
4238
4239         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4240         local mtime1=`stat -c %Y $DIR1/$tfile`
4241         [ "$mtime1" = $TEST_39_MTIME ] || \
4242                 error "mtime is not set to past: $mtime1, should be $TEST_39_MTIME"
4243
4244         local d1=`date +%s`
4245         echo hello >> $DIR1/$tfile
4246         local d2=`date +%s`
4247         local mtime2=`stat -c %Y $DIR1/$tfile`
4248         [ "$mtime2" -ge "$d1" ] && [ "$mtime2" -le "$d2" ] || \
4249                 error "mtime is not updated on write: $d1 <= $mtime2 <= $d2"
4250
4251         mv $DIR1/$tfile $DIR1/$tfile-1
4252
4253         for (( i=0; i < 2; i++ )) ; do
4254                 local mtime3=`stat -c %Y $DIR1/$tfile-1`
4255                 [ "$mtime2" = "$mtime3" ] || \
4256                         error "mtime ($mtime2) changed (to $mtime3) on rename"
4257
4258                 cancel_lru_locks $OSC
4259                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4260         done
4261 }
4262 run_test 39c "mtime change on rename ==========================="
4263
4264 # bug 21114
4265 test_39d() {
4266         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4267
4268         touch $DIR1/$tfile
4269         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4270
4271         for (( i=0; i < 2; i++ )) ; do
4272                 local mtime=`stat -c %Y $DIR1/$tfile`
4273                 [ $mtime = $TEST_39_MTIME ] || \
4274                         error "mtime($mtime) is not set to $TEST_39_MTIME"
4275
4276                 cancel_lru_locks $OSC
4277                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4278         done
4279 }
4280 run_test 39d "create, utime, stat =============================="
4281
4282 # bug 21114
4283 test_39e() {
4284         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4285
4286         touch $DIR1/$tfile
4287         local mtime1=`stat -c %Y $DIR1/$tfile`
4288
4289         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4290
4291         for (( i=0; i < 2; i++ )) ; do
4292                 local mtime2=`stat -c %Y $DIR1/$tfile`
4293                 [ $mtime2 = $TEST_39_MTIME ] || \
4294                         error "mtime($mtime2) is not set to $TEST_39_MTIME"
4295
4296                 cancel_lru_locks $OSC
4297                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4298         done
4299 }
4300 run_test 39e "create, stat, utime, stat ========================"
4301
4302 # bug 21114
4303 test_39f() {
4304         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4305
4306         touch $DIR1/$tfile
4307         mtime1=`stat -c %Y $DIR1/$tfile`
4308
4309         sleep 2
4310         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4311
4312         for (( i=0; i < 2; i++ )) ; do
4313                 local mtime2=`stat -c %Y $DIR1/$tfile`
4314                 [ $mtime2 = $TEST_39_MTIME ] || \
4315                         error "mtime($mtime2) is not set to $TEST_39_MTIME"
4316
4317                 cancel_lru_locks $OSC
4318                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4319         done
4320 }
4321 run_test 39f "create, stat, sleep, utime, stat ================="
4322
4323 # bug 11063
4324 test_39g() {
4325         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4326
4327         echo hello >> $DIR1/$tfile
4328         local mtime1=`stat -c %Y $DIR1/$tfile`
4329
4330         sleep 2
4331         chmod o+r $DIR1/$tfile
4332
4333         for (( i=0; i < 2; i++ )) ; do
4334                 local mtime2=`stat -c %Y $DIR1/$tfile`
4335                 [ "$mtime1" = "$mtime2" ] || \
4336                         error "lost mtime: $mtime2, should be $mtime1"
4337
4338                 cancel_lru_locks $OSC
4339                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4340         done
4341 }
4342 run_test 39g "write, chmod, stat ==============================="
4343
4344 # bug 11063
4345 test_39h() {
4346         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4347
4348         touch $DIR1/$tfile
4349         sleep 1
4350
4351         local d1=`date`
4352         echo hello >> $DIR1/$tfile
4353         local mtime1=`stat -c %Y $DIR1/$tfile`
4354
4355         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4356         local d2=`date`
4357         if [ "$d1" != "$d2" ]; then
4358                 echo "write and touch not within one second"
4359         else
4360                 for (( i=0; i < 2; i++ )) ; do
4361                         local mtime2=`stat -c %Y $DIR1/$tfile`
4362                         [ "$mtime2" = $TEST_39_MTIME ] || \
4363                                 error "lost mtime: $mtime2, should be $TEST_39_MTIME"
4364
4365                         cancel_lru_locks $OSC
4366                         if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4367                 done
4368         fi
4369 }
4370 run_test 39h "write, utime within one second, stat ============="
4371
4372 test_39i() {
4373         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4374
4375         touch $DIR1/$tfile
4376         sleep 1
4377
4378         echo hello >> $DIR1/$tfile
4379         local mtime1=`stat -c %Y $DIR1/$tfile`
4380
4381         mv $DIR1/$tfile $DIR1/$tfile-1
4382
4383         for (( i=0; i < 2; i++ )) ; do
4384                 local mtime2=`stat -c %Y $DIR1/$tfile-1`
4385
4386                 [ "$mtime1" = "$mtime2" ] || \
4387                         error "lost mtime: $mtime2, should be $mtime1"
4388
4389                 cancel_lru_locks $OSC
4390                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4391         done
4392 }
4393 run_test 39i "write, rename, stat =============================="
4394
4395 test_39j() {
4396         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4397
4398         start_full_debug_logging
4399         touch $DIR1/$tfile
4400         sleep 1
4401
4402         #define OBD_FAIL_OSC_DELAY_SETTIME       0x412
4403         lctl set_param fail_loc=0x80000412
4404         multiop_bg_pause $DIR1/$tfile oO_RDWR:w2097152_c ||
4405                 error "multiop failed"
4406         local multipid=$!
4407         local mtime1=`stat -c %Y $DIR1/$tfile`
4408
4409         mv $DIR1/$tfile $DIR1/$tfile-1
4410
4411         kill -USR1 $multipid
4412         wait $multipid || error "multiop close failed"
4413
4414         for (( i=0; i < 2; i++ )) ; do
4415                 local mtime2=`stat -c %Y $DIR1/$tfile-1`
4416                 [ "$mtime1" = "$mtime2" ] ||
4417                         error "mtime is lost on close: $mtime2, " \
4418                               "should be $mtime1"
4419
4420                 cancel_lru_locks
4421                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4422         done
4423         lctl set_param fail_loc=0
4424         stop_full_debug_logging
4425 }
4426 run_test 39j "write, rename, close, stat ======================="
4427
4428 test_39k() {
4429         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4430
4431         touch $DIR1/$tfile
4432         sleep 1
4433
4434         multiop_bg_pause $DIR1/$tfile oO_RDWR:w2097152_c || error "multiop failed"
4435         local multipid=$!
4436         local mtime1=`stat -c %Y $DIR1/$tfile`
4437
4438         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4439
4440         kill -USR1 $multipid
4441         wait $multipid || error "multiop close failed"
4442
4443         for (( i=0; i < 2; i++ )) ; do
4444                 local mtime2=`stat -c %Y $DIR1/$tfile`
4445
4446                 [ "$mtime2" = $TEST_39_MTIME ] || \
4447                         error "mtime is lost on close: $mtime2, should be $TEST_39_MTIME"
4448
4449                 cancel_lru_locks
4450                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4451         done
4452 }
4453 run_test 39k "write, utime, close, stat ========================"
4454
4455 # this should be set to future
4456 TEST_39_ATIME=`date -d "1 year" +%s`
4457
4458 test_39l() {
4459         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4460         remote_mds_nodsh && skip "remote MDS with nodsh"
4461
4462         local atime_diff=$(do_facet $SINGLEMDS \
4463                                 lctl get_param -n mdd.*MDT0000*.atime_diff)
4464         rm -rf $DIR/$tdir
4465         mkdir -p $DIR/$tdir
4466
4467         # test setting directory atime to future
4468         touch -a -d @$TEST_39_ATIME $DIR/$tdir
4469         local atime=$(stat -c %X $DIR/$tdir)
4470         [ "$atime" = $TEST_39_ATIME ] ||
4471                 error "atime is not set to future: $atime, $TEST_39_ATIME"
4472
4473         # test setting directory atime from future to now
4474         local now=$(date +%s)
4475         touch -a -d @$now $DIR/$tdir
4476
4477         atime=$(stat -c %X $DIR/$tdir)
4478         [ "$atime" -eq "$now"  ] ||
4479                 error "atime is not updated from future: $atime, $now"
4480
4481         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=2
4482         sleep 3
4483
4484         # test setting directory atime when now > dir atime + atime_diff
4485         local d1=$(date +%s)
4486         ls $DIR/$tdir
4487         local d2=$(date +%s)
4488         cancel_lru_locks mdc
4489         atime=$(stat -c %X $DIR/$tdir)
4490         [ "$atime" -ge "$d1" -a "$atime" -le "$d2" ] ||
4491                 error "atime is not updated  : $atime, should be $d2"
4492
4493         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=60
4494         sleep 3
4495
4496         # test not setting directory atime when now < dir atime + atime_diff
4497         ls $DIR/$tdir
4498         cancel_lru_locks mdc
4499         atime=$(stat -c %X $DIR/$tdir)
4500         [ "$atime" -ge "$d1" -a "$atime" -le "$d2" ] ||
4501                 error "atime is updated to $atime, should remain $d1<atime<$d2"
4502
4503         do_facet $SINGLEMDS \
4504                 lctl set_param -n mdd.*MDT0000*.atime_diff=$atime_diff
4505 }
4506 run_test 39l "directory atime update ==========================="
4507
4508 test_39m() {
4509         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4510
4511         touch $DIR1/$tfile
4512         sleep 2
4513         local far_past_mtime=$(date -d "May 29 1953" +%s)
4514         local far_past_atime=$(date -d "Dec 17 1903" +%s)
4515
4516         touch -m -d @$far_past_mtime $DIR1/$tfile
4517         touch -a -d @$far_past_atime $DIR1/$tfile
4518
4519         for (( i=0; i < 2; i++ )) ; do
4520                 local timestamps=$(stat -c "%X %Y" $DIR1/$tfile)
4521                 [ "$timestamps" = "$far_past_atime $far_past_mtime" ] || \
4522                         error "atime or mtime set incorrectly"
4523
4524                 cancel_lru_locks $OSC
4525                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4526         done
4527 }
4528 run_test 39m "test atime and mtime before 1970"
4529
4530 test_39n() { # LU-3832
4531         remote_mds_nodsh && skip "remote MDS with nodsh"
4532
4533         local atime_diff=$(do_facet $SINGLEMDS \
4534                 lctl get_param -n mdd.*MDT0000*.atime_diff)
4535         local atime0
4536         local atime1
4537         local atime2
4538
4539         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=1
4540
4541         rm -rf $DIR/$tfile
4542         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 status=noxfer
4543         atime0=$(stat -c %X $DIR/$tfile)
4544
4545         sleep 5
4546         $MULTIOP $DIR/$tfile oO_RDONLY:O_NOATIME:r4096c
4547         atime1=$(stat -c %X $DIR/$tfile)
4548
4549         sleep 5
4550         cancel_lru_locks mdc
4551         cancel_lru_locks osc
4552         $MULTIOP $DIR/$tfile oO_RDONLY:O_NOATIME:r4096c
4553         atime2=$(stat -c %X $DIR/$tfile)
4554
4555         do_facet $SINGLEMDS \
4556                 lctl set_param -n mdd.*MDT0000*.atime_diff=$atime_diff
4557
4558         [ "$atime0" -eq "$atime1" ] || error "atime0 $atime0 != atime1 $atime1"
4559         [ "$atime1" -eq "$atime2" ] || error "atime0 $atime0 != atime1 $atime1"
4560 }
4561 run_test 39n "check that O_NOATIME is honored"
4562
4563 test_39o() {
4564         TESTDIR=$DIR/$tdir/$tfile
4565         [ -e $TESTDIR ] && rm -rf $TESTDIR
4566         mkdir -p $TESTDIR
4567         cd $TESTDIR
4568         links1=2
4569         ls
4570         mkdir a b
4571         ls
4572         links2=$(stat -c %h .)
4573         [ $(($links1 + 2)) != $links2 ] &&
4574                 error "wrong links count $(($links1 + 2)) != $links2"
4575         rmdir b
4576         links3=$(stat -c %h .)
4577         [ $(($links1 + 1)) != $links3 ] &&
4578                 error "wrong links count $links1 != $links3"
4579         return 0
4580 }
4581 run_test 39o "directory cached attributes updated after create"
4582
4583 test_39p() {
4584         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
4585
4586         local MDTIDX=1
4587         TESTDIR=$DIR/$tdir/$tdir
4588         [ -e $TESTDIR ] && rm -rf $TESTDIR
4589         test_mkdir -p $TESTDIR
4590         cd $TESTDIR
4591         links1=2
4592         ls
4593         test_mkdir -i $MDTIDX $TESTDIR/remote_dir1
4594         test_mkdir -i $MDTIDX $TESTDIR/remote_dir2
4595         ls
4596         links2=$(stat -c %h .)
4597         [ $(($links1 + 2)) != $links2 ] &&
4598                 error "wrong links count $(($links1 + 2)) != $links2"
4599         rmdir remote_dir2
4600         links3=$(stat -c %h .)
4601         [ $(($links1 + 1)) != $links3 ] &&
4602                 error "wrong links count $links1 != $links3"
4603         return 0
4604 }
4605 run_test 39p "remote directory cached attributes updated after create ========"
4606
4607 test_39r() {
4608         [ $OST1_VERSION -ge $(version_code 2.13.52) ] ||
4609                 skip "no atime update on old OST"
4610         if [ "$ost1_FSTYPE" != ldiskfs ]; then
4611                 skip_env "ldiskfs only test"
4612         fi
4613
4614         local saved_adiff
4615         saved_adiff=$(do_facet ost1 \
4616                 lctl get_param -n obdfilter.*OST0000.atime_diff)
4617         stack_trap "do_facet ost1 \
4618                 lctl set_param obdfilter.*.atime_diff=$saved_adiff"
4619
4620         do_facet ost1 "lctl set_param obdfilter.*.atime_diff=5"
4621
4622         $LFS setstripe -i 0 $DIR/$tfile
4623         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 ||
4624                 error "can't write initial file"
4625         cancel_lru_locks osc
4626
4627         # exceed atime_diff and access file
4628         sleep 6
4629         dd if=$DIR/$tfile of=/dev/null || error "can't udpate atime"
4630
4631         local atime_cli=$(stat -c %X $DIR/$tfile)
4632         echo "client atime: $atime_cli"
4633         # allow atime update to be written to device
4634         do_facet ost1 "$LCTL set_param -n osd*.*OST*.force_sync 1"
4635         sleep 5
4636
4637         local ostdev=$(ostdevname 1)
4638         local fid=($(lfs getstripe -y $DIR/$tfile |
4639                         awk '/l_fid:/ { print $2 }' | tr ':' ' '))
4640         local objpath="O/0/d$((${fid[1]} % 32))/$((${fid[1]}))"
4641         local cmd="debugfs -c -R \\\"stat $objpath\\\" $ostdev"
4642
4643         echo "OST atime: $(do_facet ost1 "$cmd" |& grep atime)"
4644         local atime_ost=$(do_facet ost1 "$cmd" |&
4645                           awk -F'[: ]' '/atime:/ { print $4 }')
4646         (( atime_cli == atime_ost )) ||
4647                 error "atime on client $atime_cli != ost $atime_ost"
4648 }
4649 run_test 39r "lazy atime update on OST"
4650
4651 test_39q() { # LU-8041
4652         local testdir=$DIR/$tdir
4653         mkdir -p $testdir
4654         multiop_bg_pause $testdir D_c || error "multiop failed"
4655         local multipid=$!
4656         cancel_lru_locks mdc
4657         kill -USR1 $multipid
4658         local atime=$(stat -c %X $testdir)
4659         [ "$atime" -ne 0 ] || error "atime is zero"
4660 }
4661 run_test 39q "close won't zero out atime"
4662
4663 test_40() {
4664         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1
4665         $RUNAS $OPENFILE -f O_WRONLY:O_TRUNC $DIR/$tfile &&
4666                 error "openfile O_WRONLY:O_TRUNC $tfile failed"
4667         $CHECKSTAT -t file -s 4096 $DIR/$tfile ||
4668                 error "$tfile is not 4096 bytes in size"
4669 }
4670 run_test 40 "failed open(O_TRUNC) doesn't truncate ============="
4671
4672 test_41() {
4673         # bug 1553
4674         small_write $DIR/f41 18
4675 }
4676 run_test 41 "test small file write + fstat ====================="
4677
4678 count_ost_writes() {
4679         lctl get_param -n ${OSC}.*.stats |
4680                 awk -vwrites=0 '/ost_write/ { writes += $2 } \
4681                         END { printf("%0.0f", writes) }'
4682 }
4683
4684 # decent default
4685 WRITEBACK_SAVE=500
4686 DIRTY_RATIO_SAVE=40
4687 MAX_DIRTY_RATIO=50
4688 BG_DIRTY_RATIO_SAVE=10
4689 MAX_BG_DIRTY_RATIO=25
4690
4691 start_writeback() {
4692         trap 0
4693         # in 2.6, restore /proc/sys/vm/dirty_writeback_centisecs,
4694         # dirty_ratio, dirty_background_ratio
4695         if [ -f /proc/sys/vm/dirty_writeback_centisecs ]; then
4696                 sysctl -w vm.dirty_writeback_centisecs=$WRITEBACK_SAVE
4697                 sysctl -w vm.dirty_background_ratio=$BG_DIRTY_RATIO_SAVE
4698                 sysctl -w vm.dirty_ratio=$DIRTY_RATIO_SAVE
4699         else
4700                 # if file not here, we are a 2.4 kernel
4701                 kill -CONT `pidof kupdated`
4702         fi
4703 }
4704
4705 stop_writeback() {
4706         # setup the trap first, so someone cannot exit the test at the
4707         # exact wrong time and mess up a machine
4708         trap start_writeback EXIT
4709         # in 2.6, save and 0 /proc/sys/vm/dirty_writeback_centisecs
4710         if [ -f /proc/sys/vm/dirty_writeback_centisecs ]; then
4711                 WRITEBACK_SAVE=`sysctl -n vm.dirty_writeback_centisecs`
4712                 sysctl -w vm.dirty_writeback_centisecs=0
4713                 sysctl -w vm.dirty_writeback_centisecs=0
4714                 # save and increase /proc/sys/vm/dirty_ratio
4715                 DIRTY_RATIO_SAVE=`sysctl -n vm.dirty_ratio`
4716                 sysctl -w vm.dirty_ratio=$MAX_DIRTY_RATIO
4717                 # save and increase /proc/sys/vm/dirty_background_ratio
4718                 BG_DIRTY_RATIO_SAVE=`sysctl -n vm.dirty_background_ratio`
4719                 sysctl -w vm.dirty_background_ratio=$MAX_BG_DIRTY_RATIO
4720         else
4721                 # if file not here, we are a 2.4 kernel
4722                 kill -STOP `pidof kupdated`
4723         fi
4724 }
4725
4726 # ensure that all stripes have some grant before we test client-side cache
4727 setup_test42() {
4728         for i in `seq -f $DIR/f42-%g 1 $OSTCOUNT`; do
4729                 dd if=/dev/zero of=$i bs=4k count=1
4730                 rm $i
4731         done
4732 }
4733
4734 # Tests 42* verify that our behaviour is correct WRT caching, file closure,
4735 # file truncation, and file removal.
4736 test_42a() {
4737         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4738
4739         setup_test42
4740         cancel_lru_locks $OSC
4741         stop_writeback
4742         sync; sleep 1; sync # just to be safe
4743         BEFOREWRITES=`count_ost_writes`
4744         lctl get_param -n osc.*[oO][sS][cC][_-]*.cur_grant_bytes | grep "[0-9]"
4745         dd if=/dev/zero of=$DIR/f42a bs=1024 count=100
4746         AFTERWRITES=`count_ost_writes`
4747         [ $BEFOREWRITES -eq $AFTERWRITES ] || \
4748                 error "$BEFOREWRITES < $AFTERWRITES"
4749         start_writeback
4750 }
4751 run_test 42a "ensure that we don't flush on close"
4752
4753 test_42b() {
4754         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4755
4756         setup_test42
4757         cancel_lru_locks $OSC
4758         stop_writeback
4759         sync
4760         dd if=/dev/zero of=$DIR/f42b bs=1024 count=100
4761         BEFOREWRITES=$(count_ost_writes)
4762         $MUNLINK $DIR/f42b || error "$MUNLINK $DIR/f42b: $?"
4763         AFTERWRITES=$(count_ost_writes)
4764         if [[ $BEFOREWRITES -lt $AFTERWRITES ]]; then
4765                 error "$BEFOREWRITES < $AFTERWRITES on unlink"
4766         fi
4767         BEFOREWRITES=$(count_ost_writes)
4768         sync || error "sync: $?"
4769         AFTERWRITES=$(count_ost_writes)
4770         if [[ $BEFOREWRITES -lt $AFTERWRITES ]]; then
4771                 error "$BEFOREWRITES < $AFTERWRITES on sync"
4772         fi
4773         dmesg | grep 'error from obd_brw_async' && error 'error writing back'
4774         start_writeback
4775         return 0
4776 }
4777 run_test 42b "test destroy of file with cached dirty data ======"
4778
4779 # if these tests just want to test the effect of truncation,
4780 # they have to be very careful.  consider:
4781 # - the first open gets a {0,EOF}PR lock
4782 # - the first write conflicts and gets a {0, count-1}PW
4783 # - the rest of the writes are under {count,EOF}PW
4784 # - the open for truncate tries to match a {0,EOF}PR
4785 #   for the filesize and cancels the PWs.
4786 # any number of fixes (don't get {0,EOF} on open, match
4787 # composite locks, do smarter file size management) fix
4788 # this, but for now we want these tests to verify that
4789 # the cancellation with truncate intent works, so we
4790 # start the file with a full-file pw lock to match against
4791 # until the truncate.
4792 trunc_test() {
4793         test=$1
4794         file=$DIR/$test
4795         offset=$2
4796         cancel_lru_locks $OSC
4797         stop_writeback
4798         # prime the file with 0,EOF PW to match
4799         touch $file
4800         $TRUNCATE $file 0
4801         sync; sync
4802         # now the real test..
4803         dd if=/dev/zero of=$file bs=1024 count=100
4804         BEFOREWRITES=`count_ost_writes`
4805         $TRUNCATE $file $offset
4806         cancel_lru_locks $OSC
4807         AFTERWRITES=`count_ost_writes`
4808         start_writeback
4809 }
4810
4811 test_42c() {
4812         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4813
4814         trunc_test 42c 1024
4815         [ $BEFOREWRITES -eq $AFTERWRITES ] &&
4816                 error "beforewrites $BEFOREWRITES == afterwrites $AFTERWRITES on truncate"
4817         rm $file
4818 }
4819 run_test 42c "test partial truncate of file with cached dirty data"
4820
4821 test_42d() {
4822         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4823
4824         trunc_test 42d 0
4825         [ $BEFOREWRITES -eq $AFTERWRITES ] ||
4826                 error "beforewrites $BEFOREWRITES != afterwrites $AFTERWRITES on truncate"
4827         rm $file
4828 }
4829 run_test 42d "test complete truncate of file with cached dirty data"
4830
4831 test_42e() { # bug22074
4832         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4833
4834         local TDIR=$DIR/${tdir}e
4835         local pages=16 # hardcoded 16 pages, don't change it.
4836         local files=$((OSTCOUNT * 500)) # hopefully 500 files on each OST
4837         local proc_osc0="osc.${FSNAME}-OST0000-osc-[^MDT]*"
4838         local max_dirty_mb
4839         local warmup_files
4840
4841         test_mkdir $DIR/${tdir}e
4842         $LFS setstripe -c 1 $TDIR
4843         createmany -o $TDIR/f $files
4844
4845         max_dirty_mb=$($LCTL get_param -n $proc_osc0/max_dirty_mb)
4846
4847         # we assume that with $OSTCOUNT files, at least one of them will
4848         # be allocated on OST0.
4849         warmup_files=$((OSTCOUNT * max_dirty_mb))
4850         createmany -o $TDIR/w $warmup_files
4851
4852         # write a large amount of data into one file and sync, to get good
4853         # avail_grant number from OST.
4854         for ((i=0; i<$warmup_files; i++)); do
4855                 idx=$($LFS getstripe -i $TDIR/w$i)
4856                 [ $idx -ne 0 ] && continue
4857                 dd if=/dev/zero of=$TDIR/w$i bs="$max_dirty_mb"M count=1
4858                 break
4859         done
4860         [[ $i -gt $warmup_files ]] && error "OST0 is still cold"
4861         sync
4862         $LCTL get_param $proc_osc0/cur_dirty_bytes
4863         $LCTL get_param $proc_osc0/cur_grant_bytes
4864
4865         # create as much dirty pages as we can while not to trigger the actual
4866         # RPCs directly. but depends on the env, VFS may trigger flush during this
4867         # period, hopefully we are good.
4868         for ((i=0; i<$warmup_files; i++)); do
4869                 idx=$($LFS getstripe -i $TDIR/w$i)
4870                 [ $idx -ne 0 ] && continue
4871                 dd if=/dev/zero of=$TDIR/w$i bs=1M count=1 2>/dev/null
4872         done
4873         $LCTL get_param $proc_osc0/cur_dirty_bytes
4874         $LCTL get_param $proc_osc0/cur_grant_bytes
4875
4876         # perform the real test
4877         $LCTL set_param $proc_osc0/rpc_stats 0
4878         for ((;i<$files; i++)); do
4879                 [ $($LFS getstripe -i $TDIR/f$i) -eq 0 ] || continue
4880                 dd if=/dev/zero of=$TDIR/f$i bs=$PAGE_SIZE count=$pages 2>/dev/null
4881         done
4882         sync
4883         $LCTL get_param $proc_osc0/rpc_stats
4884
4885         local percent=0
4886         local have_ppr=false
4887         $LCTL get_param $proc_osc0/rpc_stats |
4888                 while read PPR RRPC RPCT RCUM BAR WRPC WPCT WCUM; do
4889                         # skip lines until we are at the RPC histogram data
4890                         [ "$PPR" == "pages" ] && have_ppr=true && continue
4891                         $have_ppr || continue
4892
4893                         # we only want the percent stat for < 16 pages
4894                         [[ $(echo $PPR | tr -d ':') -ge $pages ]] && break
4895
4896                         percent=$((percent + WPCT))
4897                         if [[ $percent -gt 15 ]]; then
4898                                 error "less than 16-pages write RPCs" \
4899                                       "$percent% > 15%"
4900                                 break
4901                         fi
4902                 done
4903         rm -rf $TDIR
4904 }
4905 run_test 42e "verify sub-RPC writes are not done synchronously"
4906
4907 test_43A() { # was test_43
4908         test_mkdir $DIR/$tdir
4909         cp -p /bin/ls $DIR/$tdir/$tfile
4910         $MULTIOP $DIR/$tdir/$tfile Ow_c &
4911         pid=$!
4912         # give multiop a chance to open
4913         sleep 1
4914
4915         $DIR/$tdir/$tfile && error "execute $DIR/$tdir/$tfile succeeded" || true
4916         kill -USR1 $pid
4917         # Wait for multiop to exit
4918         wait $pid
4919 }
4920 run_test 43A "execution of file opened for write should return -ETXTBSY"
4921
4922 test_43a() {
4923         test_mkdir $DIR/$tdir
4924         cp -p $(which sleep) $DIR/$tdir/sleep || error "can't copy"
4925         $DIR/$tdir/sleep 60 &
4926         SLEEP_PID=$!
4927         # Make sure exec of $tdir/sleep wins race with truncate
4928         sleep 1
4929         $MULTIOP $DIR/$tdir/sleep Oc && error "expected error, got success"
4930         kill $SLEEP_PID
4931 }
4932 run_test 43a "open(RDWR) of file being executed should return -ETXTBSY"
4933
4934 test_43b() {
4935         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4936
4937         test_mkdir $DIR/$tdir
4938         cp -p $(which sleep) $DIR/$tdir/sleep || error "can't copy"
4939         $DIR/$tdir/sleep 60 &
4940         SLEEP_PID=$!
4941         # Make sure exec of $tdir/sleep wins race with truncate
4942         sleep 1
4943         $TRUNCATE $DIR/$tdir/sleep 0 && error "expected error, got success"
4944         kill $SLEEP_PID
4945 }
4946 run_test 43b "truncate of file being executed should return -ETXTBSY"
4947
4948 test_43c() {
4949         local testdir="$DIR/$tdir"
4950         test_mkdir $testdir
4951         cp $SHELL $testdir/
4952         ( cd $(dirname $SHELL) && md5sum $(basename $SHELL) ) |
4953                 ( cd $testdir && md5sum -c )
4954 }
4955 run_test 43c "md5sum of copy into lustre"
4956
4957 test_44A() { # was test_44
4958         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
4959
4960         dd if=/dev/zero of=$DIR/f1 bs=4k count=1 seek=1023
4961         dd if=$DIR/f1 bs=4k count=1 > /dev/null
4962 }
4963 run_test 44A "zero length read from a sparse stripe"
4964
4965 test_44a() {
4966         local nstripe=$($LCTL lov_getconfig $DIR | grep default_stripe_count: |
4967                 awk '{ print $2 }')
4968         [ -z "$nstripe" ] && skip "can't get stripe info"
4969         [[ $nstripe -gt $OSTCOUNT ]] &&
4970                 skip "Wrong default_stripe_count: $nstripe OSTCOUNT: $OSTCOUNT"
4971
4972         local stride=$($LCTL lov_getconfig $DIR | grep default_stripe_size: |
4973                 awk '{ print $2 }')
4974         if [[ $nstripe -eq 0 || $nstripe -eq -1 ]]; then
4975                 nstripe=$($LCTL lov_getconfig $DIR | grep obd_count: |
4976                         awk '{ print $2 }')
4977         fi
4978
4979         OFFSETS="0 $((stride/2)) $((stride-1))"
4980         for offset in $OFFSETS; do
4981                 for i in $(seq 0 $((nstripe-1))); do
4982                         local GLOBALOFFSETS=""
4983                         # size in Bytes
4984                         local size=$((((i + 2 * $nstripe )*$stride + $offset)))
4985                         local myfn=$DIR/d44a-$size
4986                         echo "--------writing $myfn at $size"
4987                         ll_sparseness_write $myfn $size ||
4988                                 error "ll_sparseness_write"
4989                         GLOBALOFFSETS="$GLOBALOFFSETS $size"
4990                         ll_sparseness_verify $myfn $GLOBALOFFSETS ||
4991                                 error "ll_sparseness_verify $GLOBALOFFSETS"
4992
4993                         for j in $(seq 0 $((nstripe-1))); do
4994                                 # size in Bytes
4995                                 size=$((((j + $nstripe )*$stride + $offset)))
4996                                 ll_sparseness_write $myfn $size ||
4997                                         error "ll_sparseness_write"
4998                                 GLOBALOFFSETS="$GLOBALOFFSETS $size"
4999                         done
5000                         ll_sparseness_verify $myfn $GLOBALOFFSETS ||
5001                                 error "ll_sparseness_verify $GLOBALOFFSETS"
5002                         rm -f $myfn
5003                 done
5004         done
5005 }
5006 run_test 44a "test sparse pwrite ==============================="
5007
5008 dirty_osc_total() {
5009         tot=0
5010         for d in `lctl get_param -n ${OSC}.*.cur_dirty_bytes`; do
5011                 tot=$(($tot + $d))
5012         done
5013         echo $tot
5014 }
5015 do_dirty_record() {
5016         before=`dirty_osc_total`
5017         echo executing "\"$*\""
5018         eval $*
5019         after=`dirty_osc_total`
5020         echo before $before, after $after
5021 }
5022 test_45() {
5023         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5024
5025         f="$DIR/f45"
5026         # Obtain grants from OST if it supports it
5027         echo blah > ${f}_grant
5028         stop_writeback
5029         sync
5030         do_dirty_record "echo blah > $f"
5031         [[ $before -eq $after ]] && error "write wasn't cached"
5032         do_dirty_record "> $f"
5033         [[ $before -gt $after ]] || error "truncate didn't lower dirty count"
5034         do_dirty_record "echo blah > $f"
5035         [[ $before -eq $after ]] && error "write wasn't cached"
5036         do_dirty_record "sync"
5037         [[ $before -gt $after ]] || error "writeback didn't lower dirty count"
5038         do_dirty_record "echo blah > $f"
5039         [[ $before -eq $after ]] && error "write wasn't cached"
5040         do_dirty_record "cancel_lru_locks osc"
5041         [[ $before -gt $after ]] ||
5042                 error "lock cancellation didn't lower dirty count"
5043         start_writeback
5044 }
5045 run_test 45 "osc io page accounting ============================"
5046
5047 # in a 2 stripe file (lov.sh), page 1023 maps to page 511 in its object.  this
5048 # test tickles a bug where re-dirtying a page was failing to be mapped to the
5049 # objects offset and an assert hit when an rpc was built with 1023's mapped
5050 # offset 511 and 511's raw 511 offset. it also found general redirtying bugs.
5051 test_46() {
5052         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5053
5054         f="$DIR/f46"
5055         stop_writeback
5056         sync
5057         dd if=/dev/zero of=$f bs=$PAGE_SIZE seek=511 count=1
5058         sync
5059         dd conv=notrunc if=/dev/zero of=$f bs=$PAGE_SIZE seek=1023 count=1
5060         dd conv=notrunc if=/dev/zero of=$f bs=$PAGE_SIZE seek=511 count=1
5061         sync
5062         start_writeback
5063 }
5064 run_test 46 "dirtying a previously written page ================"
5065
5066 # test_47 is removed "Device nodes check" is moved to test_28
5067
5068 test_48a() { # bug 2399
5069         [ "$mds1_FSTYPE" = "zfs" ] &&
5070         [ $MDS1_VERSION -lt $(version_code 2.3.63) ] &&
5071                 skip "MDS prior to 2.3.63 handle ZFS dir .. incorrectly"
5072
5073         test_mkdir $DIR/$tdir
5074         cd $DIR/$tdir
5075         mv $DIR/$tdir $DIR/$tdir.new || error "move directory failed"
5076         test_mkdir $DIR/$tdir
5077         touch foo || error "'touch foo' failed after recreating cwd"
5078         test_mkdir bar
5079         touch .foo || error "'touch .foo' failed after recreating cwd"
5080         test_mkdir .bar
5081         ls . > /dev/null || error "'ls .' failed after recreating cwd"
5082         ls .. > /dev/null || error "'ls ..' failed after removing cwd"
5083         cd . || error "'cd .' failed after recreating cwd"
5084         mkdir . && error "'mkdir .' worked after recreating cwd"
5085         rmdir . && error "'rmdir .' worked after recreating cwd"
5086         ln -s . baz || error "'ln -s .' failed after recreating cwd"
5087         cd .. || error "'cd ..' failed after recreating cwd"
5088 }
5089 run_test 48a "Access renamed working dir (should return errors)="
5090
5091 test_48b() { # bug 2399
5092         rm -rf $DIR/$tdir
5093         test_mkdir $DIR/$tdir
5094         cd $DIR/$tdir
5095         rmdir $DIR/$tdir || error "remove cwd $DIR/$tdir failed"
5096         touch foo && error "'touch foo' worked after removing cwd"
5097         mkdir foo && error "'mkdir foo' worked after removing cwd"
5098         touch .foo && error "'touch .foo' worked after removing cwd"
5099         mkdir .foo && error "'mkdir .foo' worked after removing cwd"
5100         ls . > /dev/null && error "'ls .' worked after removing cwd"
5101         ls .. > /dev/null || error "'ls ..' failed after removing cwd"
5102         mkdir . && error "'mkdir .' worked after removing cwd"
5103         rmdir . && error "'rmdir .' worked after removing cwd"
5104         ln -s . foo && error "'ln -s .' worked after removing cwd"
5105         cd .. || echo "'cd ..' failed after removing cwd `pwd`"  #bug 3517
5106 }
5107 run_test 48b "Access removed working dir (should return errors)="
5108
5109 test_48c() { # bug 2350
5110         #lctl set_param debug=-1
5111         #set -vx
5112         rm -rf $DIR/$tdir
5113         test_mkdir -p $DIR/$tdir/dir
5114         cd $DIR/$tdir/dir
5115         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
5116         $TRACE touch foo && error "touch foo worked after removing cwd"
5117         $TRACE mkdir foo && error "'mkdir foo' worked after removing cwd"
5118         touch .foo && error "touch .foo worked after removing cwd"
5119         mkdir .foo && error "mkdir .foo worked after removing cwd"
5120         $TRACE ls . && error "'ls .' worked after removing cwd"
5121         $TRACE ls .. || error "'ls ..' failed after removing cwd"
5122         $TRACE mkdir . && error "'mkdir .' worked after removing cwd"
5123         $TRACE rmdir . && error "'rmdir .' worked after removing cwd"
5124         $TRACE ln -s . foo && error "'ln -s .' worked after removing cwd"
5125         $TRACE cd .. || echo "'cd ..' failed after removing cwd `pwd`" #bug 3415
5126 }
5127 run_test 48c "Access removed working subdir (should return errors)"
5128
5129 test_48d() { # bug 2350
5130         #lctl set_param debug=-1
5131         #set -vx
5132         rm -rf $DIR/$tdir
5133         test_mkdir -p $DIR/$tdir/dir
5134         cd $DIR/$tdir/dir
5135         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
5136         $TRACE rmdir $DIR/$tdir || error "remove parent $DIR/$tdir failed"
5137         $TRACE touch foo && error "'touch foo' worked after removing parent"
5138         $TRACE mkdir foo && error "mkdir foo worked after removing parent"
5139         touch .foo && error "'touch .foo' worked after removing parent"
5140         mkdir .foo && error "mkdir .foo worked after removing parent"
5141         $TRACE ls . && error "'ls .' worked after removing parent"
5142         $TRACE ls .. && error "'ls ..' worked after removing parent"
5143         $TRACE mkdir . && error "'mkdir .' worked after removing parent"
5144         $TRACE rmdir . && error "'rmdir .' worked after removing parent"
5145         $TRACE ln -s . foo && error "'ln -s .' worked after removing parent"
5146         true
5147 }
5148 run_test 48d "Access removed parent subdir (should return errors)"
5149
5150 test_48e() { # bug 4134
5151         #lctl set_param debug=-1
5152         #set -vx
5153         rm -rf $DIR/$tdir
5154         test_mkdir -p $DIR/$tdir/dir
5155         cd $DIR/$tdir/dir
5156         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
5157         $TRACE rmdir $DIR/$tdir || error "remove parent $DIR/$tdir failed"
5158         $TRACE touch $DIR/$tdir || error "'touch $DIR/$tdir' failed"
5159         $TRACE chmod +x $DIR/$tdir || error "'chmod +x $DIR/$tdir' failed"
5160         # On a buggy kernel addition of "touch foo" after cd .. will
5161         # produce kernel oops in lookup_hash_it
5162         touch ../foo && error "'cd ..' worked after recreate parent"
5163         cd $DIR
5164         $TRACE rm $DIR/$tdir || error "rm '$DIR/$tdir' failed"
5165 }
5166 run_test 48e "Access to recreated parent subdir (should return errors)"
5167
5168 test_48f() {
5169         [[ $MDS1_VERSION -ge $(version_code 2.13.55) ]] ||
5170                 skip "need MDS >= 2.13.55"
5171         [[ $MDSCOUNT -ge 2 ]] || skip "needs >= 2 MDTs"
5172         [[ "$(facet_host mds1)" != "$(facet_host mds2)" ]] ||
5173                 skip "needs different host for mdt1 mdt2"
5174         [[ $(facet_fstype mds1) == ldiskfs ]] || skip "ldiskfs only"
5175
5176         $LFS mkdir -i0 $DIR/$tdir
5177         $LFS mkdir -i 1 $DIR/$tdir/sub1 $DIR/$tdir/sub2 $DIR/$tdir/sub3
5178
5179         for d in sub1 sub2 sub3; do
5180                 #define OBD_FAIL_OSD_REF_DEL    0x19c
5181                 do_facet mds1 $LCTL set_param fail_loc=0x8000019c
5182                 rm -rf $DIR/$tdir/$d && error "rm $d should fail"
5183         done
5184
5185         rm -d --interactive=never $DIR/$tdir || error "rm $tdir fail"
5186 }
5187 run_test 48f "non-zero nlink dir unlink won't LBUG()"
5188
5189 test_49() { # LU-1030
5190         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5191         remote_ost_nodsh && skip "remote OST with nodsh"
5192
5193         # get ost1 size - $FSNAME-OST0000
5194         ost1_size=$(do_facet ost1 $LFS df | grep ${ost1_svc} |
5195                 awk '{ print $4 }')
5196         # write 800M at maximum
5197         [[ $ost1_size -lt 2 ]] && ost1_size=2
5198         [[ $ost1_size -gt 819200 ]] && ost1_size=819200
5199
5200         $LFS setstripe -c 1 -i 0 $DIR/$tfile
5201         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((ost1_size >> 2)) &
5202         local dd_pid=$!
5203
5204         # change max_pages_per_rpc while writing the file
5205         local osc1_mppc=osc.$(get_osc_import_name client ost1).max_pages_per_rpc
5206         local orig_mppc=$($LCTL get_param -n $osc1_mppc)
5207         # loop until dd process exits
5208         while ps ax -opid | grep -wq $dd_pid; do
5209                 $LCTL set_param $osc1_mppc=$((RANDOM % 256 + 1))
5210                 sleep $((RANDOM % 5 + 1))
5211         done
5212         # restore original max_pages_per_rpc
5213         $LCTL set_param $osc1_mppc=$orig_mppc
5214         rm $DIR/$tfile || error "rm $DIR/$tfile failed"
5215 }
5216 run_test 49 "Change max_pages_per_rpc won't break osc extent"
5217
5218 test_50() {
5219         # bug 1485
5220         test_mkdir $DIR/$tdir
5221         cd $DIR/$tdir
5222         ls /proc/$$/cwd || error "ls /proc/$$/cwd failed"
5223 }
5224 run_test 50 "special situations: /proc symlinks  ==============="
5225
5226 test_51a() {    # was test_51
5227         # bug 1516 - create an empty entry right after ".." then split dir
5228         test_mkdir -c1 $DIR/$tdir
5229         touch $DIR/$tdir/foo
5230         $MCREATE $DIR/$tdir/bar
5231         rm $DIR/$tdir/foo
5232         createmany -m $DIR/$tdir/longfile 201
5233         FNUM=202
5234         while [[ $(ls -sd $DIR/$tdir | awk '{ print $1 }') -eq 4 ]]; do
5235                 $MCREATE $DIR/$tdir/longfile$FNUM
5236                 FNUM=$(($FNUM + 1))
5237                 echo -n "+"
5238         done
5239         echo
5240         ls -l $DIR/$tdir > /dev/null || error "ls -l $DIR/$tdir failed"
5241 }
5242 run_test 51a "special situations: split htree with empty entry =="
5243
5244 cleanup_print_lfs_df () {
5245         trap 0
5246         $LFS df
5247         $LFS df -i
5248 }
5249
5250 test_51b() {
5251         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5252
5253         local dir=$DIR/$tdir
5254         local nrdirs=$((65536 + 100))
5255
5256         # cleanup the directory
5257         rm -fr $dir
5258
5259         test_mkdir -c1 $dir
5260
5261         $LFS df
5262         $LFS df -i
5263         local mdtidx=$(printf "%04x" $($LFS getstripe -m $dir))
5264         local numfree=$(lctl get_param -n mdc.$FSNAME-MDT$mdtidx*.filesfree)
5265         [[ $numfree -lt $nrdirs ]] &&
5266                 skip "not enough free inodes ($numfree) on MDT$mdtidx"
5267
5268         # need to check free space for the directories as well
5269         local blkfree=$(lctl get_param -n mdc.$FSNAME-MDT$mdtidx*.kbytesavail)
5270         numfree=$(( blkfree / $(fs_inode_ksize) ))
5271         [[ $numfree -lt $nrdirs ]] && skip "not enough blocks ($numfree)"
5272
5273         trap cleanup_print_lfs_df EXIT
5274
5275         # create files
5276         createmany -d $dir/d $nrdirs || {
5277                 unlinkmany $dir/d $nrdirs
5278                 error "failed to create $nrdirs subdirs in MDT$mdtidx:$dir"
5279         }
5280
5281         # really created :
5282         nrdirs=$(ls -U $dir | wc -l)
5283
5284         # unlink all but 100 subdirectories, then check it still works
5285         local left=100
5286         local delete=$((nrdirs - left))
5287
5288         $LFS df
5289         $LFS df -i
5290
5291         # for ldiskfs the nlink count should be 1, but this is OSD specific
5292         # and so this is listed for informational purposes only
5293         echo "nlink before: $(stat -c %h $dir), created before: $nrdirs"
5294         unlinkmany -d $dir/d $delete ||
5295                 error "unlink of first $delete subdirs failed"
5296
5297         echo "nlink between: $(stat -c %h $dir)"
5298         local found=$(ls -U $dir | wc -l)
5299         [ $found -ne $left ] &&
5300                 error "can't find subdirs: found only $found, expected $left"
5301
5302         unlinkmany -d $dir/d $delete $left ||
5303                 error "unlink of second $left subdirs failed"
5304         # regardless of whether the backing filesystem tracks nlink accurately
5305         # or not, the nlink count shouldn't be more than "." and ".." here
5306         local after=$(stat -c %h $dir)
5307         [[ $after -gt 2 ]] && error "nlink after: $after > 2" ||
5308                 echo "nlink after: $after"
5309
5310         cleanup_print_lfs_df
5311 }
5312 run_test 51b "exceed 64k subdirectory nlink limit on create, verify unlink"
5313
5314 test_51d() {
5315         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5316         [[ $OSTCOUNT -lt 3 ]] && skip_env "needs >= 3 OSTs"
5317
5318         test_mkdir $DIR/$tdir
5319         createmany -o $DIR/$tdir/t- 1000
5320         $LFS getstripe $DIR/$tdir > $TMP/$tfile
5321         for N in $(seq 0 $((OSTCOUNT - 1))); do
5322                 OBJS[$N]=$(awk -vobjs=0 '($1 == '$N') { objs += 1 } \
5323                         END { printf("%0.0f", objs) }' $TMP/$tfile)
5324                 OBJS0[$N]=$(grep -A 1 idx $TMP/$tfile | awk -vobjs=0 \
5325                         '($1 == '$N') { objs += 1 } \
5326                         END { printf("%0.0f", objs) }')
5327                 log "OST$N has ${OBJS[$N]} objects, ${OBJS0[$N]} are index 0"
5328         done
5329         unlinkmany $DIR/$tdir/t- 1000
5330
5331         NLAST=0
5332         for N in $(seq 1 $((OSTCOUNT - 1))); do
5333                 [[ ${OBJS[$N]} -lt $((${OBJS[$NLAST]} - 20)) ]] &&
5334                         error "OST $N has less objects vs OST $NLAST" \
5335                               " (${OBJS[$N]} < ${OBJS[$NLAST]}"
5336                 [[ ${OBJS[$N]} -gt $((${OBJS[$NLAST]} + 20)) ]] &&
5337                         error "OST $N has less objects vs OST $NLAST" \
5338                               " (${OBJS[$N]} < ${OBJS[$NLAST]}"
5339
5340                 [[ ${OBJS0[$N]} -lt $((${OBJS0[$NLAST]} - 20)) ]] &&
5341                         error "OST $N has less #0 objects vs OST $NLAST" \
5342                               " (${OBJS0[$N]} < ${OBJS0[$NLAST]}"
5343                 [[ ${OBJS0[$N]} -gt $((${OBJS0[$NLAST]} + 20)) ]] &&
5344                         error "OST $N has less #0 objects vs OST $NLAST" \
5345                               " (${OBJS0[$N]} < ${OBJS0[$NLAST]}"
5346                 NLAST=$N
5347         done
5348         rm -f $TMP/$tfile
5349 }
5350 run_test 51d "check object distribution"
5351
5352 test_51e() {
5353         if [ "$mds1_FSTYPE" != ldiskfs ]; then
5354                 skip_env "ldiskfs only test"
5355         fi
5356
5357         test_mkdir -c1 $DIR/$tdir
5358         test_mkdir -c1 $DIR/$tdir/d0
5359
5360         touch $DIR/$tdir/d0/foo
5361         createmany -l $DIR/$tdir/d0/foo $DIR/$tdir/d0/f- 65001 &&
5362                 error "file exceed 65000 nlink limit!"
5363         unlinkmany $DIR/$tdir/d0/f- 65001
5364         return 0
5365 }
5366 run_test 51e "check file nlink limit"
5367
5368 test_51f() {
5369         test_mkdir $DIR/$tdir
5370
5371         local max=100000
5372         local ulimit_old=$(ulimit -n)
5373         local spare=20 # number of spare fd's for scripts/libraries, etc.
5374         local mdt=$($LFS getstripe -m $DIR/$tdir)
5375         local numfree=$($LFS df -i $DIR/$tdir | awk '/MDT:'$mdt'/ { print $4 }')
5376
5377         echo "MDT$mdt numfree=$numfree, max=$max"
5378         [[ $numfree -gt $max ]] && numfree=$max || numfree=$((numfree * 7 / 8))
5379         if [ $((numfree + spare)) -gt $ulimit_old ]; then
5380                 while ! ulimit -n $((numfree + spare)); do
5381                         numfree=$((numfree * 3 / 4))
5382                 done
5383                 echo "changed ulimit from $ulimit_old to $((numfree + spare))"
5384         else
5385                 echo "left ulimit at $ulimit_old"
5386         fi
5387
5388         createmany -o -k -t 120 $DIR/$tdir/f $numfree || {
5389                 unlinkmany $DIR/$tdir/f $numfree
5390                 error "create+open $numfree files in $DIR/$tdir failed"
5391         }
5392         ulimit -n $ulimit_old
5393
5394         # if createmany exits at 120s there will be fewer than $numfree files
5395         unlinkmany $DIR/$tdir/f $numfree || true
5396 }
5397 run_test 51f "check many open files limit"
5398
5399 test_52a() {
5400         [ -f $DIR/$tdir/foo ] && chattr -a $DIR/$tdir/foo
5401         test_mkdir $DIR/$tdir
5402         touch $DIR/$tdir/foo
5403         chattr +a $DIR/$tdir/foo || error "chattr +a failed"
5404         echo bar >> $DIR/$tdir/foo || error "append bar failed"
5405         cp /etc/hosts $DIR/$tdir/foo && error "cp worked"
5406         rm -f $DIR/$tdir/foo 2>/dev/null && error "rm worked"
5407         link $DIR/$tdir/foo $DIR/$tdir/foo_link 2>/dev/null &&
5408                                         error "link worked"
5409         echo foo >> $DIR/$tdir/foo || error "append foo failed"
5410         mrename $DIR/$tdir/foo $DIR/$tdir/foo_ren && error "rename worked"
5411         lsattr $DIR/$tdir/foo | egrep -q "^-+a[-e]+ $DIR/$tdir/foo" ||
5412                                                      error "lsattr"
5413         chattr -a $DIR/$tdir/foo || error "chattr -a failed"
5414         cp -r $DIR/$tdir $TMP/
5415         rm -fr $DIR/$tdir $TMP/$tdir || error "cleanup rm failed"
5416 }
5417 run_test 52a "append-only flag test (should return errors)"
5418
5419 test_52b() {
5420         [ -f $DIR/$tdir/foo ] && chattr -i $DIR/$tdir/foo
5421         test_mkdir $DIR/$tdir
5422         touch $DIR/$tdir/foo
5423         chattr +i $DIR/$tdir/foo || error "chattr +i failed"
5424         cat test > $DIR/$tdir/foo && error "cat test worked"
5425         cp /etc/hosts $DIR/$tdir/foo && error "cp worked"
5426         rm -f $DIR/$tdir/foo 2>/dev/null && error "rm worked"
5427         link $DIR/$tdir/foo $DIR/$tdir/foo_link 2>/dev/null &&
5428                                         error "link worked"
5429         echo foo >> $DIR/$tdir/foo && error "echo worked"
5430         mrename $DIR/$tdir/foo $DIR/$tdir/foo_ren && error "rename worked"
5431         [ -f $DIR/$tdir/foo ] || error "$tdir/foo is not a file"
5432         [ -f $DIR/$tdir/foo_ren ] && error "$tdir/foo_ren is not a file"
5433         lsattr $DIR/$tdir/foo | egrep -q "^-+i[-e]+ $DIR/$tdir/foo" ||
5434                                                         error "lsattr"
5435         chattr -i $DIR/$tdir/foo || error "chattr failed"
5436
5437         rm -fr $DIR/$tdir || error "unable to remove $DIR/$tdir"
5438 }
5439 run_test 52b "immutable flag test (should return errors) ======="
5440
5441 test_53() {
5442         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5443         remote_mds_nodsh && skip "remote MDS with nodsh"
5444         remote_ost_nodsh && skip "remote OST with nodsh"
5445
5446         local param
5447         local param_seq
5448         local ostname
5449         local mds_last
5450         local mds_last_seq
5451         local ost_last
5452         local ost_last_seq
5453         local ost_last_id
5454         local ostnum
5455         local node
5456         local found=false
5457         local support_last_seq=true
5458
5459         [[ $MDS1_VERSION -ge $(version_code 2.3.60) ]] ||
5460                 support_last_seq=false
5461
5462         # only test MDT0000
5463         local mdtosc=$(get_mdtosc_proc_path $SINGLEMDS)
5464         local value
5465         for value in $(do_facet $SINGLEMDS \
5466                        $LCTL get_param osp.$mdtosc.prealloc_last_id) ; do
5467                 param=$(echo ${value[0]} | cut -d "=" -f1)
5468                 ostname=$(echo $param | cut -d "." -f2 | cut -d - -f 1-2)
5469
5470                 if $support_last_seq; then
5471                         param_seq=$(echo $param |
5472                                 sed -e s/prealloc_last_id/prealloc_last_seq/g)
5473                         mds_last_seq=$(do_facet $SINGLEMDS \
5474                                        $LCTL get_param -n $param_seq)
5475                 fi
5476                 mds_last=$(do_facet $SINGLEMDS $LCTL get_param -n $param)
5477
5478                 ostnum=$(index_from_ostuuid ${ostname}_UUID)
5479                 node=$(facet_active_host ost$((ostnum+1)))
5480                 param="obdfilter.$ostname.last_id"
5481                 for ost_last in $(do_node $node $LCTL get_param -n $param) ; do
5482                         echo "$ostname.last_id=$ost_last; MDS.last_id=$mds_last"
5483                         ost_last_id=$ost_last
5484
5485                         if $support_last_seq; then
5486                                 ost_last_id=$(echo $ost_last |
5487                                               awk -F':' '{print $2}' |
5488                                               sed -e "s/^0x//g")
5489                                 ost_last_seq=$(echo $ost_last |
5490                                                awk -F':' '{print $1}')
5491                                 [[ $ost_last_seq = $mds_last_seq ]] || continue
5492                         fi
5493
5494                         if [[ $ost_last_id != $mds_last ]]; then
5495                                 error "$ost_last_id != $mds_last"
5496                         else
5497                                 found=true
5498                                 break
5499                         fi
5500                 done
5501         done
5502         $found || error "can not match last_seq/last_id for $mdtosc"
5503         return 0
5504 }
5505 run_test 53 "verify that MDS and OSTs agree on pre-creation ===="
5506
5507 test_54a() {
5508         perl -MSocket -e ';' || skip "no Socket perl module installed"
5509
5510         $SOCKETSERVER $DIR/socket ||
5511                 error "$SOCKETSERVER $DIR/socket failed: $?"
5512         $SOCKETCLIENT $DIR/socket ||
5513                 error "$SOCKETCLIENT $DIR/socket failed: $?"
5514         $MUNLINK $DIR/socket || error "$MUNLINK $DIR/socket failed: $?"
5515 }
5516 run_test 54a "unix domain socket test =========================="
5517
5518 test_54b() {
5519         f="$DIR/f54b"
5520         mknod $f c 1 3
5521         chmod 0666 $f
5522         dd if=/dev/zero of=$f bs=$PAGE_SIZE count=1
5523 }
5524 run_test 54b "char device works in lustre ======================"
5525
5526 find_loop_dev() {
5527         [ -b /dev/loop/0 ] && LOOPBASE=/dev/loop/
5528         [ -b /dev/loop0 ] && LOOPBASE=/dev/loop
5529         [ -z "$LOOPBASE" ] && echo "/dev/loop/0 and /dev/loop0 gone?" && return
5530
5531         for i in $(seq 3 7); do
5532                 losetup $LOOPBASE$i > /dev/null 2>&1 && continue
5533                 LOOPDEV=$LOOPBASE$i
5534                 LOOPNUM=$i
5535                 break
5536         done
5537 }
5538
5539 cleanup_54c() {
5540         local rc=0
5541         loopdev="$DIR/loop54c"
5542
5543         trap 0
5544         $UMOUNT $DIR/$tdir || rc=$?
5545         losetup -d $loopdev || true
5546         losetup -d $LOOPDEV || true
5547         rm -rf $loopdev $DIR/$tfile $DIR/$tdir
5548         return $rc
5549 }
5550
5551 test_54c() {
5552         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5553
5554         loopdev="$DIR/loop54c"
5555
5556         find_loop_dev
5557         [ -z "$LOOPNUM" ] && skip_env "couldn't find empty loop device"
5558         trap cleanup_54c EXIT
5559         mknod $loopdev b 7 $LOOPNUM
5560         echo "make a loop file system with $DIR/$tfile on $loopdev ($LOOPNUM)."
5561         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE seek=1024 count=1 > /dev/null
5562         losetup $loopdev $DIR/$tfile ||
5563                 error "can't set up $loopdev for $DIR/$tfile"
5564         mkfs.ext2 $loopdev || error "mke2fs on $loopdev"
5565         test_mkdir $DIR/$tdir
5566         mount -t ext2 $loopdev $DIR/$tdir ||
5567                 error "error mounting $loopdev on $DIR/$tdir"
5568         dd if=/dev/zero of=$DIR/$tdir/tmp bs=$PAGE_SIZE count=30 ||
5569                 error "dd write"
5570         df $DIR/$tdir
5571         dd if=$DIR/$tdir/tmp of=/dev/zero bs=$PAGE_SIZE count=30 ||
5572                 error "dd read"
5573         cleanup_54c
5574 }
5575 run_test 54c "block device works in lustre ====================="
5576
5577 test_54d() {
5578         f="$DIR/f54d"
5579         string="aaaaaa"
5580         mknod $f p
5581         [ "$string" = $(echo $string > $f | cat $f) ] || error "$f != $string"
5582 }
5583 run_test 54d "fifo device works in lustre ======================"
5584
5585 test_54e() {
5586         f="$DIR/f54e"
5587         string="aaaaaa"
5588         cp -aL /dev/console $f
5589         echo $string > $f || error "echo $string to $f failed"
5590 }
5591 run_test 54e "console/tty device works in lustre ======================"
5592
5593 test_56a() {
5594         local numfiles=3
5595         local dir=$DIR/$tdir
5596
5597         rm -rf $dir
5598         test_mkdir -p $dir/dir
5599         for i in $(seq $numfiles); do
5600                 touch $dir/file$i
5601                 touch $dir/dir/file$i
5602         done
5603
5604         local numcomp=$($LFS getstripe --component-count $dir)
5605
5606         [[ $numcomp == 0 ]] && numcomp=1
5607
5608         # test lfs getstripe with --recursive
5609         local filenum=$($LFS getstripe -r $dir | egrep -c "obdidx|l_ost_idx")
5610
5611         [[ $filenum -eq $((numfiles * 2)) ]] ||
5612                 error "$LFS getstripe -r: found $filenum != $((numfiles * 2))"
5613         filenum=$($LFS getstripe $dir | egrep -c "obdidx|l_ost_idx")
5614         [[ $filenum -eq $numfiles ]] ||
5615                 error "$LFS getstripe $dir: found $filenum, not $numfiles"
5616         echo "$LFS getstripe showed obdidx or l_ost_idx"
5617
5618         # test lfs getstripe with file instead of dir
5619         filenum=$($LFS getstripe $dir/file1 | egrep -c "obdidx|l_ost_idx")
5620         [[ $filenum -eq 1 ]] ||
5621                 error "$LFS getstripe $dir/file1: found $filenum, not 1"
5622         echo "$LFS getstripe file1 passed"
5623
5624         #test lfs getstripe with --verbose
5625         filenum=$($LFS getstripe --verbose $dir | grep -c lmm_magic)
5626         [[ $filenum -eq $((numfiles * numcomp)) ]] ||
5627                 error "$LFS getstripe --verbose $dir: "\
5628                       "got $filenum want $((numfiles * numcomp)) lmm_magic"
5629         [[ $($LFS getstripe $dir | grep -c lmm_magic) -eq 0 ]] ||
5630                 error "$LFS getstripe $dir: showed lmm_magic"
5631
5632         #test lfs getstripe with -v prints lmm_fid
5633         filenum=$($LFS getstripe -v $dir | grep -c lmm_fid)
5634         [[ $filenum -eq $((numfiles * numcomp)) ]] ||
5635                 error "$LFS getstripe -v $dir: "\
5636                       "got $filenum want $((numfiles * numcomp)) lmm_fid"
5637         [[ $($LFS getstripe $dir | grep -c lmm_fid) -eq 0 ]] ||
5638                 error "$LFS getstripe $dir: showed lmm_fid by default"
5639         echo "$LFS getstripe --verbose passed"
5640
5641         #check for FID information
5642         local fid1=$($LFS getstripe --fid $dir/file1)
5643         local fid2=$($LFS getstripe --verbose $dir/file1 |
5644                      awk '/lmm_fid: / { print $2; exit; }')
5645         local fid3=$($LFS path2fid $dir/file1)
5646
5647         [ "$fid1" != "$fid2" ] &&
5648                 error "getstripe --fid '$fid1' != getstripe --verbose '$fid2'"
5649         [ "$fid1" != "$fid3" ] &&
5650                 error "getstripe --fid '$fid1' != lfs path2fid '$fid3'"
5651         echo "$LFS getstripe --fid passed"
5652
5653         #test lfs getstripe with --obd
5654         $LFS getstripe --obd wrong_uuid $dir 2>&1 | grep -q "unknown obduuid" ||
5655                 error "$LFS getstripe --obd wrong_uuid: should return error"
5656
5657         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
5658
5659         local ostidx=1
5660         local obduuid=$(ostuuid_from_index $ostidx)
5661         local found=$($LFS getstripe -r --obd $obduuid $dir |
5662                 grep 'lmm_stripe_offset:' | grep -c " $ostidx\$")
5663
5664         filenum=$($LFS getstripe -ir $dir | grep -c "^$ostidx\$")
5665         [[ $($LFS getstripe -id $dir) -ne $ostidx ]] ||
5666                 ((filenum--))
5667         [[ $($LFS getstripe -id $dir/dir) -ne $ostidx ]] ||
5668                 ((filenum--))
5669
5670         [[ $found -eq $filenum ]] ||
5671                 error "$LFS getstripe --obd: found $found expect $filenum"
5672         [[ $($LFS getstripe -r -v --obd $obduuid $dir |
5673                 sed '/^[         ]*'${ostidx}'[  ]/d' |
5674                 sed -n '/^[      ]*[0-9][0-9]*[  ]/p' | wc -l) -eq 0 ]] ||
5675                 error "$LFS getstripe --obd: should not show file on other obd"
5676         echo "$LFS getstripe --obd passed"
5677 }
5678 run_test 56a "check $LFS getstripe"
5679
5680 test_56b() {
5681         local dir=$DIR/$tdir
5682         local numdirs=3
5683
5684         test_mkdir $dir
5685         for i in $(seq $numdirs); do
5686                 test_mkdir $dir/dir$i
5687         done
5688
5689         # test lfs getdirstripe default mode is non-recursion, which is
5690         # different from lfs getstripe
5691         local dircnt=$($LFS getdirstripe $dir | grep -c lmv_stripe_count)
5692
5693         [[ $dircnt -eq 1 ]] ||
5694                 error "$LFS getdirstripe: found $dircnt, not 1"
5695         dircnt=$($LFS getdirstripe --recursive $dir |
5696                 grep -c lmv_stripe_count)
5697         [[ $dircnt -eq $((numdirs + 1)) ]] ||
5698                 error "$LFS getdirstripe -r: $dircnt, != $((numdirs + 1))"
5699 }
5700 run_test 56b "check $LFS getdirstripe"
5701
5702 test_56c() {
5703         remote_ost_nodsh && skip "remote OST with nodsh"
5704
5705         local ost_idx=0
5706         local ost_name=$(ostname_from_index $ost_idx)
5707         local old_status=$(ost_dev_status $ost_idx)
5708         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
5709
5710         [[ -z "$old_status" ]] ||
5711                 skip_env "OST $ost_name is in $old_status status"
5712
5713         do_facet ost1 $LCTL set_param -n obdfilter.$ost_name.degraded=1
5714         [[ $OST1_VERSION -lt $(version_code 2.12.55) ]] || do_facet ost1 \
5715                 $LCTL set_param -n obdfilter.$ost_name.no_precreate=1
5716         if [[ $OST1_VERSION -ge $(version_code 2.12.57) ]]; then
5717                 save_lustre_params ost1 osd-*.$ost_name.nonrotational > $p
5718                 do_facet ost1 $LCTL set_param -n osd-*.$ost_name.nonrotational=1
5719         fi
5720
5721         [[ $($LFS df -v $MOUNT |& grep -c "inactive device") -eq 0 ]] ||
5722                 error "$LFS df -v showing inactive devices"
5723         sleep_maxage
5724
5725         local new_status=$(ost_dev_status $ost_idx $MOUNT -v)
5726
5727         [[ "$new_status" =~ "D" ]] ||
5728                 error "$ost_name status is '$new_status', missing 'D'"
5729         if [[ $OST1_VERSION -ge $(version_code 2.12.55) ]]; then
5730                 [[ "$new_status" =~ "N" ]] ||
5731                         error "$ost_name status is '$new_status', missing 'N'"
5732         fi
5733         if [[ $OST1_VERSION -ge $(version_code 2.12.57) ]]; then
5734                 [[ "$new_status" =~ "f" ]] ||
5735                         error "$ost_name status is '$new_status', missing 'f'"
5736         fi
5737
5738         do_facet ost1 $LCTL set_param -n obdfilter.$ost_name.degraded=0
5739         [[ $OST1_VERSION -lt $(version_code 2.12.55) ]] || do_facet ost1 \
5740                 $LCTL set_param -n obdfilter.$ost_name.no_precreate=0
5741         [[ -z "$p" ]] && restore_lustre_params < $p || true
5742         sleep_maxage
5743
5744         new_status=$(ost_dev_status $ost_idx)
5745         [[ ! "$new_status" =~ "D" && ! "$new_status" =~ "N" ]] ||
5746                 error "$ost_name status is '$new_status', has 'D' and/or 'N'"
5747         # can't check 'f' as devices may actually be on flash
5748 }
5749 run_test 56c "check 'lfs df' showing device status"
5750
5751 test_56d() {
5752         local mdts=$($LFS df -v $MOUNT | grep -c MDT)
5753         local osts=$($LFS df -v $MOUNT | grep -c OST)
5754
5755         $LFS df $MOUNT
5756
5757         (( mdts == MDSCOUNT )) ||
5758                 error "lfs df -v showed $mdts MDTs, not $MDSCOUNT"
5759         (( osts == OSTCOUNT )) ||
5760                 error "lfs df -v showed $osts OSTs, not $OSTCOUNT"
5761 }
5762 run_test 56d "'lfs df -v' prints only configured devices"
5763
5764 NUMFILES=3
5765 NUMDIRS=3
5766 setup_56() {
5767         local local_tdir="$1"
5768         local local_numfiles="$2"
5769         local local_numdirs="$3"
5770         local dir_params="$4"
5771         local dir_stripe_params="$5"
5772
5773         if [ ! -d "$local_tdir" ] ; then
5774                 test_mkdir -p $dir_stripe_params $local_tdir
5775                 [ "$dir_params" ] && $LFS setstripe $dir_params $local_tdir
5776                 for i in $(seq $local_numfiles) ; do
5777                         touch $local_tdir/file$i
5778                 done
5779                 for i in $(seq $local_numdirs) ; do
5780                         test_mkdir $dir_stripe_params $local_tdir/dir$i
5781                         for j in $(seq $local_numfiles) ; do
5782                                 touch $local_tdir/dir$i/file$j
5783                         done
5784                 done
5785         fi
5786 }
5787
5788 setup_56_special() {
5789         local local_tdir=$1
5790         local local_numfiles=$2
5791         local local_numdirs=$3
5792
5793         setup_56 $local_tdir $local_numfiles $local_numdirs
5794
5795         if [ ! -e "$local_tdir/loop${local_numfiles}b" ] ; then
5796                 for i in $(seq $local_numfiles) ; do
5797                         mknod $local_tdir/loop${i}b b 7 $i
5798                         mknod $local_tdir/null${i}c c 1 3
5799                         ln -s $local_tdir/file1 $local_tdir/link${i}
5800                 done
5801                 for i in $(seq $local_numdirs) ; do
5802                         mknod $local_tdir/dir$i/loop${i}b b 7 $i
5803                         mknod $local_tdir/dir$i/null${i}c c 1 3
5804                         ln -s $local_tdir/dir$i/file1 $local_tdir/dir$i/link${i}
5805                 done
5806         fi
5807 }
5808
5809 test_56g() {
5810         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
5811         local expected=$(($NUMDIRS + 2))
5812
5813         setup_56 $dir $NUMFILES $NUMDIRS
5814
5815         # test lfs find with -name
5816         for i in $(seq $NUMFILES) ; do
5817                 local nums=$($LFS find -name "*$i" $dir | wc -l)
5818
5819                 [ $nums -eq $expected ] ||
5820                         error "lfs find -name '*$i' $dir wrong: "\
5821                               "found $nums, expected $expected"
5822         done
5823 }
5824 run_test 56g "check lfs find -name"
5825
5826 test_56h() {
5827         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
5828         local expected=$(((NUMDIRS + 1) * (NUMFILES - 1) + NUMFILES))
5829
5830         setup_56 $dir $NUMFILES $NUMDIRS
5831
5832         # test lfs find with ! -name
5833         for i in $(seq $NUMFILES) ; do
5834                 local nums=$($LFS find ! -name "*$i" $dir | wc -l)
5835
5836                 [ $nums -eq $expected ] ||
5837                         error "lfs find ! -name '*$i' $dir wrong: "\
5838                               "found $nums, expected $expected"
5839         done
5840 }
5841 run_test 56h "check lfs find ! -name"
5842
5843 test_56i() {
5844         local dir=$DIR/$tdir
5845
5846         test_mkdir $dir
5847
5848         local cmd="$LFS find -ost $(ostuuid_from_index 0 $dir) $dir"
5849         local out=$($cmd)
5850
5851         [ -z "$out" ] || error "'$cmd' returned directory '$out'"
5852 }
5853 run_test 56i "check 'lfs find -ost UUID' skips directories"
5854
5855 test_56j() {
5856         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
5857
5858         setup_56_special $dir $NUMFILES $NUMDIRS
5859
5860         local expected=$((NUMDIRS + 1))
5861         local cmd="$LFS find -type d $dir"
5862         local nums=$($cmd | wc -l)
5863
5864         [ $nums -eq $expected ] ||
5865                 error "'$cmd' wrong: found $nums, expected $expected"
5866 }
5867 run_test 56j "check lfs find -type d"
5868
5869 test_56k() {
5870         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
5871
5872         setup_56_special $dir $NUMFILES $NUMDIRS
5873
5874         local expected=$(((NUMDIRS + 1) * NUMFILES))
5875         local cmd="$LFS find -type f $dir"
5876         local nums=$($cmd | wc -l)
5877
5878         [ $nums -eq $expected ] ||
5879                 error "'$cmd' wrong: found $nums, expected $expected"
5880 }
5881 run_test 56k "check lfs find -type f"
5882
5883 test_56l() {
5884         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
5885
5886         setup_56_special $dir $NUMFILES $NUMDIRS
5887
5888         local expected=$((NUMDIRS + NUMFILES))
5889         local cmd="$LFS find -type b $dir"
5890         local nums=$($cmd | wc -l)
5891
5892         [ $nums -eq $expected ] ||
5893                 error "'$cmd' wrong: found $nums, expected $expected"
5894 }
5895 run_test 56l "check lfs find -type b"
5896
5897 test_56m() {
5898         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
5899
5900         setup_56_special $dir $NUMFILES $NUMDIRS
5901
5902         local expected=$((NUMDIRS + NUMFILES))
5903         local cmd="$LFS find -type c $dir"
5904         local nums=$($cmd | wc -l)
5905         [ $nums -eq $expected ] ||
5906                 error "'$cmd' wrong: found $nums, expected $expected"
5907 }
5908 run_test 56m "check lfs find -type c"
5909
5910 test_56n() {
5911         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
5912         setup_56_special $dir $NUMFILES $NUMDIRS
5913
5914         local expected=$((NUMDIRS + NUMFILES))
5915         local cmd="$LFS find -type l $dir"
5916         local nums=$($cmd | wc -l)
5917
5918         [ $nums -eq $expected ] ||
5919                 error "'$cmd' wrong: found $nums, expected $expected"
5920 }
5921 run_test 56n "check lfs find -type l"
5922
5923 test_56o() {
5924         local dir=$DIR/$tdir
5925
5926         setup_56 $dir $NUMFILES $NUMDIRS
5927         utime $dir/file1 > /dev/null || error "utime (1)"
5928         utime $dir/file2 > /dev/null || error "utime (2)"
5929         utime $dir/dir1 > /dev/null || error "utime (3)"
5930         utime $dir/dir2 > /dev/null || error "utime (4)"
5931         utime $dir/dir1/file1 > /dev/null || error "utime (5)"
5932         dd if=/dev/zero count=1 >> $dir/dir1/file1 && sync
5933
5934         local expected=4
5935         local nums=$($LFS find -mtime +0 $dir | wc -l)
5936
5937         [ $nums -eq $expected ] ||
5938                 error "lfs find -mtime +0 $dir: found $nums expect $expected"
5939
5940         expected=12
5941         cmd="$LFS find -mtime 0 $dir"
5942         nums=$($cmd | wc -l)
5943         [ $nums -eq $expected ] ||
5944                 error "'$cmd' wrong: found $nums, expected $expected"
5945 }
5946 run_test 56o "check lfs find -mtime for old files"
5947
5948 test_56ob() {
5949         local dir=$DIR/$tdir
5950         local expected=1
5951         local count=0
5952
5953         # just to make sure there is something that won't be found
5954         test_mkdir $dir
5955         touch $dir/$tfile.now
5956
5957         for age in year week day hour min; do
5958                 count=$((count + 1))
5959
5960                 touch $dir/$tfile-a.$age $dir/$tfile-m.$age
5961                 touch --date="$count $age ago" -a $dir/$tfile-a.$age
5962                 touch --date="$count $age ago" -m $dir/$tfile-m.$age
5963
5964                 local cmd="$LFS find $dir -mtime $count${age:0:1}"
5965                 local nums=$($cmd | wc -l)
5966                 [ $nums -eq $expected ] ||
5967                         error "'$cmd' wrong: found $nums, expected $expected"
5968
5969                 cmd="$LFS find $dir -atime $count${age:0:1}"
5970                 nums=$($cmd | wc -l)
5971                 [ $nums -eq $expected ] ||
5972                         error "'$cmd' wrong: found $nums, expected $expected"
5973         done
5974
5975         sleep 2
5976         cmd="$LFS find $dir -ctime +1s -type f"
5977         nums=$($cmd | wc -l)
5978         (( $nums == $count * 2 + 1)) ||
5979                 error "'$cmd' wrong: found $nums, expected $((count * 2 + 1))"
5980 }
5981 run_test 56ob "check lfs find -atime -mtime -ctime with units"
5982
5983 test_newerXY_base() {
5984         local x=$1
5985         local y=$2
5986         local dir=$DIR/$tdir
5987         local ref
5988         local negref
5989
5990         if [ $y == "t" ]; then
5991                 if [ $x == "b" ]; then
5992                         ref="\"$(do_facet mds1 date +"%Y-%m-%d\ %H:%M:%S")\""
5993                 else
5994                         ref="\"$(date +"%Y-%m-%d %H:%M:%S")\""
5995                 fi
5996         else
5997                 ref=$DIR/$tfile.newer.$x$y
5998                 touch $ref || error "touch $ref failed"
5999         fi
6000
6001         echo "before = $ref"
6002         sleep 2
6003         setup_56 $dir $NUMFILES $NUMDIRS "-i0 -c1" "-i0 -c1"
6004         sleep 2
6005         if [ $y == "t" ]; then
6006                 if [ $x == "b" ]; then
6007                         negref="\"$(do_facet mds1 date +"%Y-%m-%d\ %H:%M:%S")\""
6008                 else
6009                         negref="\"$(date +"%Y-%m-%d %H:%M:%S")\""
6010                 fi
6011         else
6012                 negref=$DIR/$tfile.negnewer.$x$y
6013                 touch $negref || error "touch $negref failed"
6014         fi
6015
6016         echo "after = $negref"
6017         local cmd="$LFS find $dir -newer$x$y $ref"
6018         local nums=$(eval $cmd | wc -l)
6019         local expected=$(((NUMFILES + 2) * NUMDIRS + 1))
6020
6021         [ $nums -eq $expected ] || { ls -lauR --full-time $dir ;
6022                 error "'$cmd' wrong: found $nums newer, expected $expected"  ; }
6023
6024         cmd="$LFS find $dir ! -newer$x$y $negref"
6025         nums=$(eval $cmd | wc -l)
6026         [ $nums -eq $expected ] || { ls -lauR --full-time $dir ;
6027                 error "'$cmd' wrong: found $nums older, expected $expected"  ; }
6028
6029         cmd="$LFS find $dir -newer$x$y $ref ! -newer$x$y $negref"
6030         nums=$(eval $cmd | wc -l)
6031         [ $nums -eq $expected ] || { ls -lauR --full-time $dir ;
6032                 error "'$cmd' wrong: found $nums between, expected $expected"; }
6033
6034         rm -rf $DIR/*
6035 }
6036
6037 test_56oc() {
6038         test_newerXY_base "a" "a"
6039         test_newerXY_base "a" "m"
6040         test_newerXY_base "a" "c"
6041         test_newerXY_base "m" "a"
6042         test_newerXY_base "m" "m"
6043         test_newerXY_base "m" "c"
6044         test_newerXY_base "c" "a"
6045         test_newerXY_base "c" "m"
6046         test_newerXY_base "c" "c"
6047
6048         [[ -n "$sles_version" ]] &&
6049                 echo "skip timestamp tests on SLES, LU-13665" && return 0
6050
6051         test_newerXY_base "a" "t"
6052         test_newerXY_base "m" "t"
6053         test_newerXY_base "c" "t"
6054
6055         [[ $MDS1_VERSION -lt $(version_code 2.13.54) ||
6056            $CLIENT_VERSION -lt $(version_code 2.13.54) ]] &&
6057                 ! btime_supported && echo "btime unsupported" && return 0
6058
6059         test_newerXY_base "b" "b"
6060         test_newerXY_base "b" "t"
6061 }
6062 run_test 56oc "check lfs find -newerXY work"
6063
6064 btime_supported() {
6065         local dir=$DIR/$tdir
6066         local rc
6067
6068         mkdir -p $dir
6069         touch $dir/$tfile
6070         $LFS find $dir -btime -1d -type f
6071         rc=$?
6072         rm -rf $dir
6073         return $rc
6074 }
6075
6076 test_56od() {
6077         [ $MDS1_VERSION -lt $(version_code 2.13.53) ] &&
6078                 ! btime_supported && skip "btime unsupported on MDS"
6079
6080         [ $CLIENT_VERSION -lt $(version_code 2.13.53) ] &&
6081                 ! btime_supported && skip "btime unsupported on clients"
6082
6083         local dir=$DIR/$tdir
6084         local ref=$DIR/$tfile.ref
6085         local negref=$DIR/$tfile.negref
6086
6087         mkdir $dir || error "mkdir $dir failed"
6088         touch $dir/$tfile.n1 || error "touch $dir/$tfile.n1 failed"
6089         touch $dir/$tfile.n2 || error "touch $dir/$tfile.n2 failed"
6090         mkdir $dir/$tdir.n1 || error "mkdir $dir/$tdir.n1 failed"
6091         mkdir $dir/$tdir.n2 || error "mkdir $dir/$tdir.n2 failed"
6092         touch $ref || error "touch $ref failed"
6093         # sleep 3 seconds at least
6094         sleep 3
6095
6096         local before=$(do_facet mds1 date +%s)
6097         local skew=$(($(date +%s) - before + 1))
6098
6099         if (( skew < 0 && skew > -5 )); then
6100                 sleep $((0 - skew + 1))
6101                 skew=0
6102         fi
6103
6104         # Set the dir stripe params to limit files all on MDT0,
6105         # otherwise we need to calc the max clock skew between
6106         # the client and MDTs.
6107         setup_56 $dir/d.btime $NUMFILES $NUMDIRS "-i0 -c1" "-i0 -c1"
6108         sleep 2
6109         touch $negref || error "touch $negref failed"
6110
6111         local cmd="$LFS find $dir -newerbb $ref ! -newerbb $negref -type f"
6112         local nums=$($cmd | wc -l)
6113         local expected=$(((NUMFILES + 1) * NUMDIRS))
6114
6115         [ $nums -eq $expected ] ||
6116                 error "'$cmd' wrong: found $nums, expected $expected"
6117
6118         cmd="$LFS find $dir -newerbb $ref ! -newerbb $negref -type d"
6119         nums=$($cmd | wc -l)
6120         expected=$((NUMFILES + 1))
6121         [ $nums -eq $expected ] ||
6122                 error "'$cmd' wrong: found $nums, expected $expected"
6123
6124         [ $skew -lt 0 ] && return
6125
6126         local after=$(do_facet mds1 date +%s)
6127         local age=$((after - before + 1 + skew))
6128
6129         cmd="$LFS find $dir -btime -${age}s -type f"
6130         nums=$($cmd | wc -l)
6131         expected=$(((NUMFILES + 1) * NUMDIRS))
6132
6133         echo "Clock skew between client and server: $skew, age:$age"
6134         [ $nums -eq $expected ] ||
6135                 error "'$cmd' wrong: found $nums, expected $expected"
6136
6137         expected=$(($NUMDIRS + 1))
6138         cmd="$LFS find $dir -btime -${age}s -type d"
6139         nums=$($cmd | wc -l)
6140         [ $nums -eq $expected ] ||
6141                 error "'$cmd' wrong: found $nums, expected $expected"
6142         rm -f $ref $negref || error "Failed to remove $ref $negref"
6143 }
6144 run_test 56od "check lfs find -btime with units"
6145
6146 test_56p() {
6147         [ $RUNAS_ID -eq $UID ] &&
6148                 skip_env "RUNAS_ID = UID = $UID -- skipping"
6149
6150         local dir=$DIR/$tdir
6151
6152         setup_56 $dir $NUMFILES $NUMDIRS
6153         chown $RUNAS_ID $dir/file* || error "chown $DIR/${tdir}g/file$i failed"
6154
6155         local expected=$NUMFILES
6156         local cmd="$LFS find -uid $RUNAS_ID $dir"
6157         local nums=$($cmd | wc -l)
6158
6159         [ $nums -eq $expected ] ||
6160                 error "'$cmd' wrong: found $nums, expected $expected"
6161
6162         expected=$(((NUMFILES + 1) * NUMDIRS + 1))
6163         cmd="$LFS find ! -uid $RUNAS_ID $dir"
6164         nums=$($cmd | wc -l)
6165         [ $nums -eq $expected ] ||
6166                 error "'$cmd' wrong: found $nums, expected $expected"
6167 }
6168 run_test 56p "check lfs find -uid and ! -uid"
6169
6170 test_56q() {
6171         [ $RUNAS_ID -eq $UID ] &&
6172                 skip_env "RUNAS_ID = UID = $UID -- skipping"
6173
6174         local dir=$DIR/$tdir
6175
6176         setup_56 $dir $NUMFILES $NUMDIRS
6177         chgrp $RUNAS_GID $dir/file* || error "chown $dir/file$i failed"
6178
6179         local expected=$NUMFILES
6180         local cmd="$LFS find -gid $RUNAS_GID $dir"
6181         local nums=$($cmd | wc -l)
6182
6183         [ $nums -eq $expected ] ||
6184                 error "'$cmd' wrong: found $nums, expected $expected"
6185
6186         expected=$(( ($NUMFILES+1) * $NUMDIRS + 1))
6187         cmd="$LFS find ! -gid $RUNAS_GID $dir"
6188         nums=$($cmd | wc -l)
6189         [ $nums -eq $expected ] ||
6190                 error "'$cmd' wrong: found $nums, expected $expected"
6191 }
6192 run_test 56q "check lfs find -gid and ! -gid"
6193
6194 test_56r() {
6195         local dir=$DIR/$tdir
6196
6197         setup_56 $dir $NUMFILES $NUMDIRS
6198
6199         local expected=12
6200         local cmd="$LFS find -size 0 -type f -lazy $dir"
6201         local nums=$($cmd | wc -l)
6202
6203         [ $nums -eq $expected ] ||
6204                 error "'$cmd' wrong: found $nums, expected $expected"
6205         cmd="$LFS find -size 0 -type f $dir"
6206         nums=$($cmd | wc -l)
6207         [ $nums -eq $expected ] ||
6208                 error "'$cmd' wrong: found $nums, expected $expected"
6209
6210         expected=0
6211         cmd="$LFS find ! -size 0 -type f -lazy $dir"
6212         nums=$($cmd | wc -l)
6213         [ $nums -eq $expected ] ||
6214                 error "'$cmd' wrong: found $nums, expected $expected"
6215         cmd="$LFS find ! -size 0 -type f $dir"
6216         nums=$($cmd | wc -l)
6217         [ $nums -eq $expected ] ||
6218                 error "'$cmd' wrong: found $nums, expected $expected"
6219
6220         echo "test" > $dir/$tfile
6221         echo "test2" > $dir/$tfile.2 && sync
6222         expected=1
6223         cmd="$LFS find -size 5 -type f -lazy $dir"
6224         nums=$($cmd | wc -l)
6225         [ $nums -eq $expected ] ||
6226                 error "'$cmd' wrong: found $nums, expected $expected"
6227         cmd="$LFS find -size 5 -type f $dir"
6228         nums=$($cmd | wc -l)
6229         [ $nums -eq $expected ] ||
6230                 error "'$cmd' wrong: found $nums, expected $expected"
6231
6232         expected=1
6233         cmd="$LFS find -size +5 -type f -lazy $dir"
6234         nums=$($cmd | wc -l)
6235         [ $nums -eq $expected ] ||
6236                 error "'$cmd' wrong: found $nums, expected $expected"
6237         cmd="$LFS find -size +5 -type f $dir"
6238         nums=$($cmd | wc -l)
6239         [ $nums -eq $expected ] ||
6240                 error "'$cmd' wrong: found $nums, expected $expected"
6241
6242         expected=2
6243         cmd="$LFS find -size +0 -type f -lazy $dir"
6244         nums=$($cmd | wc -l)
6245         [ $nums -eq $expected ] ||
6246                 error "'$cmd' wrong: found $nums, expected $expected"
6247         cmd="$LFS find -size +0 -type f $dir"
6248         nums=$($cmd | wc -l)
6249         [ $nums -eq $expected ] ||
6250                 error "'$cmd' wrong: found $nums, expected $expected"
6251
6252         expected=2
6253         cmd="$LFS find ! -size -5 -type f -lazy $dir"
6254         nums=$($cmd | wc -l)
6255         [ $nums -eq $expected ] ||
6256                 error "'$cmd' wrong: found $nums, expected $expected"
6257         cmd="$LFS find ! -size -5 -type f $dir"
6258         nums=$($cmd | wc -l)
6259         [ $nums -eq $expected ] ||
6260                 error "'$cmd' wrong: found $nums, expected $expected"
6261
6262         expected=12
6263         cmd="$LFS find -size -5 -type f -lazy $dir"
6264         nums=$($cmd | wc -l)
6265         [ $nums -eq $expected ] ||
6266                 error "'$cmd' wrong: found $nums, expected $expected"
6267         cmd="$LFS find -size -5 -type f $dir"
6268         nums=$($cmd | wc -l)
6269         [ $nums -eq $expected ] ||
6270                 error "'$cmd' wrong: found $nums, expected $expected"
6271 }
6272 run_test 56r "check lfs find -size works"
6273
6274 test_56ra_sub() {
6275         local expected=$1
6276         local glimpses=$2
6277         local cmd="$3"
6278
6279         cancel_lru_locks $OSC
6280
6281         local rpcs_before=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
6282         local nums=$($cmd | wc -l)
6283
6284         [ $nums -eq $expected ] ||
6285                 error "'$cmd' wrong: found $nums, expected $expected"
6286
6287         local rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
6288
6289         if (( rpcs_before + glimpses != rpcs_after )); then
6290                 echo "Before: $rpcs_before After: $rpcs_after $NUMFILES"
6291                 $LCTL get_param osc.*.stats | grep ldlm_glimpse_enqueue
6292
6293                 if [[ $glimpses == 0 ]]; then
6294                         error "'$cmd' should not send glimpse RPCs to OST"
6295                 else
6296                         error "'$cmd' should send $glimpses glimpse RPCs to OST"
6297                 fi
6298         fi
6299 }
6300
6301 test_56ra() {
6302         [[ $MDS1_VERSION -gt $(version_code 2.12.58) ]] ||
6303                 skip "MDS < 2.12.58 doesn't return LSOM data"
6304         local dir=$DIR/$tdir
6305         local old_agl=$($LCTL get_param -n llite.*.statahead_agl)
6306
6307         [[ $OSC == "mdc" ]] && skip "statahead not needed for DoM files"
6308
6309         # statahead_agl may cause extra glimpse which confuses results. LU-13017
6310         $LCTL set_param -n llite.*.statahead_agl=0
6311         stack_trap "$LCTL set_param -n llite.*.statahead_agl=$old_agl"
6312
6313         setup_56 $dir $NUMFILES $NUMDIRS "-c 1"
6314         # open and close all files to ensure LSOM is updated
6315         cancel_lru_locks $OSC
6316         find $dir -type f | xargs cat > /dev/null
6317
6318         #   expect_found  glimpse_rpcs  command_to_run
6319         test_56ra_sub 12  0 "$LFS find -size 0 -type f -lazy $dir"
6320         test_56ra_sub 12 12 "$LFS find -size 0 -type f $dir"
6321         test_56ra_sub  0  0 "$LFS find ! -size 0 -type f -lazy $dir"
6322         test_56ra_sub  0 12 "$LFS find ! -size 0 -type f $dir"
6323
6324         echo "test" > $dir/$tfile
6325         echo "test2" > $dir/$tfile.2 && sync
6326         cancel_lru_locks $OSC
6327         cat $dir/$tfile $dir/$tfile.2 > /dev/null
6328
6329         test_56ra_sub  1  0 "$LFS find -size 5 -type f -lazy $dir"
6330         test_56ra_sub  1 14 "$LFS find -size 5 -type f $dir"
6331         test_56ra_sub  1  0 "$LFS find -size +5 -type f -lazy $dir"
6332         test_56ra_sub  1 14 "$LFS find -size +5 -type f $dir"
6333
6334         test_56ra_sub  2  0 "$LFS find -size +0 -type f -lazy $dir"
6335         test_56ra_sub  2 14 "$LFS find -size +0 -type f $dir"
6336         test_56ra_sub  2  0 "$LFS find ! -size -5 -type f -lazy $dir"
6337         test_56ra_sub  2 14 "$LFS find ! -size -5 -type f $dir"
6338         test_56ra_sub 12  0 "$LFS find -size -5 -type f -lazy $dir"
6339         test_56ra_sub 12 14 "$LFS find -size -5 -type f $dir"
6340 }
6341 run_test 56ra "check lfs find -size -lazy works for data on OSTs"
6342
6343 test_56rb() {
6344         local dir=$DIR/$tdir
6345         local tmp=$TMP/$tfile.log
6346         local mdt_idx;
6347
6348         test_mkdir -p $dir || error "failed to mkdir $dir"
6349         $LFS setstripe -c 1 -i 0 $dir/$tfile ||
6350                 error "failed to setstripe $dir/$tfile"
6351         mdt_idx=$($LFS getdirstripe -i $dir)
6352         dd if=/dev/zero of=$dir/$tfile bs=1M count=1
6353
6354         stack_trap "rm -f $tmp" EXIT
6355         $LFS find --size +100K --ost 0 $dir |& tee $tmp
6356         ! grep -q obd_uuid $tmp ||
6357                 error "failed to find --size +100K --ost 0 $dir"
6358         $LFS find --size +100K --mdt $mdt_idx $dir |& tee $tmp
6359         ! grep -q obd_uuid $tmp ||
6360                 error "failed to find --size +100K --mdt $mdt_idx $dir"
6361 }
6362 run_test 56rb "check lfs find --size --ost/--mdt works"
6363
6364 test_56s() { # LU-611 #LU-9369
6365         [[ $OSTCOUNT -lt 2 ]] && skip_env "need at least 2 OSTs"
6366
6367         local dir=$DIR/$tdir
6368         local onestripe=$(((NUMDIRS + 1) * NUMFILES))
6369
6370         setup_56 $dir $NUMFILES $NUMDIRS "-c 1"
6371         for i in $(seq $NUMDIRS); do
6372                 $LFS setstripe -c $((OSTCOUNT + 1)) $dir/dir$i/$tfile
6373         done
6374
6375         local expected=$NUMDIRS
6376         local cmd="$LFS find -c $OSTCOUNT $dir"
6377         local nums=$($cmd | wc -l)
6378
6379         [ $nums -eq $expected ] || {
6380                 $LFS getstripe -R $dir
6381                 error "'$cmd' wrong: found $nums, expected $expected"
6382         }
6383
6384         expected=$((NUMDIRS + onestripe))
6385         cmd="$LFS find -stripe-count +0 -type f $dir"
6386         nums=$($cmd | wc -l)
6387         [ $nums -eq $expected ] || {
6388                 $LFS getstripe -R $dir
6389                 error "'$cmd' wrong: found $nums, expected $expected"
6390         }
6391
6392         expected=$onestripe
6393         cmd="$LFS find -stripe-count 1 -type f $dir"
6394         nums=$($cmd | wc -l)
6395         [ $nums -eq $expected ] || {
6396                 $LFS getstripe -R $dir
6397                 error "'$cmd' wrong: found $nums, expected $expected"
6398         }
6399
6400         cmd="$LFS find -stripe-count -2 -type f $dir"
6401         nums=$($cmd | wc -l)
6402         [ $nums -eq $expected ] || {
6403                 $LFS getstripe -R $dir
6404                 error "'$cmd' wrong: found $nums, expected $expected"
6405         }
6406
6407         expected=0
6408         cmd="$LFS find -stripe-count $((OSTCOUNT + 1)) -type f $dir"
6409         nums=$($cmd | wc -l)
6410         [ $nums -eq $expected ] || {
6411                 $LFS getstripe -R $dir
6412                 error "'$cmd' wrong: found $nums, expected $expected"
6413         }
6414 }
6415 run_test 56s "check lfs find -stripe-count works"
6416
6417 test_56t() { # LU-611 #LU-9369
6418         local dir=$DIR/$tdir
6419
6420         setup_56 $dir 0 $NUMDIRS
6421         for i in $(seq $NUMDIRS); do
6422                 $LFS setstripe -S 8M $dir/dir$i/$tfile
6423         done
6424
6425         local expected=$NUMDIRS
6426         local cmd="$LFS find -S 8M $dir"
6427         local nums=$($cmd | wc -l)
6428
6429         [ $nums -eq $expected ] || {
6430                 $LFS getstripe -R $dir
6431                 error "'$cmd' wrong: found $nums, expected $expected"
6432         }
6433         rm -rf $dir
6434
6435         setup_56 $dir $NUMFILES $NUMDIRS "--stripe-size 512k"
6436
6437         $LFS setstripe -S 256k $dir/$tfile.{0,1,2,3}
6438
6439         expected=$(((NUMDIRS + 1) * NUMFILES))
6440         cmd="$LFS find -stripe-size 512k -type f $dir"
6441         nums=$($cmd | wc -l)
6442         [ $nums -eq $expected ] ||
6443                 error "'$cmd' wrong: found $nums, expected $expected"
6444
6445         cmd="$LFS find -stripe-size +320k -type f $dir"
6446         nums=$($cmd | wc -l)
6447         [ $nums -eq $expected ] ||
6448                 error "'$cmd' wrong: found $nums, expected $expected"
6449
6450         expected=$(((NUMDIRS + 1) * NUMFILES + 4))
6451         cmd="$LFS find -stripe-size +200k -type f $dir"
6452         nums=$($cmd | wc -l)
6453         [ $nums -eq $expected ] ||
6454                 error "'$cmd' wrong: found $nums, expected $expected"
6455
6456         cmd="$LFS find -stripe-size -640k -type f $dir"
6457         nums=$($cmd | wc -l)
6458         [ $nums -eq $expected ] ||
6459                 error "'$cmd' wrong: found $nums, expected $expected"
6460
6461         expected=4
6462         cmd="$LFS find -stripe-size 256k -type f $dir"
6463         nums=$($cmd | wc -l)
6464         [ $nums -eq $expected ] ||
6465                 error "'$cmd' wrong: found $nums, expected $expected"
6466
6467         cmd="$LFS find -stripe-size -320k -type f $dir"
6468         nums=$($cmd | wc -l)
6469         [ $nums -eq $expected ] ||
6470                 error "'$cmd' wrong: found $nums, expected $expected"
6471
6472         expected=0
6473         cmd="$LFS find -stripe-size 1024k -type f $dir"
6474         nums=$($cmd | wc -l)
6475         [ $nums -eq $expected ] ||
6476                 error "'$cmd' wrong: found $nums, expected $expected"
6477 }
6478 run_test 56t "check lfs find -stripe-size works"
6479
6480 test_56u() { # LU-611
6481         local dir=$DIR/$tdir
6482
6483         setup_56 $dir $NUMFILES $NUMDIRS "-i 0 -c 1"
6484
6485         if [[ $OSTCOUNT -gt 1 ]]; then
6486                 $LFS setstripe -i 1 -c 1 $dir/$tfile.{0,1,2,3}
6487                 onestripe=4
6488         else
6489                 onestripe=0
6490         fi
6491
6492         local expected=$(((NUMDIRS + 1) * NUMFILES))
6493         local cmd="$LFS find -stripe-index 0 -type f $dir"
6494         local nums=$($cmd | wc -l)
6495
6496         [ $nums -eq $expected ] ||
6497                 error "'$cmd' wrong: found $nums, expected $expected"
6498
6499         expected=$onestripe
6500         cmd="$LFS find -stripe-index 1 -type f $dir"
6501         nums=$($cmd | wc -l)
6502         [ $nums -eq $expected ] ||
6503                 error "'$cmd' wrong: found $nums, expected $expected"
6504
6505         cmd="$LFS find ! -stripe-index 0 -type f $dir"
6506         nums=$($cmd | wc -l)
6507         [ $nums -eq $expected ] ||
6508                 error "'$cmd' wrong: found $nums, expected $expected"
6509
6510         expected=0
6511         # This should produce an error and not return any files
6512         cmd="$LFS find -stripe-index $OSTCOUNT -type f $dir"
6513         nums=$($cmd 2>/dev/null | wc -l)
6514         [ $nums -eq $expected ] ||
6515                 error "'$cmd' wrong: found $nums, expected $expected"
6516
6517         if [[ $OSTCOUNT -gt 1 ]]; then
6518                 expected=$(((NUMDIRS + 1) * NUMFILES + onestripe))
6519                 cmd="$LFS find -stripe-index 0,1 -type f $dir"
6520                 nums=$($cmd | wc -l)
6521                 [ $nums -eq $expected ] ||
6522                         error "'$cmd' wrong: found $nums, expected $expected"
6523         fi
6524 }
6525 run_test 56u "check lfs find -stripe-index works"
6526
6527 test_56v() {
6528         local mdt_idx=0
6529         local dir=$DIR/$tdir
6530
6531         setup_56 $dir $NUMFILES $NUMDIRS
6532
6533         UUID=$(mdtuuid_from_index $mdt_idx $dir)
6534         [ -z "$UUID" ] && error "mdtuuid_from_index cannot find MDT $mdt_idx"
6535
6536         for file in $($LFS find -m $UUID $dir); do
6537                 file_midx=$($LFS getstripe -m $file)
6538                 [ $file_midx -eq $mdt_idx ] ||
6539                         error "lfs find -m $UUID != getstripe -m $file_midx"
6540         done
6541 }
6542 run_test 56v "check 'lfs find -m match with lfs getstripe -m'"
6543
6544 test_56w() {
6545         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
6546         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6547
6548         local dir=$DIR/$tdir
6549
6550         setup_56 $dir $NUMFILES $NUMDIRS "-c $OSTCOUNT" "-c1"
6551
6552         local stripe_size=$($LFS getstripe -S -d $dir) ||
6553                 error "$LFS getstripe -S -d $dir failed"
6554         stripe_size=${stripe_size%% *}
6555
6556         local file_size=$((stripe_size * OSTCOUNT))
6557         local file_num=$((NUMDIRS * NUMFILES + NUMFILES))
6558         local required_space=$((file_num * file_size))
6559         local free_space=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
6560                            head -n1)
6561         [[ $free_space -le $((required_space / 1024)) ]] &&
6562                 skip_env "need $required_space, have $free_space kbytes"
6563
6564         local dd_bs=65536
6565         local dd_count=$((file_size / dd_bs))
6566
6567         # write data into the files
6568         local i
6569         local j
6570         local file
6571
6572         for i in $(seq $NUMFILES); do
6573                 file=$dir/file$i
6574                 yes | dd bs=$dd_bs count=$dd_count of=$file &>/dev/null ||
6575                         error "write data into $file failed"
6576         done
6577         for i in $(seq $NUMDIRS); do
6578                 for j in $(seq $NUMFILES); do
6579                         file=$dir/dir$i/file$j
6580                         yes|dd bs=$dd_bs count=$dd_count of=$file &>/dev/null ||
6581                                 error "write data into $file failed"
6582                 done
6583         done
6584
6585         # $LFS_MIGRATE will fail if hard link migration is unsupported
6586         if [[ $MDS1_VERSION -gt $(version_code 2.5.55) ]]; then
6587                 createmany -l$dir/dir1/file1 $dir/dir1/link 200 ||
6588                         error "creating links to $dir/dir1/file1 failed"
6589         fi
6590
6591         local expected=-1
6592
6593         [[ $OSTCOUNT -gt 1 ]] && expected=$((OSTCOUNT - 1))
6594
6595         # lfs_migrate file
6596         local cmd="$LFS_MIGRATE -y -c $expected $dir/file1"
6597
6598         echo "$cmd"
6599         eval $cmd || error "$cmd failed"
6600
6601         check_stripe_count $dir/file1 $expected
6602
6603         if [ $MDS1_VERSION -ge $(version_code 2.6.90) ];
6604         then
6605                 # lfs_migrate file onto OST 0 if it is on OST 1, or onto
6606                 # OST 1 if it is on OST 0. This file is small enough to
6607                 # be on only one stripe.
6608                 file=$dir/migr_1_ost
6609                 dd bs=$dd_bs count=1 if=/dev/urandom of=$file >/dev/null 2>&1 ||
6610                         error "write data into $file failed"
6611                 local obdidx=$($LFS getstripe -i $file)
6612                 local oldmd5=$(md5sum $file)
6613                 local newobdidx=0
6614
6615                 [[ $obdidx -eq 0 ]] && newobdidx=1
6616                 cmd="$LFS migrate -i $newobdidx $file"
6617                 echo $cmd
6618                 eval $cmd || error "$cmd failed"
6619
6620                 local realobdix=$($LFS getstripe -i $file)
6621                 local newmd5=$(md5sum $file)
6622
6623                 [[ $newobdidx -ne $realobdix ]] &&
6624                         error "new OST is different (was=$obdidx, "\
6625                               "wanted=$newobdidx, got=$realobdix)"
6626                 [[ "$oldmd5" != "$newmd5" ]] &&
6627                         error "md5sum differ: $oldmd5, $newmd5"
6628         fi
6629
6630         # lfs_migrate dir
6631         cmd="$LFS_MIGRATE -y -c $expected $dir/dir1"
6632         echo "$cmd"
6633         eval $cmd || error "$cmd failed"
6634
6635         for j in $(seq $NUMFILES); do
6636                 check_stripe_count $dir/dir1/file$j $expected
6637         done
6638
6639         # lfs_migrate works with lfs find
6640         cmd="$LFS find -stripe_count $OSTCOUNT -type f $dir |
6641              $LFS_MIGRATE -y -c $expected"
6642         echo "$cmd"
6643         eval $cmd || error "$cmd failed"
6644
6645         for i in $(seq 2 $NUMFILES); do
6646                 check_stripe_count $dir/file$i $expected
6647         done
6648         for i in $(seq 2 $NUMDIRS); do
6649                 for j in $(seq $NUMFILES); do
6650                 check_stripe_count $dir/dir$i/file$j $expected
6651                 done
6652         done
6653 }
6654 run_test 56w "check lfs_migrate -c stripe_count works"
6655
6656 test_56wb() {
6657         local file1=$DIR/$tdir/file1
6658         local create_pool=false
6659         local initial_pool=$($LFS getstripe -p $DIR)
6660         local pool_list=()
6661         local pool=""
6662
6663         echo -n "Creating test dir..."
6664         test_mkdir $DIR/$tdir &> /dev/null || error "cannot create dir"
6665         echo "done."
6666
6667         echo -n "Creating test file..."
6668         touch $file1 || error "cannot create file"
6669         echo "done."
6670
6671         echo -n "Detecting existing pools..."
6672         pool_list=($($LFS pool_list $FSNAME | grep "$FSNAME\." | cut -d. -f2))
6673
6674         if [ ${#pool_list[@]} -gt 0 ]; then
6675                 echo "${pool_list[@]}"
6676                 for thispool in "${pool_list[@]}"; do
6677                         if [[ -z "$initial_pool" ||
6678                               "$initial_pool" != "$thispool" ]]; then
6679                                 pool="$thispool"
6680                                 echo "Using existing pool '$pool'"
6681                                 break
6682                         fi
6683                 done
6684         else
6685                 echo "none detected."
6686         fi
6687         if [ -z "$pool" ]; then
6688                 pool=${POOL:-testpool}
6689                 [ "$initial_pool" = "$pool" ] && pool="testpool2"
6690                 echo -n "Creating pool '$pool'..."
6691                 create_pool=true
6692                 pool_add $pool &> /dev/null ||
6693                         error "pool_add failed"
6694                 echo "done."
6695
6696                 echo -n "Adding target to pool..."
6697                 pool_add_targets $pool 0 0 1 &> /dev/null ||
6698                         error "pool_add_targets failed"
6699                 echo "done."
6700         fi
6701
6702         echo -n "Setting pool using -p option..."
6703         $LFS_MIGRATE -y -q --no-rsync -p $pool $file1 &> /dev/null ||
6704                 error "migrate failed rc = $?"
6705         echo "done."
6706
6707         echo -n "Verifying test file is in pool after migrating..."
6708         [ "$($LFS getstripe -p $file1)" = $pool ] ||
6709                 error "file was not migrated to pool $pool"
6710         echo "done."
6711
6712         echo -n "Removing test file from pool '$pool'..."
6713         # "lfs migrate $file" won't remove the file from the pool
6714         # until some striping information is changed.
6715         $LFS migrate -c 1 $file1 &> /dev/null ||
6716                 error "cannot remove from pool"
6717         [ "$($LFS getstripe -p $file1)" ] &&
6718                 error "pool still set"
6719         echo "done."
6720
6721         echo -n "Setting pool using --pool option..."
6722         $LFS_MIGRATE -y -q --no-rsync --pool $pool $file1 &> /dev/null ||
6723                 error "migrate failed rc = $?"
6724         echo "done."
6725
6726         # Clean up
6727         rm -f $file1
6728         if $create_pool; then
6729                 destroy_test_pools 2> /dev/null ||
6730                         error "destroy test pools failed"
6731         fi
6732 }
6733 run_test 56wb "check lfs_migrate pool support"
6734
6735 test_56wc() {
6736         local file1="$DIR/$tdir/file1"
6737         local parent_ssize
6738         local parent_scount
6739         local cur_ssize
6740         local cur_scount
6741         local orig_ssize
6742
6743         echo -n "Creating test dir..."
6744         test_mkdir $DIR/$tdir &> /dev/null || error "cannot create dir"
6745         $LFS setstripe -S 1M -c 1 "$DIR/$tdir" &> /dev/null ||
6746                 error "cannot set stripe by '-S 1M -c 1'"
6747         echo "done"
6748
6749         echo -n "Setting initial stripe for test file..."
6750         $LFS setstripe -S 512K -c 1 "$file1" &> /dev/null ||
6751                 error "cannot set stripe"
6752         cur_ssize=$($LFS getstripe -S "$file1")
6753         [ $cur_ssize -eq 524288 ] || error "setstripe -S $cur_ssize != 524288"
6754         echo "done."
6755
6756         # File currently set to -S 512K -c 1
6757
6758         # Ensure -c and -S options are rejected when -R is set
6759         echo -n "Verifying incompatible options are detected..."
6760         $LFS_MIGRATE -y -R -c 1 "$file1" &> /dev/null &&
6761                 error "incompatible -c and -R options not detected"
6762         $LFS_MIGRATE -y -R -S 1M "$file1" &> /dev/null &&
6763                 error "incompatible -S and -R options not detected"
6764         echo "done."
6765
6766         # Ensure unrecognized options are passed through to 'lfs migrate'
6767         echo -n "Verifying -S option is passed through to lfs migrate..."
6768         $LFS_MIGRATE -y -S 1M "$file1" &> /dev/null ||
6769                 error "migration failed"
6770         cur_ssize=$($LFS getstripe -S "$file1")
6771         [ $cur_ssize -eq 1048576 ] || error "migrate -S $cur_ssize != 1048576"
6772         echo "done."
6773
6774         # File currently set to -S 1M -c 1
6775
6776         # Ensure long options are supported
6777         echo -n "Verifying long options supported..."
6778         $LFS_MIGRATE -y --non-block "$file1" &> /dev/null ||
6779                 error "long option without argument not supported"
6780         $LFS_MIGRATE -y --stripe-size 512K "$file1" &> /dev/null ||
6781                 error "long option with argument not supported"
6782         cur_ssize=$($LFS getstripe -S "$file1")
6783         [ $cur_ssize -eq 524288 ] ||
6784                 error "migrate --stripe-size $cur_ssize != 524288"
6785         echo "done."
6786
6787         # File currently set to -S 512K -c 1
6788
6789         if [ "$OSTCOUNT" -gt 1 ]; then
6790                 echo -n "Verifying explicit stripe count can be set..."
6791                 $LFS_MIGRATE -y -c 2 "$file1" &> /dev/null ||
6792                         error "migrate failed"
6793                 cur_scount=$($LFS getstripe -c "$file1")
6794                 [ $cur_scount -eq 2 ] || error "migrate -c $cur_scount != 2"
6795                 echo "done."
6796         fi
6797
6798         # File currently set to -S 512K -c 1 or -S 512K -c 2
6799
6800         # Ensure parent striping is used if -R is set, and no stripe
6801         # count or size is specified
6802         echo -n "Setting stripe for parent directory..."
6803         $LFS setstripe -S 2M -c 1 "$DIR/$tdir" &> /dev/null ||
6804                 error "cannot set stripe '-S 2M -c 1'"
6805         echo "done."
6806
6807         echo -n "Verifying restripe option uses parent stripe settings..."
6808         parent_ssize=$($LFS getstripe -S $DIR/$tdir 2>/dev/null)
6809         parent_scount=$($LFS getstripe -c $DIR/$tdir 2>/dev/null)
6810         $LFS_MIGRATE -y -R "$file1" &> /dev/null ||
6811                 error "migrate failed"
6812         cur_ssize=$($LFS getstripe -S "$file1")
6813         [ $cur_ssize -eq $parent_ssize ] ||
6814                 error "migrate -R stripe_size $cur_ssize != $parent_ssize"
6815         cur_scount=$($LFS getstripe -c "$file1")
6816         [ $cur_scount -eq $parent_scount ] ||
6817                 error "migrate -R stripe_count $cur_scount != $parent_scount"
6818         echo "done."
6819
6820         # File currently set to -S 1M -c 1
6821
6822         # Ensure striping is preserved if -R is not set, and no stripe
6823         # count or size is specified
6824         echo -n "Verifying striping size preserved when not specified..."
6825         orig_ssize=$($LFS getstripe -S "$file1" 2>/dev/null)
6826         $LFS setstripe -S 2M -c 1 "$DIR/$tdir" &> /dev/null ||
6827                 error "cannot set stripe on parent directory"
6828         $LFS_MIGRATE -y "$file1" &> /dev/null ||
6829                 error "migrate failed"
6830         cur_ssize=$($LFS getstripe -S "$file1")
6831         [ $cur_ssize -eq $orig_ssize ] ||
6832                 error "migrate by default $cur_ssize != $orig_ssize"
6833         echo "done."
6834
6835         # Ensure file name properly detected when final option has no argument
6836         echo -n "Verifying file name properly detected..."
6837         $LFS_MIGRATE -y "$file1" &> /dev/null ||
6838                 error "file name interpreted as option argument"
6839         echo "done."
6840
6841         # Clean up
6842         rm -f "$file1"
6843 }
6844 run_test 56wc "check unrecognized options for lfs_migrate are passed through"
6845
6846 test_56wd() {
6847         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
6848
6849         local file1=$DIR/$tdir/file1
6850
6851         echo -n "Creating test dir..."
6852         test_mkdir $DIR/$tdir || error "cannot create dir"
6853         echo "done."
6854
6855         echo -n "Creating test file..."
6856         touch $file1
6857         echo "done."
6858
6859         # Ensure 'lfs migrate' will fail by using a non-existent option,
6860         # and make sure rsync is not called to recover
6861         echo -n "Make sure --no-rsync option works..."
6862         $LFS_MIGRATE -y --no-rsync --invalid-opt $file1 2>&1 |
6863                 grep -q 'refusing to fall back to rsync' ||
6864                 error "rsync was called with --no-rsync set"
6865         echo "done."
6866
6867         # Ensure rsync is called without trying 'lfs migrate' first
6868         echo -n "Make sure --rsync option works..."
6869         $LFS_MIGRATE -y --rsync --invalid-opt $file1 2>&1 |
6870                 grep -q 'falling back to rsync' &&
6871                 error "lfs migrate was called with --rsync set"
6872         echo "done."
6873
6874         echo -n "Make sure --rsync and --no-rsync options are exclusive..."
6875         $LFS_MIGRATE -y --rsync --no-rsync $file1 2>&1 |
6876                 grep -q 'at the same time' ||
6877                 error "--rsync and --no-rsync accepted concurrently"
6878         echo "done."
6879
6880         # Clean up
6881         rm -f $file1
6882 }
6883 run_test 56wd "check lfs_migrate --rsync and --no-rsync work"
6884
6885 test_56we() {
6886         local td=$DIR/$tdir
6887         local tf=$td/$tfile
6888
6889         test_mkdir $td || error "cannot create $td"
6890         touch $tf || error "cannot touch $tf"
6891
6892         echo -n "Make sure --non-direct|-D works..."
6893         $LFS_MIGRATE -y --non-direct -v $tf 2>&1 |
6894                 grep -q "lfs migrate --non-direct" ||
6895                 error "--non-direct option cannot work correctly"
6896         $LFS_MIGRATE -y -D -v $tf 2>&1 |
6897                 grep -q "lfs migrate -D" ||
6898                 error "-D option cannot work correctly"
6899         echo "done."
6900 }
6901 run_test 56we "check lfs_migrate --non-direct|-D support"
6902
6903 test_56x() {
6904         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
6905         check_swap_layouts_support
6906
6907         local dir=$DIR/$tdir
6908         local ref1=/etc/passwd
6909         local file1=$dir/file1
6910
6911         test_mkdir $dir || error "creating dir $dir"
6912         $LFS setstripe -c 2 $file1
6913         cp $ref1 $file1
6914         $LFS migrate -c 1 $file1 || error "migrate failed rc = $?"
6915         stripe=$($LFS getstripe -c $file1)
6916         [[ $stripe == 1 ]] || error "stripe of $file1 is $stripe != 1"
6917         cmp $file1 $ref1 || error "content mismatch $file1 differs from $ref1"
6918
6919         # clean up
6920         rm -f $file1
6921 }
6922 run_test 56x "lfs migration support"
6923
6924 test_56xa() {
6925         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
6926         check_swap_layouts_support
6927
6928         local dir=$DIR/$tdir/$testnum
6929
6930         test_mkdir -p $dir
6931
6932         local ref1=/etc/passwd
6933         local file1=$dir/file1
6934
6935         $LFS setstripe -c 2 $file1
6936         cp $ref1 $file1
6937         $LFS migrate --block -c 1 $file1 || error "migrate failed rc = $?"
6938
6939         local stripe=$($LFS getstripe -c $file1)
6940
6941         [[ $stripe == 1 ]] || error "stripe of $file1 is $stripe != 1"
6942         cmp $file1 $ref1 || error "content mismatch $file1 differs from $ref1"
6943
6944         # clean up
6945         rm -f $file1
6946 }
6947 run_test 56xa "lfs migration --block support"
6948
6949 check_migrate_links() {
6950         local dir="$1"
6951         local file1="$dir/file1"
6952         local begin="$2"
6953         local count="$3"
6954         local runas="$4"
6955         local total_count=$(($begin + $count - 1))
6956         local symlink_count=10
6957         local uniq_count=10
6958
6959         if [ ! -f "$file1" ]; then
6960                 echo -n "creating initial file..."
6961                 $LFS setstripe -c 1 -S "512k" "$file1" ||
6962                         error "cannot setstripe initial file"
6963                 echo "done"
6964
6965                 echo -n "creating symlinks..."
6966                 for s in $(seq 1 $symlink_count); do
6967                         ln -s "$file1" "$dir/slink$s" ||
6968                                 error "cannot create symlinks"
6969                 done
6970                 echo "done"
6971
6972                 echo -n "creating nonlinked files..."
6973                 createmany -o "$dir/uniq" 1 10 &> /dev/null ||
6974                         error "cannot create nonlinked files"
6975                 echo "done"
6976         fi
6977
6978         # create hard links
6979         if [ ! -f "$dir/file$total_count" ]; then
6980                 echo -n "creating hard links $begin:$total_count..."
6981                 createmany -l"$file1" "$dir/file" "$begin" "$count" &>  \
6982                         /dev/null || error "cannot create hard links"
6983                 echo "done"
6984         fi
6985
6986         echo -n "checking number of hard links listed in xattrs..."
6987         local fid=$($LFS getstripe -F "$file1")
6988         local paths=($($LFS fid2path "$MOUNT" "$fid" 2> /dev/null))
6989
6990         echo "${#paths[*]}"
6991         if [ ${#paths[*]} -lt $total_count -a "$begin" -eq 2  ]; then
6992                         skip "hard link list has unexpected size, skipping test"
6993         fi
6994         if [ ${#paths[*]} -ge $total_count -a "$begin" -ne 2  ]; then
6995                         error "link names should exceed xattrs size"
6996         fi
6997
6998         echo -n "migrating files..."
6999         local migrate_out=$($runas $LFS_MIGRATE -y -S '1m' $dir)
7000         local rc=$?
7001         [ $rc -eq 0 ] || error "migrate failed rc = $rc"
7002         echo "done"
7003
7004         # make sure all links have been properly migrated
7005         echo -n "verifying files..."
7006         fid=$($LFS getstripe -F "$file1") ||
7007                 error "cannot get fid for file $file1"
7008         for i in $(seq 2 $total_count); do
7009                 local fid2=$($LFS getstripe -F $dir/file$i)
7010
7011                 [ "$fid2" == "$fid" ] ||
7012                         error "migrated hard link has mismatched FID"
7013         done
7014
7015         # make sure hard links were properly detected, and migration was
7016         # performed only once for the entire link set; nonlinked files should
7017         # also be migrated
7018         local actual=$(grep -c 'done' <<< "$migrate_out")
7019         local expected=$(($uniq_count + 1))
7020
7021         [ "$actual" -eq  "$expected" ] ||
7022                 error "hard links individually migrated ($actual != $expected)"
7023
7024         # make sure the correct number of hard links are present
7025         local hardlinks=$(stat -c '%h' "$file1")
7026
7027         [ $hardlinks -eq $total_count ] ||
7028                 error "num hard links $hardlinks != $total_count"
7029         echo "done"
7030
7031         return 0
7032 }
7033
7034 test_56xb() {
7035         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
7036                 skip "Need MDS version at least 2.10.55"
7037
7038         local dir="$DIR/$tdir"
7039
7040         test_mkdir "$dir" || error "cannot create dir $dir"
7041
7042         echo "testing lfs migrate mode when all links fit within xattrs"
7043         LFS_MIGRATE_RSYNC_MODE=false check_migrate_links "$dir" 2 99
7044
7045         echo "testing rsync mode when all links fit within xattrs"
7046         LFS_MIGRATE_RSYNC_MODE=true check_migrate_links "$dir" 2 99
7047
7048         echo "testing lfs migrate mode when all links do not fit within xattrs"
7049         LFS_MIGRATE_RSYNC_MODE=false check_migrate_links "$dir" 101 100
7050
7051         echo "testing rsync mode when all links do not fit within xattrs"
7052         LFS_MIGRATE_RSYNC_MODE=true check_migrate_links "$dir" 101 100
7053
7054         chown -R $RUNAS_ID $dir
7055         echo "testing non-root lfs migrate mode when not all links are in xattr"
7056         LFS_MIGRATE_RSYNC_MODE=false check_migrate_links "$dir" 101 100 "$RUNAS"
7057
7058         # clean up
7059         rm -rf $dir
7060 }
7061 run_test 56xb "lfs migration hard link support"
7062
7063 test_56xc() {
7064         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7065
7066         local dir="$DIR/$tdir"
7067
7068         test_mkdir "$dir" || error "cannot create dir $dir"
7069
7070         # Test 1: ensure file < 1 GB is always migrated with 1 stripe
7071         echo -n "Setting initial stripe for 20MB test file..."
7072         $LFS setstripe -c 2 -i 0 "$dir/20mb" ||
7073                 error "cannot setstripe 20MB file"
7074         echo "done"
7075         echo -n "Sizing 20MB test file..."
7076         $TRUNCATE "$dir/20mb" 20971520 || error "cannot create 20MB test file"
7077         echo "done"
7078         echo -n "Verifying small file autostripe count is 1..."
7079         $LFS_MIGRATE -y -A -C 1 "$dir/20mb" ||
7080                 error "cannot migrate 20MB file"
7081         local stripe_count=$($LFS getstripe -c "$dir/20mb") ||
7082                 error "cannot get stripe for $dir/20mb"
7083         [ $stripe_count -eq 1 ] ||
7084                 error "unexpected stripe count $stripe_count for 20MB file"
7085         rm -f "$dir/20mb"
7086         echo "done"
7087
7088         # Test 2: File is small enough to fit within the available space on
7089         # sqrt(size_in_gb) + 1 OSTs but is larger than 1GB.  The file must
7090         # have at least an additional 1KB for each desired stripe for test 3
7091         echo -n "Setting stripe for 1GB test file..."
7092         $LFS setstripe -c 1 -i 0 "$dir/1gb" || error "cannot setstripe 1GB file"
7093         echo "done"
7094         echo -n "Sizing 1GB test file..."
7095         # File size is 1GB + 3KB
7096         $TRUNCATE "$dir/1gb" 1073744896 || error "cannot create 1GB test file"
7097         echo "done"
7098
7099         # need at least 512MB per OST for 1GB file to fit in 2 stripes
7100         local avail=$($LCTL get_param -n llite.$FSNAME*.kbytesavail)
7101         if (( avail > 524288 * OSTCOUNT )); then
7102                 echo -n "Migrating 1GB file..."
7103                 $LFS_MIGRATE -y -A -C 1 "$dir/1gb" ||
7104                         error "cannot migrate 1GB file"
7105                 echo "done"
7106                 echo -n "Verifying autostripe count is sqrt(n) + 1..."
7107                 stripe_count=$($LFS getstripe -c "$dir/1gb") ||
7108                         error "cannot getstripe for 1GB file"
7109                 [ $stripe_count -eq 2 ] ||
7110                         error "unexpected stripe count $stripe_count != 2"
7111                 echo "done"
7112         fi
7113
7114         # Test 3: File is too large to fit within the available space on
7115         # sqrt(n) + 1 OSTs.  Simulate limited available space with -X
7116         if [ $OSTCOUNT -ge 3 ]; then
7117                 # The required available space is calculated as
7118                 # file size (1GB + 3KB) / OST count (3).
7119                 local kb_per_ost=349526
7120
7121                 echo -n "Migrating 1GB file with limit..."
7122                 $LFS_MIGRATE -y -A -C 1 -X $kb_per_ost "$dir/1gb" ||
7123                         error "cannot migrate 1GB file with limit"
7124                 echo "done"
7125
7126                 stripe_count=$($LFS getstripe -c "$dir/1gb")
7127                 echo -n "Verifying 1GB autostripe count with limited space..."
7128                 [ "$stripe_count" -a $stripe_count -ge 3 ] ||
7129                         error "unexpected stripe count $stripe_count (min 3)"
7130                 echo "done"
7131         fi
7132
7133         # clean up
7134         rm -rf $dir
7135 }
7136 run_test 56xc "lfs migration autostripe"
7137
7138 test_56xd() {
7139         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7140
7141         local dir=$DIR/$tdir
7142         local f_mgrt=$dir/$tfile.mgrt
7143         local f_yaml=$dir/$tfile.yaml
7144         local f_copy=$dir/$tfile.copy
7145         local layout_yaml="-E 1M -S 512K -c 1 -E -1 -S 1M -c 2 -i 0"
7146         local layout_copy="-c 2 -S 2M -i 1"
7147         local yamlfile=$dir/yamlfile
7148         local layout_before;
7149         local layout_after;
7150
7151         test_mkdir "$dir" || error "cannot create dir $dir"
7152         $LFS setstripe $layout_yaml $f_yaml ||
7153                 error "cannot setstripe $f_yaml with layout $layout_yaml"
7154         $LFS getstripe --yaml $f_yaml > $yamlfile
7155         $LFS setstripe $layout_copy $f_copy ||
7156                 error "cannot setstripe $f_copy with layout $layout_copy"
7157         touch $f_mgrt
7158         dd if=/dev/zero of=$f_mgrt bs=1M count=4
7159
7160         # 1. test option --yaml
7161         $LFS_MIGRATE -y --yaml $yamlfile $f_mgrt ||
7162                 error "cannot migrate $f_mgrt with --yaml $yamlfile"
7163         layout_before=$(get_layout_param $f_yaml)
7164         layout_after=$(get_layout_param $f_mgrt)
7165         [ "$layout_after" == "$layout_before" ] ||
7166                 error "lfs_migrate --yaml: $layout_after != $layout_before"
7167
7168         # 2. test option --copy
7169         $LFS_MIGRATE -y --copy $f_copy $f_mgrt ||
7170                 error "cannot migrate $f_mgrt with --copy $f_copy"
7171         layout_before=$(get_layout_param $f_copy)
7172         layout_after=$(get_layout_param $f_mgrt)
7173         [ "$layout_after" == "$layout_before" ] ||
7174                 error "lfs_migrate --copy: $layout_after != $layout_before"
7175 }
7176 run_test 56xd "check lfs_migrate --yaml and --copy support"
7177
7178 test_56xe() {
7179         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7180
7181         local dir=$DIR/$tdir
7182         local f_comp=$dir/$tfile
7183         local layout="-E 1M -S 512K -c 1 -E -1 -S 1M -c 2 -i 0"
7184         local layout_before=""
7185         local layout_after=""
7186
7187         test_mkdir "$dir" || error "cannot create dir $dir"
7188         $LFS setstripe $layout $f_comp ||
7189                 error "cannot setstripe $f_comp with layout $layout"
7190         layout_before=$(get_layout_param $f_comp)
7191         dd if=/dev/zero of=$f_comp bs=1M count=4
7192
7193         # 1. migrate a comp layout file by lfs_migrate
7194         $LFS_MIGRATE -y $f_comp || error "cannot migrate $f_comp by lfs_migrate"
7195         layout_after=$(get_layout_param $f_comp)
7196         [ "$layout_before" == "$layout_after" ] ||
7197                 error "lfs_migrate: $layout_before != $layout_after"
7198
7199         # 2. migrate a comp layout file by lfs migrate
7200         $LFS migrate $f_comp || error "cannot migrate $f_comp by lfs migrate"
7201         layout_after=$(get_layout_param $f_comp)
7202         [ "$layout_before" == "$layout_after" ] ||
7203                 error "lfs migrate: $layout_before != $layout_after"
7204 }
7205 run_test 56xe "migrate a composite layout file"
7206
7207 test_56xf() {
7208         [[ $OSTCOUNT -ge 2 ]] || skip_env "needs >= 2 OSTs"
7209
7210         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
7211                 skip "Need server version at least 2.13.53"
7212
7213         local dir=$DIR/$tdir
7214         local f_comp=$dir/$tfile
7215         local layout="-E 1M -c1 -E -1 -c2"
7216         local fid_before=""
7217         local fid_after=""
7218
7219         test_mkdir "$dir" || error "cannot create dir $dir"
7220         $LFS setstripe $layout $f_comp ||
7221                 error "cannot setstripe $f_comp with layout $layout"
7222         fid_before=$($LFS getstripe --fid $f_comp)
7223         dd if=/dev/zero of=$f_comp bs=1M count=4
7224
7225         # 1. migrate a comp layout file to a comp layout
7226         $LFS migrate $f_comp || error "cannot migrate $f_comp by lfs migrate"
7227         fid_after=$($LFS getstripe --fid $f_comp)
7228         [ "$fid_before" == "$fid_after" ] ||
7229                 error "comp-to-comp migrate: $fid_before != $fid_after"
7230
7231         # 2. migrate a comp layout file to a plain layout
7232         $LFS migrate -c2 $f_comp ||
7233                 error "cannot migrate $f_comp by lfs migrate"
7234         fid_after=$($LFS getstripe --fid $f_comp)
7235         [ "$fid_before" == "$fid_after" ] ||
7236                 error "comp-to-plain migrate: $fid_before != $fid_after"
7237
7238         # 3. migrate a plain layout file to a comp layout
7239         $LFS migrate $layout $f_comp ||
7240                 error "cannot migrate $f_comp by lfs migrate"
7241         fid_after=$($LFS getstripe --fid $f_comp)
7242         [ "$fid_before" == "$fid_after" ] ||
7243                 error "plain-to-comp migrate: $fid_before != $fid_after"
7244 }
7245 run_test 56xf "FID is not lost during migration of a composite layout file"
7246
7247 test_56y() {
7248         [ $MDS1_VERSION -lt $(version_code 2.4.53) ] &&
7249                 skip "No HSM $(lustre_build_version $SINGLEMDS) MDS < 2.4.53"
7250
7251         local res=""
7252         local dir=$DIR/$tdir
7253         local f1=$dir/file1
7254         local f2=$dir/file2
7255
7256         test_mkdir -p $dir || error "creating dir $dir"
7257         touch $f1 || error "creating std file $f1"
7258         $MULTIOP $f2 H2c || error "creating released file $f2"
7259
7260         # a directory can be raid0, so ask only for files
7261         res=$($LFS find $dir -L raid0 -type f | wc -l)
7262         [[ $res == 2 ]] || error "search raid0: found $res files != 2"
7263
7264         res=$($LFS find $dir \! -L raid0 -type f | wc -l)
7265         [[ $res == 0 ]] || error "search !raid0: found $res files != 0"
7266
7267         # only files can be released, so no need to force file search
7268         res=$($LFS find $dir -L released)
7269         [[ $res == $f2 ]] || error "search released: found $res != $f2"
7270
7271         res=$($LFS find $dir -type f \! -L released)
7272         [[ $res == $f1 ]] || error "search !released: found $res != $f1"
7273 }
7274 run_test 56y "lfs find -L raid0|released"
7275
7276 test_56z() { # LU-4824
7277         # This checks to make sure 'lfs find' continues after errors
7278         # There are two classes of errors that should be caught:
7279         # - If multiple paths are provided, all should be searched even if one
7280         #   errors out
7281         # - If errors are encountered during the search, it should not terminate
7282         #   early
7283         local dir=$DIR/$tdir
7284         local i
7285
7286         test_mkdir $dir
7287         for i in d{0..9}; do
7288                 test_mkdir $dir/$i
7289                 touch $dir/$i/$tfile
7290         done
7291         $LFS find $DIR/non_existent_dir $dir &&
7292                 error "$LFS find did not return an error"
7293         # Make a directory unsearchable. This should NOT be the last entry in
7294         # directory order.  Arbitrarily pick the 6th entry
7295         chmod 700 $($LFS find $dir -type d | sed '6!d')
7296
7297         $RUNAS $LFS find $DIR/non_existent $dir
7298         local count=$($RUNAS $LFS find $DIR/non_existent $dir | wc -l)
7299
7300         # The user should be able to see 10 directories and 9 files
7301         (( count == 19 )) ||
7302                 error "$LFS find found $count != 19 entries after error"
7303 }
7304 run_test 56z "lfs find should continue after an error"
7305
7306 test_56aa() { # LU-5937
7307         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
7308
7309         local dir=$DIR/$tdir
7310
7311         mkdir $dir
7312         $LFS setdirstripe -c$MDSCOUNT $dir/striped_dir
7313
7314         createmany -o $dir/striped_dir/${tfile}- 1024
7315         local dirs=$($LFS find --size +8k $dir/)
7316
7317         [ -n "$dirs" ] || error "lfs find --size wrong under striped dir"
7318 }
7319 run_test 56aa "lfs find --size under striped dir"
7320
7321 test_56ab() { # LU-10705
7322         test_mkdir $DIR/$tdir
7323         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=8k count=1 seek=2k
7324         dd if=/dev/zero of=$DIR/$tdir/$tfile.2 bs=4k count=1 seek=4k
7325         dd if=/dev/zero of=$DIR/$tdir/$tfile.3 bs=1M count=2 seek=16
7326         # Flush writes to ensure valid blocks.  Need to be more thorough for
7327         # ZFS, since blocks are not allocated/returned to client immediately.
7328         sync_all_data
7329         wait_zfs_commit ost1 2
7330         cancel_lru_locks osc
7331         ls -ls $DIR/$tdir
7332
7333         local files=$($LFS find --size +16M $DIR/$tdir | wc -l)
7334
7335         [[ $files == 3 ]] || error ">16M size files $files isn't 3 as expected"
7336
7337         files=$($LFS find --blocks +1M $DIR/$tdir | wc -l)
7338         [[ $files == 1 ]] || error ">1M blocks files $files isn't 1 as expected"
7339
7340         rm -f $DIR/$tdir/$tfile.[123]
7341 }
7342 run_test 56ab "lfs find --blocks"
7343
7344 test_56ba() {
7345         [ $MDS1_VERSION -lt $(version_code 2.10.50) ] &&
7346                 skip "Need MDS version at least 2.10.50"
7347
7348         # Create composite files with one component
7349         local dir=$DIR/$tdir
7350
7351         setup_56 $dir/1Mfiles 5 1 "-S 1M --component-end 1M"
7352         # Create composite files with three components
7353         setup_56 $dir/2Mfiles 5 2 "-E 2M -S 1M -E 4M -E 6M"
7354         # Create non-composite files
7355         createmany -o $dir/${tfile}- 10
7356
7357         local nfiles=$($LFS find --component-end 1M --type f $dir | wc -l)
7358
7359         [[ $nfiles == 10 ]] ||
7360                 error "lfs find -E 1M found $nfiles != 10 files"
7361
7362         nfiles=$($LFS find ! -E 1M --type f $dir | wc -l)
7363         [[ $nfiles == 25 ]] ||
7364                 error "lfs find ! -E 1M found $nfiles != 25 files"
7365
7366         # All files have a component that starts at 0
7367         nfiles=$($LFS find --component-start 0 --type f $dir | wc -l)
7368         [[ $nfiles == 35 ]] ||
7369                 error "lfs find --component-start 0 - $nfiles != 35 files"
7370
7371         nfiles=$($LFS find --component-start 2M --type f $dir | wc -l)
7372         [[ $nfiles == 15 ]] ||
7373                 error "lfs find --component-start 2M - $nfiles != 15 files"
7374
7375         # All files created here have a componenet that does not starts at 2M
7376         nfiles=$($LFS find ! --component-start 2M --type f $dir | wc -l)
7377         [[ $nfiles == 35 ]] ||
7378                 error "lfs find ! --component-start 2M - $nfiles != 35 files"
7379
7380         # Find files with a specified number of components
7381         local nfiles=$($LFS find --component-count 3 --type f $dir | wc -l)
7382         [[ $nfiles == 15 ]] ||
7383                 error "lfs find --component-count 3 - $nfiles != 15 files"
7384
7385         # Remember non-composite files have a component count of zero
7386         local nfiles=$($LFS find --component-count 0 --type f $dir | wc -l)
7387         [[ $nfiles == 10 ]] ||
7388                 error "lfs find --component-count 0 - $nfiles != 10 files"
7389
7390         nfiles=$($LFS find ! --component-count 3 --type f $dir | wc -l)
7391         [[ $nfiles == 20 ]] ||
7392                 error "lfs find ! --component-count 3 - $nfiles != 20 files"
7393
7394         # All files have a flag called "init"
7395         local nfiles=$($LFS find --component-flags init --type f $dir | wc -l)
7396         [[ $nfiles == 35 ]] ||
7397                 error "lfs find --component-flags init - $nfiles != 35 files"
7398
7399         # Multi-component files will have a component not initialized
7400         local nfiles=$($LFS find ! --component-flags init --type f $dir | wc -l)
7401         [[ $nfiles == 15 ]] ||
7402                 error "lfs find !--component-flags init - $nfiles != 15 files"
7403
7404         rm -rf $dir
7405
7406 }
7407 run_test 56ba "test lfs find --component-end, -start, -count, and -flags"
7408
7409 test_56ca() {
7410         [[ $MDS1_VERSION -ge $(version_code 2.10.57) ]] ||
7411                 skip "Need MDS version at least 2.10.57"
7412
7413         local td=$DIR/$tdir
7414         local tf=$td/$tfile
7415         local dir
7416         local nfiles
7417         local cmd
7418         local i
7419         local j
7420
7421         # create mirrored directories and mirrored files
7422         mkdir $td || error "mkdir $td failed"
7423         $LFS mirror create -N3 $td || error "create mirrored dir $td failed"
7424         createmany -o $tf- 10 || error "create $tf- failed"
7425
7426         for i in $(seq 2); do
7427                 dir=$td/dir$i
7428                 mkdir $dir || error "mkdir $dir failed"
7429                 $LFS mirror create -N$((3 + i)) $dir ||
7430                         error "create mirrored dir $dir failed"
7431                 createmany -o $dir/$tfile- 10 ||
7432                         error "create $dir/$tfile- failed"
7433         done
7434
7435         # change the states of some mirrored files
7436         echo foo > $tf-6
7437         for i in $(seq 2); do
7438                 dir=$td/dir$i
7439                 for j in $(seq 4 9); do
7440                         echo foo > $dir/$tfile-$j
7441                 done
7442         done
7443
7444         # find mirrored files with specific mirror count
7445         cmd="$LFS find --mirror-count 3 --type f $td"
7446         nfiles=$($cmd | wc -l)
7447         [[ $nfiles = 10 ]] || error "$cmd: $nfiles != 10 files"
7448
7449         cmd="$LFS find ! --mirror-count 3 --type f $td"
7450         nfiles=$($cmd | wc -l)
7451         [[ $nfiles = 20 ]] || error "$cmd: $nfiles != 20 files"
7452
7453         cmd="$LFS find --mirror-count +2 --type f $td"
7454         nfiles=$($cmd | wc -l)
7455         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
7456
7457         cmd="$LFS find --mirror-count -6 --type f $td"
7458         nfiles=$($cmd | wc -l)
7459         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
7460
7461         # find mirrored files with specific file state
7462         cmd="$LFS find --maxdepth 1 --mirror-state=^ro --type f $td"
7463         [[ $($cmd) = $tf-6 ]] || error "$cmd: didn't return $tf-6"
7464
7465         cmd="$LFS find --mirror-state=ro --type f $td"
7466         nfiles=$($cmd | wc -l)
7467         [[ $nfiles = 17 ]] || error "$cmd: $nfiles != 17 files"
7468
7469         cmd="$LFS find ! --mirror-state=ro --type f $td"
7470         nfiles=$($cmd | wc -l)
7471         [[ $nfiles = 13 ]] || error "$cmd: $nfiles != 13 files"
7472
7473         cmd="$LFS find --mirror-state=wp --type f $td"
7474         nfiles=$($cmd | wc -l)
7475         [[ $nfiles = 13 ]] || error "$cmd: $nfiles != 13 files"
7476
7477         cmd="$LFS find ! --mirror-state=sp --type f $td"
7478         nfiles=$($cmd | wc -l)
7479         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
7480 }
7481 run_test 56ca "check lfs find --mirror-count|-N and --mirror-state"
7482
7483 test_57a() {
7484         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7485         # note test will not do anything if MDS is not local
7486         if [ "$mds1_FSTYPE" != ldiskfs ]; then
7487                 skip_env "ldiskfs only test"
7488         fi
7489         remote_mds_nodsh && skip "remote MDS with nodsh"
7490
7491         local MNTDEV="osd*.*MDT*.mntdev"
7492         DEV=$(do_facet $SINGLEMDS lctl get_param -n $MNTDEV)
7493         [ -z "$DEV" ] && error "can't access $MNTDEV"
7494         for DEV in $(do_facet $SINGLEMDS lctl get_param -n $MNTDEV); do
7495                 do_facet $SINGLEMDS $DUMPE2FS -h $DEV > $TMP/t57a.dump ||
7496                         error "can't access $DEV"
7497                 DEVISIZE=$(awk '/Inode size:/ { print $3 }' $TMP/t57a.dump)
7498                 [[ $DEVISIZE -gt 128 ]] || error "inode size $DEVISIZE"
7499                 rm $TMP/t57a.dump
7500         done
7501 }
7502 run_test 57a "verify MDS filesystem created with large inodes =="
7503
7504 test_57b() {
7505         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7506         if [ "$mds1_FSTYPE" != ldiskfs ]; then
7507                 skip_env "ldiskfs only test"
7508         fi
7509         remote_mds_nodsh && skip "remote MDS with nodsh"
7510
7511         local dir=$DIR/$tdir
7512         local filecount=100
7513         local file1=$dir/f1
7514         local fileN=$dir/f$filecount
7515
7516         rm -rf $dir || error "removing $dir"
7517         test_mkdir -c1 $dir
7518         local mdtidx=$($LFS getstripe -m $dir)
7519         local mdtname=MDT$(printf %04x $mdtidx)
7520         local facet=mds$((mdtidx + 1))
7521
7522         echo "mcreating $filecount files"
7523         createmany -m $dir/f 1 $filecount || error "creating files in $dir"
7524
7525         # verify that files do not have EAs yet
7526         $LFS getstripe $file1 2>&1 | grep -q "no stripe" ||
7527                 error "$file1 has an EA"
7528         $LFS getstripe $fileN 2>&1 | grep -q "no stripe" ||
7529                 error "$fileN has an EA"
7530
7531         sync
7532         sleep 1
7533         df $dir  #make sure we get new statfs data
7534         local mdsfree=$(do_facet $facet \
7535                         lctl get_param -n osd*.*$mdtname.kbytesfree)
7536         local mdcfree=$(lctl get_param -n mdc.*$mdtname-mdc-*.kbytesfree)
7537         local file
7538
7539         echo "opening files to create objects/EAs"
7540         for file in $(seq -f $dir/f%g 1 $filecount); do
7541                 $OPENFILE -f O_RDWR $file > /dev/null 2>&1 ||
7542                         error "opening $file"
7543         done
7544
7545         # verify that files have EAs now
7546         $LFS getstripe $file1 | grep -q "obdidx" || error "$file1 missing EA"
7547         $LFS getstripe $fileN | grep -q "obdidx" || error "$fileN missing EA"
7548
7549         sleep 1  #make sure we get new statfs data
7550         df $dir
7551         local mdsfree2=$(do_facet $facet \
7552                          lctl get_param -n osd*.*$mdtname.kbytesfree)
7553         local mdcfree2=$(lctl get_param -n mdc.*$mdtname-mdc-*.kbytesfree)
7554
7555         if [[ $mdcfree2 -lt $((mdcfree - 16)) ]]; then
7556                 if [ "$mdsfree" != "$mdsfree2" ]; then
7557                         error "MDC before $mdcfree != after $mdcfree2"
7558                 else
7559                         echo "MDC before $mdcfree != after $mdcfree2"
7560                         echo "unable to confirm if MDS has large inodes"
7561                 fi
7562         fi
7563         rm -rf $dir
7564 }
7565 run_test 57b "default LOV EAs are stored inside large inodes ==="
7566
7567 test_58() {
7568         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7569         [ -z "$(which wiretest 2>/dev/null)" ] &&
7570                         skip_env "could not find wiretest"
7571
7572         wiretest
7573 }
7574 run_test 58 "verify cross-platform wire constants =============="
7575
7576 test_59() {
7577         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7578
7579         echo "touch 130 files"
7580         createmany -o $DIR/f59- 130
7581         echo "rm 130 files"
7582         unlinkmany $DIR/f59- 130
7583         sync
7584         # wait for commitment of removal
7585         wait_delete_completed
7586 }
7587 run_test 59 "verify cancellation of llog records async ========="
7588
7589 TEST60_HEAD="test_60 run $RANDOM"
7590 test_60a() {
7591         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7592         remote_mgs_nodsh && skip "remote MGS with nodsh"
7593         do_facet mgs "! which run-llog.sh &> /dev/null" &&
7594                 do_facet mgs "! ls run-llog.sh &> /dev/null" &&
7595                         skip_env "missing subtest run-llog.sh"
7596
7597         log "$TEST60_HEAD - from kernel mode"
7598         do_facet mgs "$LCTL dk > /dev/null"
7599         do_facet mgs "bash run-llog.sh" || error "run-llog.sh failed"
7600         do_facet mgs $LCTL dk > $TMP/$tfile
7601
7602         # LU-6388: test llog_reader
7603         local llog_reader=$(do_facet mgs "which llog_reader 2> /dev/null")
7604         llog_reader=${llog_reader:-$LUSTRE/utils/llog_reader}
7605         [ -z $(do_facet mgs ls -d $llog_reader 2> /dev/null) ] &&
7606                         skip_env "missing llog_reader"
7607         local fstype=$(facet_fstype mgs)
7608         [ $fstype != ldiskfs -a $fstype != zfs ] &&
7609                 skip_env "Only for ldiskfs or zfs type mgs"
7610
7611         local mntpt=$(facet_mntpt mgs)
7612         local mgsdev=$(mgsdevname 1)
7613         local fid_list
7614         local fid
7615         local rec_list
7616         local rec
7617         local rec_type
7618         local obj_file
7619         local path
7620         local seq
7621         local oid
7622         local pass=true
7623
7624         #get fid and record list
7625         fid_list=($(awk '/9_sub.*record/ { print $NF }' $TMP/$tfile |
7626                 tail -n 4))
7627         rec_list=($(awk '/9_sub.*record/ { print $((NF-3)) }' $TMP/$tfile |
7628                 tail -n 4))
7629         #remount mgs as ldiskfs or zfs type
7630         stop mgs || error "stop mgs failed"
7631         mount_fstype mgs || error "remount mgs failed"
7632         for ((i = 0; i < ${#fid_list[@]}; i++)); do
7633                 fid=${fid_list[i]}
7634                 rec=${rec_list[i]}
7635                 seq=$(echo $fid | awk -F ':' '{ print $1 }' | sed -e "s/^0x//g")
7636                 oid=$(echo $fid | awk -F ':' '{ print $2 }' | sed -e "s/^0x//g")
7637                 oid=$((16#$oid))
7638
7639                 case $fstype in
7640                         ldiskfs )
7641                                 obj_file=$mntpt/O/$seq/d$((oid%32))/$oid ;;
7642                         zfs )
7643                                 obj_file=$mntpt/oi.$(($((16#$seq))&127))/$fid ;;
7644                 esac
7645                 echo "obj_file is $obj_file"
7646                 do_facet mgs $llog_reader $obj_file
7647
7648                 rec_type=$(do_facet mgs $llog_reader $obj_file | grep "type=" |
7649                         awk '{ print $3 }' | sed -e "s/^type=//g")
7650                 if [ $rec_type != $rec ]; then
7651                         echo "FAILED test_60a wrong record type $rec_type," \
7652                               "should be $rec"
7653                         pass=false
7654                         break
7655                 fi
7656
7657                 #check obj path if record type is LLOG_LOGID_MAGIC
7658                 if [ "$rec" == "1064553b" ]; then
7659                         path=$(do_facet mgs $llog_reader $obj_file |
7660                                 grep "path=" | awk '{ print $NF }' |
7661                                 sed -e "s/^path=//g")
7662                         if [ $obj_file != $mntpt/$path ]; then
7663                                 echo "FAILED test_60a wrong obj path" \
7664                                       "$montpt/$path, should be $obj_file"
7665                                 pass=false
7666                                 break
7667                         fi
7668                 fi
7669         done
7670         rm -f $TMP/$tfile
7671         #restart mgs before "error", otherwise it will block the next test
7672         stop mgs || error "stop mgs failed"
7673         start mgs $(mgsdevname) $MGS_MOUNT_OPTS || error "start mgs failed"
7674         $pass || error "test failed, see FAILED test_60a messages for specifics"
7675 }
7676 run_test 60a "llog_test run from kernel module and test llog_reader"
7677
7678 test_60b() { # bug 6411
7679         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7680
7681         dmesg > $DIR/$tfile
7682         LLOG_COUNT=$(do_facet mgs dmesg |
7683                      awk "/$TEST60_HEAD/ { marker = 1; from_marker = 0; }
7684                           /llog_[a-z]*.c:[0-9]/ {
7685                                 if (marker)
7686                                         from_marker++
7687                                 from_begin++
7688                           }
7689                           END {
7690                                 if (marker)
7691                                         print from_marker
7692                                 else
7693                                         print from_begin
7694                           }")
7695
7696         [[ $LLOG_COUNT -gt 120 ]] &&
7697                 error "CDEBUG_LIMIT not limiting messages ($LLOG_COUNT)" || true
7698 }
7699 run_test 60b "limit repeated messages from CERROR/CWARN"
7700
7701 test_60c() {
7702         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7703
7704         echo "create 5000 files"
7705         createmany -o $DIR/f60c- 5000
7706 #define OBD_FAIL_MDS_LLOG_CREATE_FAILED  0x137
7707         lctl set_param fail_loc=0x80000137
7708         unlinkmany $DIR/f60c- 5000
7709         lctl set_param fail_loc=0
7710 }
7711 run_test 60c "unlink file when mds full"
7712
7713 test_60d() {
7714         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7715
7716         SAVEPRINTK=$(lctl get_param -n printk)
7717         # verify "lctl mark" is even working"
7718         MESSAGE="test message ID $RANDOM $$"
7719         $LCTL mark "$MESSAGE" || error "$LCTL mark failed"
7720         dmesg | grep -q "$MESSAGE" || error "didn't find debug marker in log"
7721
7722         lctl set_param printk=0 || error "set lnet.printk failed"
7723         lctl get_param -n printk | grep emerg || error "lnet.printk dropped emerg"
7724         MESSAGE="new test message ID $RANDOM $$"
7725         # Assume here that libcfs_debug_mark_buffer() uses D_WARNING
7726         $LCTL mark "$MESSAGE" || error "$LCTL mark failed"
7727         dmesg | grep -q "$MESSAGE" && error "D_WARNING wasn't masked" || true
7728
7729         lctl set_param -n printk="$SAVEPRINTK"
7730 }
7731 run_test 60d "test printk console message masking"
7732
7733 test_60e() {
7734         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7735         remote_mds_nodsh && skip "remote MDS with nodsh"
7736
7737         touch $DIR/$tfile
7738 #define OBD_FAIL_MDS_LLOG_CREATE_FAILED2  0x15b
7739         do_facet mds1 lctl set_param fail_loc=0x15b
7740         rm $DIR/$tfile
7741 }
7742 run_test 60e "no space while new llog is being created"
7743
7744 test_60g() {
7745         local pid
7746         local i
7747
7748         test_mkdir -c $MDSCOUNT $DIR/$tdir
7749
7750         (
7751                 local index=0
7752                 while true; do
7753                         $LFS setdirstripe -i $(($index % $MDSCOUNT)) \
7754                                 -c $MDSCOUNT $DIR/$tdir/subdir$index \
7755                                 2>/dev/null
7756                         mkdir $DIR/$tdir/subdir$index 2>/dev/null
7757                         rmdir $DIR/$tdir/subdir$index 2>/dev/null
7758                         index=$((index + 1))
7759                 done
7760         ) &
7761
7762         pid=$!
7763
7764         for i in {0..100}; do
7765                 # define OBD_FAIL_OSD_TXN_START    0x19a
7766                 local index=$((i % MDSCOUNT + 1))
7767
7768                 do_facet mds$index $LCTL set_param fail_loc=0x8000019a \
7769                         > /dev/null
7770                 sleep 0.01
7771         done
7772
7773         kill -9 $pid
7774
7775         for i in $(seq $MDSCOUNT); do
7776                 do_facet mds$i $LCTL set_param fail_loc=0 > /dev/null
7777         done
7778
7779         mkdir $DIR/$tdir/new || error "mkdir failed"
7780         rmdir $DIR/$tdir/new || error "rmdir failed"
7781
7782         do_facet mds1 $LCTL lfsck_start -M $(facet_svc mds1) -A -C \
7783                 -t namespace
7784         for i in $(seq $MDSCOUNT); do
7785                 wait_update_facet mds$i "$LCTL get_param -n \
7786                         mdd.$(facet_svc mds$i).lfsck_namespace |
7787                         awk '/^status/ { print \\\$2 }'" "completed"
7788         done
7789
7790         ls -R $DIR/$tdir || error "ls failed"
7791         rm -rf $DIR/$tdir || error "rmdir failed"
7792 }
7793 run_test 60g "transaction abort won't cause MDT hung"
7794
7795 test_60h() {
7796         [ $MDS1_VERSION -le $(version_code 2.12.52) ] &&
7797                 skip "Need MDS version at least 2.12.52"
7798         [ $MDSCOUNT -lt 2 ] && skip "Need at least 2 MDTs"
7799
7800         local f
7801
7802         #define OBD_FAIL_MDS_STRIPE_CREATE       0x188
7803         #define OBD_FAIL_MDS_STRIPE_FID          0x189
7804         for fail_loc in 0x80000188 0x80000189; do
7805                 do_facet mds1 "$LCTL set_param fail_loc=$fail_loc"
7806                 $LFS mkdir -c $MDSCOUNT -i 0 $DIR/$tdir-$fail_loc ||
7807                         error "mkdir $dir-$fail_loc failed"
7808                 for i in {0..10}; do
7809                         # create may fail on missing stripe
7810                         echo $i > $DIR/$tdir-$fail_loc/$i
7811                 done
7812                 $LFS getdirstripe $DIR/$tdir-$fail_loc ||
7813                         error "getdirstripe $tdir-$fail_loc failed"
7814                 $LFS migrate -m 1 $DIR/$tdir-$fail_loc ||
7815                         error "migrate $tdir-$fail_loc failed"
7816                 $LFS getdirstripe $DIR/$tdir-$fail_loc ||
7817                         error "getdirstripe $tdir-$fail_loc failed"
7818                 pushd $DIR/$tdir-$fail_loc
7819                 for f in *; do
7820                         echo $f | cmp $f - || error "$f data mismatch"
7821                 done
7822                 popd
7823                 rm -rf $DIR/$tdir-$fail_loc
7824         done
7825 }
7826 run_test 60h "striped directory with missing stripes can be accessed"
7827
7828 test_61a() {
7829         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7830
7831         f="$DIR/f61"
7832         dd if=/dev/zero of=$f bs=$PAGE_SIZE count=1 || error "dd $f failed"
7833         cancel_lru_locks osc
7834         $MULTIOP $f OSMWUc || error "$MULTIOP $f failed"
7835         sync
7836 }
7837 run_test 61a "mmap() writes don't make sync hang ================"
7838
7839 test_61b() {
7840         mmap_mknod_test $DIR/$tfile || error "mmap_mknod_test failed"
7841 }
7842 run_test 61b "mmap() of unstriped file is successful"
7843
7844 # bug 2330 - insufficient obd_match error checking causes LBUG
7845 test_62() {
7846         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7847
7848         f="$DIR/f62"
7849         echo foo > $f
7850         cancel_lru_locks osc
7851         lctl set_param fail_loc=0x405
7852         cat $f && error "cat succeeded, expect -EIO"
7853         lctl set_param fail_loc=0
7854 }
7855 # This test is now irrelevant (as of bug 10718 inclusion), we no longer
7856 # match every page all of the time.
7857 #run_test 62 "verify obd_match failure doesn't LBUG (should -EIO)"
7858
7859 # bug 2319 - oig_wait() interrupted causes crash because of invalid waitq.
7860 # Though this test is irrelevant anymore, it helped to reveal some
7861 # other grant bugs (LU-4482), let's keep it.
7862 test_63a() {   # was test_63
7863         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7864
7865         MAX_DIRTY_MB=$(lctl get_param -n osc.*.max_dirty_mb | head -n 1)
7866
7867         for i in `seq 10` ; do
7868                 dd if=/dev/zero of=$DIR/f63 bs=8k &
7869                 sleep 5
7870                 kill $!
7871                 sleep 1
7872         done
7873
7874         rm -f $DIR/f63 || true
7875 }
7876 run_test 63a "Verify oig_wait interruption does not crash ======="
7877
7878 # bug 2248 - async write errors didn't return to application on sync
7879 # bug 3677 - async write errors left page locked
7880 test_63b() {
7881         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7882
7883         debugsave
7884         lctl set_param debug=-1
7885
7886         # ensure we have a grant to do async writes
7887         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1
7888         rm $DIR/$tfile
7889
7890         sync    # sync lest earlier test intercept the fail_loc
7891
7892         #define OBD_FAIL_OSC_BRW_PREP_REQ        0x406
7893         lctl set_param fail_loc=0x80000406
7894         $MULTIOP $DIR/$tfile Owy && \
7895                 error "sync didn't return ENOMEM"
7896         sync; sleep 2; sync     # do a real sync this time to flush page
7897         lctl get_param -n llite.*.dump_page_cache | grep locked && \
7898                 error "locked page left in cache after async error" || true
7899         debugrestore
7900 }
7901 run_test 63b "async write errors should be returned to fsync ==="
7902
7903 test_64a () {
7904         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7905
7906         lfs df $DIR
7907         lctl get_param osc.*[oO][sS][cC][_-]*.cur* | grep "=[1-9]"
7908 }
7909 run_test 64a "verify filter grant calculations (in kernel) ====="
7910
7911 test_64b () {
7912         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7913
7914         sh oos.sh $MOUNT || error "oos.sh failed: $?"
7915 }
7916 run_test 64b "check out-of-space detection on client"
7917
7918 test_64c() {
7919         $LCTL set_param osc.*OST0000-osc-[^mM]*.cur_grant_bytes=0
7920 }
7921 run_test 64c "verify grant shrink"
7922
7923 import_param() {
7924         local tgt=$1
7925         local param=$2
7926
7927         $LCTL get_param osc.$tgt.import | awk "/$param/ { print \$2 }"
7928 }
7929
7930 # this does exactly what osc_request.c:osc_announce_cached() does in
7931 # order to calculate max amount of grants to ask from server
7932 want_grant() {
7933         local tgt=$1
7934
7935         local nrpages=$($LCTL get_param -n osc.$tgt.max_pages_per_rpc)
7936         local rpc_in_flight=$($LCTL get_param -n osc.$tgt.max_rpcs_in_flight)
7937
7938         ((rpc_in_flight++));
7939         nrpages=$((nrpages * rpc_in_flight))
7940
7941         local dirty_max_pages=$($LCTL get_param -n osc.$tgt.max_dirty_mb)
7942
7943         dirty_max_pages=$((dirty_max_pages * 1024 * 1024 / PAGE_SIZE))
7944
7945         [[ $dirty_max_pages -gt $nrpages ]] && nrpages=$dirty_max_pages
7946         local undirty=$((nrpages * PAGE_SIZE))
7947
7948         local max_extent_pages
7949         max_extent_pages=$(import_param $tgt grant_max_extent_size)
7950         max_extent_pages=$((max_extent_pages / PAGE_SIZE))
7951         local nrextents=$(((nrpages + max_extent_pages - 1) / max_extent_pages))
7952         local grant_extent_tax
7953         grant_extent_tax=$(import_param $tgt grant_extent_tax)
7954
7955         undirty=$((undirty + nrextents * grant_extent_tax))
7956
7957         echo $undirty
7958 }
7959
7960 # this is size of unit for grant allocation. It should be equal to
7961 # what tgt_grant.c:tgt_grant_chunk() calculates
7962 grant_chunk() {
7963         local tgt=$1
7964         local max_brw_size
7965         local grant_extent_tax
7966
7967         max_brw_size=$(import_param $tgt max_brw_size)
7968
7969         grant_extent_tax=$(import_param $tgt grant_extent_tax)
7970
7971         echo $(((max_brw_size + grant_extent_tax) * 2))
7972 }
7973
7974 test_64d() {
7975         [ $OST1_VERSION -ge $(version_code 2.10.56) ] ||
7976                 skip "OST < 2.10.55 doesn't limit grants enough"
7977
7978         local tgt=$($LCTL dl | awk '/OST0000-osc-[^mM]/ { print $4 }')
7979
7980         [[ "$($LCTL get_param osc.${tgt}.import)" =~ "grant_param" ]] ||
7981                 skip "no grant_param connect flag"
7982
7983         local olddebug="$($LCTL get_param -n debug 2> /dev/null)"
7984
7985         $LCTL set_param -n -n debug="$OLDDEBUG" || true
7986         stack_trap "$LCTL set_param -n debug='$olddebug'" EXIT
7987
7988
7989         local max_cur_granted=$(($(want_grant $tgt) + $(grant_chunk $tgt)))
7990         stack_trap "rm -f $DIR/$tfile && wait_delete_completed" EXIT
7991
7992         $LFS setstripe $DIR/$tfile -i 0 -c 1
7993         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1000 &
7994         ddpid=$!
7995
7996         while kill -0 $ddpid; do
7997                 local cur_grant=$($LCTL get_param -n osc.$tgt.cur_grant_bytes)
7998
7999                 if [[ $cur_grant -gt $max_cur_granted ]]; then
8000                         kill $ddpid
8001                         error "cur_grant $cur_grant > $max_cur_granted"
8002                 fi
8003
8004                 sleep 1
8005         done
8006 }
8007 run_test 64d "check grant limit exceed"
8008
8009 check_grants() {
8010         local tgt=$1
8011         local expected=$2
8012         local msg=$3
8013         local cur_grants=$($LCTL get_param -n osc.$tgt.cur_grant_bytes)
8014
8015         ((cur_grants == expected)) ||
8016                 error "$msg: grants mismatch: $cur_grants, expected $expected"
8017 }
8018
8019 round_up_p2() {
8020         echo $((($1 + $2 - 1) & ~($2 - 1)))
8021 }
8022
8023 test_64e() {
8024         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8025         [ $OST1_VERSION -ge $(version_code 2.11.56) ] ||
8026                 skip "Need OSS version at least 2.11.56"
8027
8028         # Remount client to reset grant
8029         remount_client $MOUNT || error "failed to remount client"
8030         local osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
8031
8032         local init_grants=$(import_param $osc_tgt initial_grant)
8033
8034         check_grants $osc_tgt $init_grants "init grants"
8035
8036         local extent_tax=$(import_param $osc_tgt grant_extent_tax)
8037         local max_brw_size=$(import_param $osc_tgt max_brw_size)
8038         local gbs=$(import_param $osc_tgt grant_block_size)
8039
8040         # write random number of bytes from max_brw_size / 4 to max_brw_size
8041         local write_bytes=$(shuf -i $((max_brw_size / 4))-$max_brw_size -n 1)
8042         # align for direct io
8043         write_bytes=$(round_up_p2 $write_bytes PAGE_SIZE)
8044         # round to grant consumption unit
8045         local wb_round_up=$(round_up_p2 $write_bytes gbs)
8046
8047         local grants=$((wb_round_up + extent_tax))
8048
8049         $LFS setstripe -c 1 -i 0 $DIR/$tfile  || error "lfs setstripe failed"
8050
8051         # define OBD_FAIL_TGT_NO_GRANT 0x725
8052         # make the server not grant more back
8053         do_facet ost1 $LCTL set_param fail_loc=0x725
8054         dd if=/dev/zero of=$DIR/$tfile bs=$write_bytes count=1 oflag=direct
8055
8056         do_facet ost1 $LCTL set_param fail_loc=0
8057
8058         check_grants $osc_tgt $((init_grants - grants)) "dio w/o grant alloc"
8059
8060         rm -f $DIR/$tfile || error "rm failed"
8061
8062         # Remount client to reset grant
8063         remount_client $MOUNT || error "failed to remount client"
8064         osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
8065
8066         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "lfs setstripe failed"
8067
8068         # define OBD_FAIL_TGT_NO_GRANT 0x725
8069         # make the server not grant more back
8070         do_facet ost1 $LCTL set_param fail_loc=0x725
8071         $MULTIOP $DIR/$tfile "oO_WRONLY:w${write_bytes}yc"
8072         do_facet ost1 $LCTL set_param fail_loc=0
8073
8074         check_grants $osc_tgt $((init_grants - grants)) "buf io w/o grant alloc"
8075 }
8076 run_test 64e "check grant consumption (no grant allocation)"
8077
8078 test_64f() {
8079         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8080
8081         # Remount client to reset grant
8082         remount_client $MOUNT || error "failed to remount client"
8083         local osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
8084
8085         local init_grants=$(import_param $osc_tgt initial_grant)
8086         local extent_tax=$(import_param $osc_tgt grant_extent_tax)
8087         local max_brw_size=$(import_param $osc_tgt max_brw_size)
8088         local gbs=$(import_param $osc_tgt grant_block_size)
8089         local chunk=$(grant_chunk $osc_tgt)
8090
8091         # write random number of bytes from max_brw_size / 4 to max_brw_size
8092         local write_bytes=$(shuf -i $((max_brw_size / 4))-$max_brw_size -n 1)
8093         # align for direct io
8094         write_bytes=$(round_up_p2 $write_bytes PAGE_SIZE)
8095         # round to grant consumption unit
8096         local wb_round_up=$(round_up_p2 $write_bytes gbs)
8097
8098         local grants=$((wb_round_up + extent_tax))
8099
8100         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "lfs setstripe failed"
8101         dd if=/dev/zero of=$DIR/$tfile bs=$write_bytes count=1 oflag=direct ||
8102                 error "error writing to $DIR/$tfile"
8103
8104         check_grants $osc_tgt $((init_grants - grants + chunk)) \
8105                 "direct io with grant allocation"
8106
8107         rm -f $DIR/$tfile || error "rm failed"
8108
8109         # Remount client to reset grant
8110         remount_client $MOUNT || error "failed to remount client"
8111         osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
8112
8113         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "lfs setstripe failed"
8114
8115         local cmd="oO_WRONLY:w${write_bytes}_yc"
8116
8117         $MULTIOP $DIR/$tfile $cmd &
8118         MULTIPID=$!
8119         sleep 1
8120
8121         check_grants $osc_tgt $((init_grants - grants)) \
8122                 "buffered io, not write rpc"
8123
8124         kill -USR1 $MULTIPID
8125         wait
8126
8127         check_grants $osc_tgt $((init_grants - grants + chunk)) \
8128                 "buffered io, one RPC"
8129 }
8130 run_test 64f "check grant consumption (with grant allocation)"
8131
8132 # bug 1414 - set/get directories' stripe info
8133 test_65a() {
8134         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8135
8136         test_mkdir $DIR/$tdir
8137         touch $DIR/$tdir/f1
8138         $LVERIFY $DIR/$tdir $DIR/$tdir/f1 || error "lverify failed"
8139 }
8140 run_test 65a "directory with no stripe info"
8141
8142 test_65b() {
8143         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8144
8145         test_mkdir $DIR/$tdir
8146         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
8147
8148         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
8149                                                 error "setstripe"
8150         touch $DIR/$tdir/f2
8151         $LVERIFY $DIR/$tdir $DIR/$tdir/f2 || error "lverify failed"
8152 }
8153 run_test 65b "directory setstripe -S stripe_size*2 -i 0 -c 1"
8154
8155 test_65c() {
8156         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8157         [ $OSTCOUNT -lt 2 ] && skip_env "need at least 2 OSTs"
8158
8159         test_mkdir $DIR/$tdir
8160         local stripesize=$($LFS getstripe -S $DIR/$tdir)
8161
8162         $LFS setstripe -S $((stripesize * 4)) -i 1 \
8163                 -c $((OSTCOUNT - 1)) $DIR/$tdir || error "setstripe"
8164         touch $DIR/$tdir/f3
8165         $LVERIFY $DIR/$tdir $DIR/$tdir/f3 || error "lverify failed"
8166 }
8167 run_test 65c "directory setstripe -S stripe_size*4 -i 1 -c $((OSTCOUNT-1))"
8168
8169 test_65d() {
8170         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8171
8172         test_mkdir $DIR/$tdir
8173         local STRIPECOUNT=$($LFS getstripe -c $DIR/$tdir)
8174         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
8175
8176         if [[ $STRIPECOUNT -le 0 ]]; then
8177                 sc=1
8178         elif [[ $STRIPECOUNT -gt $LOV_MAX_STRIPE_COUNT ]]; then
8179                 [[ $OSTCOUNT -gt $LOV_MAX_STRIPE_COUNT ]] &&
8180                         sc=$LOV_MAX_STRIPE_COUNT || sc=$(($OSTCOUNT - 1))
8181         else
8182                 sc=$(($STRIPECOUNT - 1))
8183         fi
8184         $LFS setstripe -S $STRIPESIZE -c $sc $DIR/$tdir || error "setstripe"
8185         touch $DIR/$tdir/f4 $DIR/$tdir/f5
8186         $LVERIFY $DIR/$tdir $DIR/$tdir/f4 $DIR/$tdir/f5 ||
8187                 error "lverify failed"
8188 }
8189 run_test 65d "directory setstripe -S stripe_size -c stripe_count"
8190
8191 test_65e() {
8192         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8193
8194         test_mkdir $DIR/$tdir
8195
8196         $LFS setstripe $DIR/$tdir || error "setstripe"
8197         $LFS getstripe -v $DIR/$tdir | grep "Default" ||
8198                                         error "no stripe info failed"
8199         touch $DIR/$tdir/f6
8200         $LVERIFY $DIR/$tdir $DIR/$tdir/f6 || error "lverify failed"
8201 }
8202 run_test 65e "directory setstripe defaults"
8203
8204 test_65f() {
8205         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8206
8207         test_mkdir $DIR/${tdir}f
8208         $RUNAS $LFS setstripe $DIR/${tdir}f &&
8209                 error "setstripe succeeded" || true
8210 }
8211 run_test 65f "dir setstripe permission (should return error) ==="
8212
8213 test_65g() {
8214         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8215
8216         test_mkdir $DIR/$tdir
8217         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
8218
8219         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
8220                 error "setstripe -S failed"
8221         $LFS setstripe -d $DIR/$tdir || error "setstripe -d failed"
8222         $LFS getstripe -v $DIR/$tdir | grep "Default" ||
8223                 error "delete default stripe failed"
8224 }
8225 run_test 65g "directory setstripe -d"
8226
8227 test_65h() {
8228         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8229
8230         test_mkdir $DIR/$tdir
8231         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
8232
8233         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
8234                 error "setstripe -S failed"
8235         test_mkdir $DIR/$tdir/dd1
8236         [ $($LFS getstripe -c $DIR/$tdir) = $($LFS getstripe -c $DIR/$tdir/dd1) ] ||
8237                 error "stripe info inherit failed"
8238 }
8239 run_test 65h "directory stripe info inherit ===================="
8240
8241 test_65i() {
8242         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8243
8244         save_layout_restore_at_exit $MOUNT
8245
8246         # bug6367: set non-default striping on root directory
8247         $LFS setstripe -S 65536 -c -1 $MOUNT || error "error setting stripe"
8248
8249         # bug12836: getstripe on -1 default directory striping
8250         $LFS getstripe $MOUNT || error "getstripe $MOUNT failed"
8251
8252         # bug12836: getstripe -v on -1 default directory striping
8253         $LFS getstripe -v $MOUNT || error "getstripe -v $MOUNT failed"
8254
8255         # bug12836: new find on -1 default directory striping
8256         $LFS find -mtime -1 $MOUNT > /dev/null || error "find $MOUNT failed"
8257 }
8258 run_test 65i "various tests to set root directory striping"
8259
8260 test_65j() { # bug6367
8261         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8262
8263         sync; sleep 1
8264
8265         # if we aren't already remounting for each test, do so for this test
8266         if [ "$I_MOUNTED" = "yes" ]; then
8267                 cleanup || error "failed to unmount"
8268                 setup
8269         fi
8270
8271         save_layout_restore_at_exit $MOUNT
8272
8273         $LFS setstripe -d $MOUNT || error "setstripe failed"
8274 }
8275 run_test 65j "set default striping on root directory (bug 6367)="
8276
8277 cleanup_65k() {
8278         rm -rf $DIR/$tdir
8279         wait_delete_completed
8280         do_facet $SINGLEMDS "lctl set_param -n \
8281                 osp.$ost*MDT0000.max_create_count=$max_count"
8282         do_facet $SINGLEMDS "lctl set_param -n \
8283                 osp.$ost*MDT0000.create_count=$count"
8284         do_facet $SINGLEMDS lctl --device  %$INACTIVE_OSC activate
8285         echo $INACTIVE_OSC "is Activate"
8286
8287         wait_osc_import_state mds ost$(( ostnum + 1 )) FULL
8288 }
8289
8290 test_65k() { # bug11679
8291         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8292         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
8293         remote_mds_nodsh && skip "remote MDS with nodsh"
8294
8295         local disable_precreate=true
8296         [ $MDS1_VERSION -le $(version_code 2.8.54) ] &&
8297                 disable_precreate=false
8298
8299         echo "Check OST status: "
8300         local MDS_OSCS=$(do_facet $SINGLEMDS lctl dl |
8301                 awk '/[oO][sS][cC].*md[ts]/ { print $4 }')
8302
8303         for OSC in $MDS_OSCS; do
8304                 echo $OSC "is active"
8305                 do_facet $SINGLEMDS lctl --device %$OSC activate
8306         done
8307
8308         for INACTIVE_OSC in $MDS_OSCS; do
8309                 local ost=$(osc_to_ost $INACTIVE_OSC)
8310                 local ostnum=$(do_facet $SINGLEMDS lctl get_param -n \
8311                                lov.*md*.target_obd |
8312                                awk -F: /$ost/'{ print $1 }' | head -n 1)
8313
8314                 mkdir -p $DIR/$tdir
8315                 $LFS setstripe -i $ostnum -c 1 $DIR/$tdir
8316                 createmany -o $DIR/$tdir/$tfile.$ostnum. 1000
8317
8318                 echo "Deactivate: " $INACTIVE_OSC
8319                 do_facet $SINGLEMDS lctl --device %$INACTIVE_OSC deactivate
8320
8321                 local count=$(do_facet $SINGLEMDS "lctl get_param -n \
8322                               osp.$ost*MDT0000.create_count")
8323                 local max_count=$(do_facet $SINGLEMDS "lctl get_param -n \
8324                                   osp.$ost*MDT0000.max_create_count")
8325                 $disable_precreate &&
8326                         do_facet $SINGLEMDS "lctl set_param -n \
8327                                 osp.$ost*MDT0000.max_create_count=0"
8328
8329                 for idx in $(seq 0 $((OSTCOUNT - 1))); do
8330                         [ -f $DIR/$tdir/$idx ] && continue
8331                         echo "$LFS setstripe -i $idx -c 1 $DIR/$tdir/$idx"
8332                         $LFS setstripe -i $idx -c 1 $DIR/$tdir/$idx ||
8333                                 { cleanup_65k;
8334                                   error "setstripe $idx should succeed"; }
8335                         rm -f $DIR/$tdir/$idx || error "rm $idx failed"
8336                 done
8337                 unlinkmany $DIR/$tdir/$tfile.$ostnum. 1000
8338                 rmdir $DIR/$tdir
8339
8340                 do_facet $SINGLEMDS "lctl set_param -n \
8341                         osp.$ost*MDT0000.max_create_count=$max_count"
8342                 do_facet $SINGLEMDS "lctl set_param -n \
8343                         osp.$ost*MDT0000.create_count=$count"
8344                 do_facet $SINGLEMDS lctl --device  %$INACTIVE_OSC activate
8345                 echo $INACTIVE_OSC "is Activate"
8346
8347                 wait_osc_import_state mds ost$(( ostnum + 1 )) FULL
8348         done
8349 }
8350 run_test 65k "validate manual striping works properly with deactivated OSCs"
8351
8352 test_65l() { # bug 12836
8353         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8354
8355         test_mkdir -p $DIR/$tdir/test_dir
8356         $LFS setstripe -c -1 $DIR/$tdir/test_dir
8357         $LFS find -mtime -1 $DIR/$tdir >/dev/null
8358 }
8359 run_test 65l "lfs find on -1 stripe dir ========================"
8360
8361 test_65m() {
8362         local layout=$(save_layout $MOUNT)
8363         $RUNAS $LFS setstripe -c 2 $MOUNT && {
8364                 restore_layout $MOUNT $layout
8365                 error "setstripe should fail by non-root users"
8366         }
8367         true
8368 }
8369 run_test 65m "normal user can't set filesystem default stripe"
8370
8371 test_65n() {
8372         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
8373         [[ $MDS1_VERSION -ge $(version_code 2.12.50) ]] ||
8374                 skip "Need MDS version at least 2.12.50"
8375         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
8376
8377         [[ $OSTCOUNT -ge 2 ]] || skip_env "needs >= 2 OSTs"
8378         which getfattr > /dev/null 2>&1 || skip_env "no getfattr command"
8379         which setfattr > /dev/null 2>&1 || skip_env "no setfattr command"
8380
8381         local root_layout=$(save_layout $MOUNT)
8382         stack_trap "restore_layout $MOUNT $root_layout" EXIT
8383
8384         # new subdirectory under root directory should not inherit
8385         # the default layout from root
8386         local dir1=$MOUNT/$tdir-1
8387         mkdir $dir1 || error "mkdir $dir1 failed"
8388         ! getfattr -n trusted.lov $dir1 &> /dev/null ||
8389                 error "$dir1 shouldn't have LOV EA"
8390
8391         # delete the default layout on root directory
8392         $LFS setstripe -d $MOUNT || error "delete root default layout failed"
8393
8394         local dir2=$MOUNT/$tdir-2
8395         mkdir $dir2 || error "mkdir $dir2 failed"
8396         ! getfattr -n trusted.lov $dir2 &> /dev/null ||
8397                 error "$dir2 shouldn't have LOV EA"
8398
8399         # set a new striping pattern on root directory
8400         local def_stripe_size=$($LFS getstripe -S $MOUNT)
8401         local new_def_stripe_size=$((def_stripe_size * 2))
8402         $LFS setstripe -S $new_def_stripe_size $MOUNT ||
8403                 error "set stripe size on $MOUNT failed"
8404
8405         # new file created in $dir2 should inherit the new stripe size from
8406         # the filesystem default
8407         local file2=$dir2/$tfile-2
8408         touch $file2 || error "touch $file2 failed"
8409
8410         local file2_stripe_size=$($LFS getstripe -S $file2)
8411         [[ $file2_stripe_size -eq $new_def_stripe_size ]] ||
8412         {
8413                 echo "file2_stripe_size: '$file2_stripe_size'"
8414                 echo "new_def_stripe_size: '$new_def_stripe_size'"
8415                 error "$file2 didn't inherit stripe size $new_def_stripe_size"
8416         }
8417
8418         local dir3=$MOUNT/$tdir-3
8419         mkdir $dir3 || error "mkdir $dir3 failed"
8420         # $dir3 shouldn't have LOV EA, but "lfs getstripe -d $dir3" should show
8421         # the root layout, which is the actual default layout that will be used
8422         # when new files are created in $dir3.
8423         local dir3_layout=$(get_layout_param $dir3)
8424         local root_dir_layout=$(get_layout_param $MOUNT)
8425         [[ "$dir3_layout" = "$root_dir_layout" ]] ||
8426         {
8427                 echo "dir3_layout: '$dir3_layout'"
8428                 echo "root_dir_layout: '$root_dir_layout'"
8429                 error "$dir3 should show the default layout from $MOUNT"
8430         }
8431
8432         # set OST pool on root directory
8433         local pool=$TESTNAME
8434         pool_add $pool || error "add $pool failed"
8435         pool_add_targets $pool 0 $((OSTCOUNT - 1)) 1 ||
8436                 error "add targets to $pool failed"
8437
8438         $LFS setstripe -p $pool $MOUNT ||
8439                 error "set OST pool on $MOUNT failed"
8440
8441         # new file created in $dir3 should inherit the pool from
8442         # the filesystem default
8443         local file3=$dir3/$tfile-3
8444         touch $file3 || error "touch $file3 failed"
8445
8446         local file3_pool=$($LFS getstripe -p $file3)
8447         [[ "$file3_pool" = "$pool" ]] ||
8448                 error "$file3 ('$file3_pool') didn't inherit OST pool '$pool'"
8449
8450         local dir4=$MOUNT/$tdir-4
8451         mkdir $dir4 || error "mkdir $dir4 failed"
8452         local dir4_layout=$(get_layout_param $dir4)
8453         root_dir_layout=$(get_layout_param $MOUNT)
8454         echo "$LFS getstripe -d $dir4"
8455         $LFS getstripe -d $dir4
8456         echo "$LFS getstripe -d $MOUNT"
8457         $LFS getstripe -d $MOUNT
8458         [[ "$dir4_layout" = "$root_dir_layout" ]] ||
8459         {
8460                 echo "dir4_layout: '$dir4_layout'"
8461                 echo "root_dir_layout: '$root_dir_layout'"
8462                 error "$dir4 should show the default layout from $MOUNT"
8463         }
8464
8465         # new file created in $dir4 should inherit the pool from
8466         # the filesystem default
8467         local file4=$dir4/$tfile-4
8468         touch $file4 || error "touch $file4 failed"
8469
8470         local file4_pool=$($LFS getstripe -p $file4)
8471         [[ "$file4_pool" = "$pool" ]] ||
8472                 error "$file4 ('$file4_pool') didn't inherit OST pool $pool"
8473
8474         # new subdirectory under non-root directory should inherit
8475         # the default layout from its parent directory
8476         $LFS setstripe -S $new_def_stripe_size -p $pool $dir4 ||
8477                 error "set directory layout on $dir4 failed"
8478
8479         local dir5=$dir4/$tdir-5
8480         mkdir $dir5 || error "mkdir $dir5 failed"
8481
8482         dir4_layout=$(get_layout_param $dir4)
8483         local dir5_layout=$(get_layout_param $dir5)
8484         [[ "$dir4_layout" = "$dir5_layout" ]] ||
8485         {
8486                 echo "dir4_layout: '$dir4_layout'"
8487                 echo "dir5_layout: '$dir5_layout'"
8488                 error "$dir5 should inherit the default layout from $dir4"
8489         }
8490
8491         # though subdir under ROOT doesn't inherit default layout, but
8492         # its sub dir/file should be created with default layout.
8493         [[ $MDSCOUNT -ge 2 ]] || skip_env "needs >= 2 MDTs"
8494         [[ $MDS1_VERSION -ge $(version_code 2.12.59) ]] ||
8495                 skip "Need MDS version at least 2.12.59"
8496
8497         local default_lmv_count=$($LFS getdirstripe -D -c $MOUNT)
8498         local default_lmv_index=$($LFS getdirstripe -D -i $MOUNT)
8499         local default_lmv_hash=$($LFS getdirstripe -D -H $MOUNT)
8500
8501         if [ $default_lmv_hash == "none" ]; then
8502                 stack_trap "$LFS setdirstripe -D -d $MOUNT" EXIT
8503         else
8504                 stack_trap "$LFS setdirstripe -D -i $default_lmv_index \
8505                         -c $default_lmv_count -H $default_lmv_hash $MOUNT" EXIT
8506         fi
8507
8508         $LFS setdirstripe -D -c 2 $MOUNT ||
8509                 error "setdirstripe -D -c 2 failed"
8510         mkdir $MOUNT/$tdir-6 || error "mkdir $tdir-6 failed"
8511         local lmv_count=$($LFS getdirstripe -c $MOUNT/$tdir-6)
8512         [ $lmv_count -eq 2 ] || error "$tdir-6 stripe count $lmv_count"
8513 }
8514 run_test 65n "don't inherit default layout from root for new subdirectories"
8515
8516 # bug 2543 - update blocks count on client
8517 test_66() {
8518         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8519
8520         COUNT=${COUNT:-8}
8521         dd if=/dev/zero of=$DIR/f66 bs=1k count=$COUNT
8522         sync; sync_all_data; sync; sync_all_data
8523         cancel_lru_locks osc
8524         BLOCKS=`ls -s $DIR/f66 | awk '{ print $1 }'`
8525         [ $BLOCKS -ge $COUNT ] || error "$DIR/f66 blocks $BLOCKS < $COUNT"
8526 }
8527 run_test 66 "update inode blocks count on client ==============="
8528
8529 meminfo() {
8530         awk '($1 == "'$1':") { print $2 }' /proc/meminfo
8531 }
8532
8533 swap_used() {
8534         swapon -s | awk '($1 == "'$1'") { print $4 }'
8535 }
8536
8537 # bug5265, obdfilter oa2dentry return -ENOENT
8538 # #define OBD_FAIL_SRV_ENOENT 0x217
8539 test_69() {
8540         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8541         remote_ost_nodsh && skip "remote OST with nodsh"
8542
8543         f="$DIR/$tfile"
8544         $LFS setstripe -c 1 -i 0 $f
8545
8546         $DIRECTIO write ${f}.2 0 1 || error "directio write error"
8547
8548         do_facet ost1 lctl set_param fail_loc=0x217
8549         $TRUNCATE $f 1 # vmtruncate() will ignore truncate() error.
8550         $DIRECTIO write $f 0 2 && error "write succeeded, expect -ENOENT"
8551
8552         do_facet ost1 lctl set_param fail_loc=0
8553         $DIRECTIO write $f 0 2 || error "write error"
8554
8555         cancel_lru_locks osc
8556         $DIRECTIO read $f 0 1 || error "read error"
8557
8558         do_facet ost1 lctl set_param fail_loc=0x217
8559         $DIRECTIO read $f 1 1 && error "read succeeded, expect -ENOENT"
8560
8561         do_facet ost1 lctl set_param fail_loc=0
8562         rm -f $f
8563 }
8564 run_test 69 "verify oa2dentry return -ENOENT doesn't LBUG ======"
8565
8566 test_71() {
8567         test_mkdir $DIR/$tdir
8568         $LFS setdirstripe -D -c$MDSCOUNT $DIR/$tdir
8569         sh rundbench -C -D $DIR/$tdir 2 || error "dbench failed!"
8570 }
8571 run_test 71 "Running dbench on lustre (don't segment fault) ===="
8572
8573 test_72a() { # bug 5695 - Test that on 2.6 remove_suid works properly
8574         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8575         [ "$RUNAS_ID" = "$UID" ] &&
8576                 skip_env "RUNAS_ID = UID = $UID -- skipping"
8577         # Check that testing environment is properly set up. Skip if not
8578         FAIL_ON_ERROR=false check_runas_id_ret $RUNAS_ID $RUNAS_GID $RUNAS ||
8579                 skip_env "User $RUNAS_ID does not exist - skipping"
8580
8581         touch $DIR/$tfile
8582         chmod 777 $DIR/$tfile
8583         chmod ug+s $DIR/$tfile
8584         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=512 count=1 ||
8585                 error "$RUNAS dd $DIR/$tfile failed"
8586         # See if we are still setuid/sgid
8587         [ -u $DIR/$tfile ] || [ -g $DIR/$tfile ] &&
8588                 error "S/gid is not dropped on write"
8589         # Now test that MDS is updated too
8590         cancel_lru_locks mdc
8591         [ -u $DIR/$tfile ] || [ -g $DIR/$tfile ] &&
8592                 error "S/gid is not dropped on MDS"
8593         rm -f $DIR/$tfile
8594 }
8595 run_test 72a "Test that remove suid works properly (bug5695) ===="
8596
8597 test_72b() { # bug 24226 -- keep mode setting when size is not changing
8598         local perm
8599
8600         [ "$RUNAS_ID" = "$UID" ] &&
8601                 skip_env "RUNAS_ID = UID = $UID -- skipping"
8602         [ "$RUNAS_ID" -eq 0 ] &&
8603                 skip_env "RUNAS_ID = 0 -- skipping"
8604         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8605         # Check that testing environment is properly set up. Skip if not
8606         FAIL_ON_ERROR=false check_runas_id_ret $RUNAS_ID $RUNAS_ID $RUNAS ||
8607                 skip_env "User $RUNAS_ID does not exist - skipping"
8608
8609         touch $DIR/${tfile}-f{g,u}
8610         test_mkdir $DIR/${tfile}-dg
8611         test_mkdir $DIR/${tfile}-du
8612         chmod 770 $DIR/${tfile}-{f,d}{g,u}
8613         chmod g+s $DIR/${tfile}-{f,d}g
8614         chmod u+s $DIR/${tfile}-{f,d}u
8615         for perm in 777 2777 4777; do
8616                 $RUNAS chmod $perm $DIR/${tfile}-fg && error "S/gid file allowed improper chmod to $perm"
8617                 $RUNAS chmod $perm $DIR/${tfile}-fu && error "S/uid file allowed improper chmod to $perm"
8618                 $RUNAS chmod $perm $DIR/${tfile}-dg && error "S/gid dir allowed improper chmod to $perm"
8619                 $RUNAS chmod $perm $DIR/${tfile}-du && error "S/uid dir allowed improper chmod to $perm"
8620         done
8621         true
8622 }
8623 run_test 72b "Test that we keep mode setting if without file data changed (bug 24226)"
8624
8625 # bug 3462 - multiple simultaneous MDC requests
8626 test_73() {
8627         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8628
8629         test_mkdir $DIR/d73-1
8630         test_mkdir $DIR/d73-2
8631         multiop_bg_pause $DIR/d73-1/f73-1 O_c || return 1
8632         pid1=$!
8633
8634         lctl set_param fail_loc=0x80000129
8635         $MULTIOP $DIR/d73-1/f73-2 Oc &
8636         sleep 1
8637         lctl set_param fail_loc=0
8638
8639         $MULTIOP $DIR/d73-2/f73-3 Oc &
8640         pid3=$!
8641
8642         kill -USR1 $pid1
8643         wait $pid1 || return 1
8644
8645         sleep 25
8646
8647         $CHECKSTAT -t file $DIR/d73-1/f73-1 || return 4
8648         $CHECKSTAT -t file $DIR/d73-1/f73-2 || return 5
8649         $CHECKSTAT -t file $DIR/d73-2/f73-3 || return 6
8650
8651         rm -rf $DIR/d73-*
8652 }
8653 run_test 73 "multiple MDC requests (should not deadlock)"
8654
8655 test_74a() { # bug 6149, 6184
8656         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8657
8658         touch $DIR/f74a
8659         #define OBD_FAIL_LDLM_ENQUEUE_OLD_EXPORT 0x30e
8660         #
8661         # very important to OR with OBD_FAIL_ONCE (0x80000000) -- otherwise it
8662         # will spin in a tight reconnection loop
8663         $LCTL set_param fail_loc=0x8000030e
8664         # get any lock that won't be difficult - lookup works.
8665         ls $DIR/f74a
8666         $LCTL set_param fail_loc=0
8667         rm -f $DIR/f74a
8668         true
8669 }
8670 run_test 74a "ldlm_enqueue freed-export error path, ls (shouldn't LBUG)"
8671
8672 test_74b() { # bug 13310
8673         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8674
8675         #define OBD_FAIL_LDLM_ENQUEUE_OLD_EXPORT 0x30e
8676         #
8677         # very important to OR with OBD_FAIL_ONCE (0x80000000) -- otherwise it
8678         # will spin in a tight reconnection loop
8679         $LCTL set_param fail_loc=0x8000030e
8680         # get a "difficult" lock
8681         touch $DIR/f74b
8682         $LCTL set_param fail_loc=0
8683         rm -f $DIR/f74b
8684         true
8685 }
8686 run_test 74b "ldlm_enqueue freed-export error path, touch (shouldn't LBUG)"
8687
8688 test_74c() {
8689         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8690
8691         #define OBD_FAIL_LDLM_NEW_LOCK
8692         $LCTL set_param fail_loc=0x319
8693         touch $DIR/$tfile && error "touch successful"
8694         $LCTL set_param fail_loc=0
8695         true
8696 }
8697 run_test 74c "ldlm_lock_create error path, (shouldn't LBUG)"
8698
8699 slab_lic=/sys/kernel/slab/lustre_inode_cache
8700 num_objects() {
8701         [ -f $slab_lic/shrink ] && echo 1 > $slab_lic/shrink
8702         [ -f $slab_lic/objects ] && awk '{ print $1 }' $slab_lic/objects ||
8703                 awk '/lustre_inode_cache/ { print $2; exit }' /proc/slabinfo
8704 }
8705
8706 test_76a() { # Now for b=20433, added originally in b=1443
8707         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8708
8709         cancel_lru_locks osc
8710         # there may be some slab objects cached per core
8711         local cpus=$(getconf _NPROCESSORS_ONLN 2>/dev/null)
8712         local before=$(num_objects)
8713         local count=$((512 * cpus))
8714         [ "$SLOW" = "no" ] && count=$((128 * cpus))
8715         local margin=$((count / 10))
8716         if [[ -f $slab_lic/aliases ]]; then
8717                 local aliases=$(cat $slab_lic/aliases)
8718                 (( aliases > 0 )) && margin=$((margin * aliases))
8719         fi
8720
8721         echo "before slab objects: $before"
8722         for i in $(seq $count); do
8723                 touch $DIR/$tfile
8724                 rm -f $DIR/$tfile
8725         done
8726         cancel_lru_locks osc
8727         local after=$(num_objects)
8728         echo "created: $count, after slab objects: $after"
8729         # shared slab counts are not very accurate, allow significant margin
8730         # the main goal is that the cache growth is not permanently > $count
8731         while (( after > before + margin )); do
8732                 sleep 1
8733                 after=$(num_objects)
8734                 wait=$((wait + 1))
8735                 (( wait % 5 == 0 )) && echo "wait $wait seconds objects: $after"
8736                 if (( wait > 60 )); then
8737                         error "inode slab grew from $before+$margin to $after"
8738                 fi
8739         done
8740 }
8741 run_test 76a "confirm clients recycle inodes properly ===="
8742
8743 test_76b() {
8744         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8745         [ $CLIENT_VERSION -ge $(version_code 2.13.55) ] || skip "not supported"
8746
8747         local count=512
8748         local before=$(num_objects)
8749
8750         for i in $(seq $count); do
8751                 mkdir $DIR/$tdir
8752                 rmdir $DIR/$tdir
8753         done
8754
8755         local after=$(num_objects)
8756         local wait=0
8757
8758         while (( after > before )); do
8759                 sleep 1
8760                 after=$(num_objects)
8761                 wait=$((wait + 1))
8762                 (( wait % 5 == 0 )) && echo "wait $wait seconds objects: $after"
8763                 if (( wait > 60 )); then
8764                         error "inode slab grew from $before to $after"
8765                 fi
8766         done
8767
8768         echo "slab objects before: $before, after: $after"
8769 }
8770 run_test 76b "confirm clients recycle directory inodes properly ===="
8771
8772 export ORIG_CSUM=""
8773 set_checksums()
8774 {
8775         # Note: in sptlrpc modes which enable its own bulk checksum, the
8776         # original crc32_le bulk checksum will be automatically disabled,
8777         # and the OBD_FAIL_OSC_CHECKSUM_SEND/OBD_FAIL_OSC_CHECKSUM_RECEIVE
8778         # will be checked by sptlrpc code against sptlrpc bulk checksum.
8779         # In this case set_checksums() will not be no-op, because sptlrpc
8780         # bulk checksum will be enabled all through the test.
8781
8782         [ "$ORIG_CSUM" ] || ORIG_CSUM=`lctl get_param -n osc.*.checksums | head -n1`
8783         lctl set_param -n osc.*.checksums $1
8784         return 0
8785 }
8786
8787 export ORIG_CSUM_TYPE="`lctl get_param -n osc.*osc-[^mM]*.checksum_type |
8788                         sed 's/.*\[\(.*\)\].*/\1/g' | head -n1`"
8789 CKSUM_TYPES=${CKSUM_TYPES:-$(lctl get_param -n osc.*osc-[^mM]*.checksum_type |
8790                              tr -d [] | head -n1)}
8791 set_checksum_type()
8792 {
8793         lctl set_param -n osc.*osc-[^mM]*.checksum_type $1
8794         rc=$?
8795         log "set checksum type to $1, rc = $rc"
8796         return $rc
8797 }
8798
8799 get_osc_checksum_type()
8800 {
8801         # arugment 1: OST name, like OST0000
8802         ost=$1
8803         checksum_type=$(lctl get_param -n osc.*${ost}-osc-[^mM]*.checksum_type |
8804                         sed 's/.*\[\(.*\)\].*/\1/g')
8805         rc=$?
8806         [ $rc -ne 0 ] && error "failed to get checksum type of $ost, rc = $rc, output = $checksum_type"
8807         echo $checksum_type
8808 }
8809
8810 F77_TMP=$TMP/f77-temp
8811 F77SZ=8
8812 setup_f77() {
8813         dd if=/dev/urandom of=$F77_TMP bs=1M count=$F77SZ || \
8814                 error "error writing to $F77_TMP"
8815 }
8816
8817 test_77a() { # bug 10889
8818         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8819         $GSS && skip_env "could not run with gss"
8820
8821         [ ! -f $F77_TMP ] && setup_f77
8822         set_checksums 1
8823         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ || error "dd error"
8824         set_checksums 0
8825         rm -f $DIR/$tfile
8826 }
8827 run_test 77a "normal checksum read/write operation"
8828
8829 test_77b() { # bug 10889
8830         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8831         $GSS && skip_env "could not run with gss"
8832
8833         [ ! -f $F77_TMP ] && setup_f77
8834         #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
8835         $LCTL set_param fail_loc=0x80000409
8836         set_checksums 1
8837
8838         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ conv=sync ||
8839                 error "dd error: $?"
8840         $LCTL set_param fail_loc=0
8841
8842         for algo in $CKSUM_TYPES; do
8843                 cancel_lru_locks osc
8844                 set_checksum_type $algo
8845                 #define OBD_FAIL_OSC_CHECKSUM_RECEIVE    0x408
8846                 $LCTL set_param fail_loc=0x80000408
8847                 cmp $F77_TMP $DIR/$tfile || error "file compare failed"
8848                 $LCTL set_param fail_loc=0
8849         done
8850         set_checksums 0
8851         set_checksum_type $ORIG_CSUM_TYPE
8852         rm -f $DIR/$tfile
8853 }
8854 run_test 77b "checksum error on client write, read"
8855
8856 cleanup_77c() {
8857         trap 0
8858         set_checksums 0
8859         $LCTL set_param osc.*osc-[^mM]*.checksum_dump=0
8860         $check_ost &&
8861                 do_facet ost1 $LCTL set_param obdfilter.*-OST*.checksum_dump=0
8862         [ -n "$osc_file_prefix" ] && rm -f ${osc_file_prefix}*
8863         $check_ost && [ -n "$ost_file_prefix" ] &&
8864                 do_facet ost1 rm -f ${ost_file_prefix}\*
8865 }
8866
8867 test_77c() {
8868         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8869         $GSS && skip_env "could not run with gss"
8870         remote_ost_nodsh && skip "remote OST with nodsh"
8871
8872         local bad1
8873         local osc_file_prefix
8874         local osc_file
8875         local check_ost=false
8876         local ost_file_prefix
8877         local ost_file
8878         local orig_cksum
8879         local dump_cksum
8880         local fid
8881
8882         # ensure corruption will occur on first OSS/OST
8883         $LFS setstripe -i 0 $DIR/$tfile
8884
8885         [ ! -f $F77_TMP ] && setup_f77
8886         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ conv=sync ||
8887                 error "dd write error: $?"
8888         fid=$($LFS path2fid $DIR/$tfile)
8889
8890         if [ $OST1_VERSION -ge $(version_code 2.9.57) ]
8891         then
8892                 check_ost=true
8893                 ost_file_prefix=$(do_facet ost1 $LCTL get_param -n debug_path)
8894                 ost_file_prefix=${ost_file_prefix}-checksum_dump-ost-\\${fid}
8895         else
8896                 echo "OSS do not support bulk pages dump upon error"
8897         fi
8898
8899         osc_file_prefix=$($LCTL get_param -n debug_path)
8900         osc_file_prefix=${osc_file_prefix}-checksum_dump-osc-\\${fid}
8901
8902         trap cleanup_77c EXIT
8903
8904         set_checksums 1
8905         # enable bulk pages dump upon error on Client
8906         $LCTL set_param osc.*osc-[^mM]*.checksum_dump=1
8907         # enable bulk pages dump upon error on OSS
8908         $check_ost &&
8909                 do_facet ost1 $LCTL set_param obdfilter.*-OST*.checksum_dump=1
8910
8911         # flush Client cache to allow next read to reach OSS
8912         cancel_lru_locks osc
8913
8914         #define OBD_FAIL_OSC_CHECKSUM_RECEIVE       0x408
8915         $LCTL set_param fail_loc=0x80000408
8916         dd if=$DIR/$tfile of=/dev/null bs=1M || error "dd read error: $?"
8917         $LCTL set_param fail_loc=0
8918
8919         rm -f $DIR/$tfile
8920
8921         # check cksum dump on Client
8922         osc_file=$(ls ${osc_file_prefix}*)
8923         [ -n "$osc_file" ] || error "no checksum dump file on Client"
8924         # OBD_FAIL_OSC_CHECKSUM_RECEIVE corrupts with "bad1" at start of file
8925         bad1=$(dd if=$osc_file bs=1 count=4 2>/dev/null) || error "dd error: $?"
8926         [ $bad1 == "bad1" ] || error "unexpected corrupt pattern"
8927         orig_cksum=$(dd if=$F77_TMP bs=1 skip=4 count=1048572 2>/dev/null |
8928                      cksum)
8929         dump_cksum=$(dd if=$osc_file bs=1 skip=4 2>/dev/null | cksum)
8930         [[ "$orig_cksum" == "$dump_cksum" ]] ||
8931                 error "dump content does not match on Client"
8932
8933         $check_ost || skip "No need to check cksum dump on OSS"
8934
8935         # check cksum dump on OSS
8936         ost_file=$(do_facet ost1 ls ${ost_file_prefix}\*)
8937         [ -n "$ost_file" ] || error "no checksum dump file on OSS"
8938         orig_cksum=$(dd if=$F77_TMP bs=1048576 count=1 2>/dev/null | cksum)
8939         dump_cksum=$(do_facet ost1 dd if=$ost_file 2>/dev/null \| cksum)
8940         [[ "$orig_cksum" == "$dump_cksum" ]] ||
8941                 error "dump content does not match on OSS"
8942
8943         cleanup_77c
8944 }
8945 run_test 77c "checksum error on client read with debug"
8946
8947 test_77d() { # bug 10889
8948         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8949         $GSS && skip_env "could not run with gss"
8950
8951         #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
8952         $LCTL set_param fail_loc=0x80000409
8953         set_checksums 1
8954         $DIRECTIO write $DIR/$tfile 0 $F77SZ $((1024 * 1024)) ||
8955                 error "direct write: rc=$?"
8956         $LCTL set_param fail_loc=0
8957         set_checksums 0
8958
8959         #define OBD_FAIL_OSC_CHECKSUM_RECEIVE    0x408
8960         $LCTL set_param fail_loc=0x80000408
8961         set_checksums 1
8962         cancel_lru_locks osc
8963         $DIRECTIO read $DIR/$tfile 0 $F77SZ $((1024 * 1024)) ||
8964                 error "direct read: rc=$?"
8965         $LCTL set_param fail_loc=0
8966         set_checksums 0
8967 }
8968 run_test 77d "checksum error on OST direct write, read"
8969
8970 test_77f() { # bug 10889
8971         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8972         $GSS && skip_env "could not run with gss"
8973
8974         set_checksums 1
8975         for algo in $CKSUM_TYPES; do
8976                 cancel_lru_locks osc
8977                 set_checksum_type $algo
8978                 #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
8979                 $LCTL set_param fail_loc=0x409
8980                 $DIRECTIO write $DIR/$tfile 0 $F77SZ $((1024 * 1024)) &&
8981                         error "direct write succeeded"
8982                 $LCTL set_param fail_loc=0
8983         done
8984         set_checksum_type $ORIG_CSUM_TYPE
8985         set_checksums 0
8986 }
8987 run_test 77f "repeat checksum error on write (expect error)"
8988
8989 test_77g() { # bug 10889
8990         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8991         $GSS && skip_env "could not run with gss"
8992         remote_ost_nodsh && skip "remote OST with nodsh"
8993
8994         [ ! -f $F77_TMP ] && setup_f77
8995
8996         local file=$DIR/$tfile
8997         stack_trap "rm -f $file" EXIT
8998
8999         $LFS setstripe -c 1 -i 0 $file
9000         #define OBD_FAIL_OST_CHECKSUM_RECEIVE       0x21a
9001         do_facet ost1 lctl set_param fail_loc=0x8000021a
9002         set_checksums 1
9003         dd if=$F77_TMP of=$file bs=1M count=$F77SZ ||
9004                 error "write error: rc=$?"
9005         do_facet ost1 lctl set_param fail_loc=0
9006         set_checksums 0
9007
9008         cancel_lru_locks osc
9009         #define OBD_FAIL_OST_CHECKSUM_SEND          0x21b
9010         do_facet ost1 lctl set_param fail_loc=0x8000021b
9011         set_checksums 1
9012         cmp $F77_TMP $file || error "file compare failed"
9013         do_facet ost1 lctl set_param fail_loc=0
9014         set_checksums 0
9015 }
9016 run_test 77g "checksum error on OST write, read"
9017
9018 test_77k() { # LU-10906
9019         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9020         $GSS && skip_env "could not run with gss"
9021
9022         local cksum_param="osc.$FSNAME*.checksums"
9023         local get_checksum="$LCTL get_param -n $cksum_param | head -n1"
9024         local checksum
9025         local i
9026
9027         [ "$ORIG_CSUM" ] || ORIG_CSUM=$(eval $get_checksum)
9028         stack_trap "wait_update $HOSTNAME '$get_checksum' $ORIG_CSUM || true"
9029         stack_trap "do_facet mgs $LCTL set_param -P $cksum_param=$ORIG_CSUM"
9030
9031         for i in 0 1; do
9032                 do_facet mgs $LCTL set_param -P $cksum_param=$i ||
9033                         error "failed to set checksum=$i on MGS"
9034                 wait_update $HOSTNAME "$get_checksum" $i
9035                 #remount
9036                 echo "remount client, checksum should be $i"
9037                 remount_client $MOUNT || error "failed to remount client"
9038                 checksum=$(eval $get_checksum)
9039                 [ $checksum -eq $i ] || error "checksum($checksum) != $i"
9040         done
9041         # remove persistent param to avoid races with checksum mountopt below
9042         do_facet mgs $LCTL set_param -P -d $cksum_param ||
9043                 error "failed to delete checksum on MGS"
9044
9045         for opt in "checksum" "nochecksum"; do
9046                 #remount with mount option
9047                 echo "remount client with option $opt, checksum should be $i"
9048                 umount_client $MOUNT || error "failed to umount client"
9049                 mount_client $MOUNT "$MOUNT_OPTS,$opt" ||
9050                         error "failed to mount client with option '$opt'"
9051                 checksum=$(eval $get_checksum)
9052                 [ $checksum -eq $i ] || error "checksum($checksum) != $i"
9053                 i=$((i - 1))
9054         done
9055
9056         remount_client $MOUNT || error "failed to remount client"
9057 }
9058 run_test 77k "enable/disable checksum correctly"
9059
9060 test_77l() {
9061         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9062         $GSS && skip_env "could not run with gss"
9063
9064         set_checksums 1
9065         stack_trap "set_checksums $ORIG_CSUM" EXIT
9066         stack_trap "set_checksum_type $ORIG_CSUM_TYPE" EXIT
9067
9068         set_checksum_type invalid && error "unexpected success of invalid checksum type"
9069
9070         $LFS setstripe -c 1 -i 0 $DIR/$tfile
9071         for algo in $CKSUM_TYPES; do
9072                 set_checksum_type $algo || error "fail to set checksum type $algo"
9073                 osc_algo=$(get_osc_checksum_type OST0000)
9074                 [ "$osc_algo" != "$algo" ] && error "checksum type is $osc_algo after setting it to $algo"
9075
9076                 # no locks, no reqs to let the connection idle
9077                 cancel_lru_locks osc
9078                 lru_resize_disable osc
9079                 wait_osc_import_state client ost1 IDLE
9080
9081                 # ensure ost1 is connected
9082                 stat $DIR/$tfile >/dev/null || error "can't stat"
9083                 wait_osc_import_state client ost1 FULL
9084
9085                 osc_algo=$(get_osc_checksum_type OST0000)
9086                 [ "$osc_algo" != "$algo" ] && error "checksum type changed from $algo to $osc_algo after reconnection"
9087         done
9088         return 0
9089 }
9090 run_test 77l "preferred checksum type is remembered after reconnected"
9091
9092 [ "$ORIG_CSUM" ] && set_checksums $ORIG_CSUM || true
9093 rm -f $F77_TMP
9094 unset F77_TMP
9095
9096 cleanup_test_78() {
9097         trap 0
9098         rm -f $DIR/$tfile
9099 }
9100
9101 test_78() { # bug 10901
9102         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9103         remote_ost || skip_env "local OST"
9104
9105         NSEQ=5
9106         F78SIZE=$(($(awk '/MemFree:/ { print $2 }' /proc/meminfo) / 1024))
9107         echo "MemFree: $F78SIZE, Max file size: $MAXFREE"
9108         MEMTOTAL=$(($(awk '/MemTotal:/ { print $2 }' /proc/meminfo) / 1024))
9109         echo "MemTotal: $MEMTOTAL"
9110
9111         # reserve 256MB of memory for the kernel and other running processes,
9112         # and then take 1/2 of the remaining memory for the read/write buffers.
9113         if [ $MEMTOTAL -gt 512 ] ;then
9114                 MEMTOTAL=$(((MEMTOTAL - 256 ) / 2))
9115         else
9116                 # for those poor memory-starved high-end clusters...
9117                 MEMTOTAL=$((MEMTOTAL / 2))
9118         fi
9119         echo "Mem to use for directio: $MEMTOTAL"
9120
9121         [[ $F78SIZE -gt $MEMTOTAL ]] && F78SIZE=$MEMTOTAL
9122         [[ $F78SIZE -gt 512 ]] && F78SIZE=512
9123         [[ $F78SIZE -gt $((MAXFREE / 1024)) ]] && F78SIZE=$((MAXFREE / 1024))
9124         SMALLESTOST=$($LFS df $DIR | grep OST | awk '{ print $4 }' | sort -n |
9125                 head -n1)
9126         echo "Smallest OST: $SMALLESTOST"
9127         [[ $SMALLESTOST -lt 10240 ]] &&
9128                 skip "too small OSTSIZE, useless to run large O_DIRECT test"
9129
9130         trap cleanup_test_78 EXIT
9131
9132         [[ $F78SIZE -gt $((SMALLESTOST * $OSTCOUNT / 1024 - 80)) ]] &&
9133                 F78SIZE=$((SMALLESTOST * $OSTCOUNT / 1024 - 80))
9134
9135         [ "$SLOW" = "no" ] && NSEQ=1 && [ $F78SIZE -gt 32 ] && F78SIZE=32
9136         echo "File size: $F78SIZE"
9137         $LFS setstripe -c $OSTCOUNT $DIR/$tfile || error "setstripe failed"
9138         for i in $(seq 1 $NSEQ); do
9139                 FSIZE=$(($F78SIZE / ($NSEQ - $i + 1)))
9140                 echo directIO rdwr round $i of $NSEQ
9141                 $DIRECTIO rdwr $DIR/$tfile 0 $FSIZE 1048576||error "rdwr failed"
9142         done
9143
9144         cleanup_test_78
9145 }
9146 run_test 78 "handle large O_DIRECT writes correctly ============"
9147
9148 test_79() { # bug 12743
9149         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9150
9151         wait_delete_completed
9152
9153         BKTOTAL=$(calc_osc_kbytes kbytestotal)
9154         BKFREE=$(calc_osc_kbytes kbytesfree)
9155         BKAVAIL=$(calc_osc_kbytes kbytesavail)
9156
9157         STRING=`df -P $MOUNT | tail -n 1 | awk '{print $2","$3","$4}'`
9158         DFTOTAL=`echo $STRING | cut -d, -f1`
9159         DFUSED=`echo $STRING  | cut -d, -f2`
9160         DFAVAIL=`echo $STRING | cut -d, -f3`
9161         DFFREE=$(($DFTOTAL - $DFUSED))
9162
9163         ALLOWANCE=$((64 * $OSTCOUNT))
9164
9165         if [ $DFTOTAL -lt $(($BKTOTAL - $ALLOWANCE)) ] ||
9166            [ $DFTOTAL -gt $(($BKTOTAL + $ALLOWANCE)) ] ; then
9167                 error "df total($DFTOTAL) mismatch OST total($BKTOTAL)"
9168         fi
9169         if [ $DFFREE -lt $(($BKFREE - $ALLOWANCE)) ] ||
9170            [ $DFFREE -gt $(($BKFREE + $ALLOWANCE)) ] ; then
9171                 error "df free($DFFREE) mismatch OST free($BKFREE)"
9172         fi
9173         if [ $DFAVAIL -lt $(($BKAVAIL - $ALLOWANCE)) ] ||
9174            [ $DFAVAIL -gt $(($BKAVAIL + $ALLOWANCE)) ] ; then
9175                 error "df avail($DFAVAIL) mismatch OST avail($BKAVAIL)"
9176         fi
9177 }
9178 run_test 79 "df report consistency check ======================="
9179
9180 test_80() { # bug 10718
9181         remote_ost_nodsh && skip "remote OST with nodsh"
9182         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9183
9184         # relax strong synchronous semantics for slow backends like ZFS
9185         if [ "$ost1_FSTYPE" != "ldiskfs" ]; then
9186                 local soc="obdfilter.*.sync_lock_cancel"
9187                 local save=$(do_facet ost1 $LCTL get_param -n $soc | head -n1)
9188
9189                 # "sync_on_lock_cancel" was broken by v2_11_55_0-26-g7059644e9a
9190                 if [ -z "$save" ]; then
9191                         soc="obdfilter.*.sync_on_lock_cancel"
9192                         save=$(do_facet ost1 $LCTL get_param -n $soc | head -n1)
9193                 fi
9194
9195                 if [ "$save" != "never" ]; then
9196                         local hosts=$(comma_list $(osts_nodes))
9197
9198                         do_nodes $hosts $LCTL set_param $soc=never
9199                         stack_trap "do_nodes $hosts $LCTL set_param $soc=$save"
9200                 fi
9201         fi
9202
9203         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=1M
9204         sync; sleep 1; sync
9205         local before=$(date +%s)
9206         cancel_lru_locks osc
9207         local after=$(date +%s)
9208         local diff=$((after - before))
9209         [ $diff -le 1 ] || error "elapsed for 1M@1T = $diff"
9210
9211         rm -f $DIR/$tfile
9212 }
9213 run_test 80 "Page eviction is equally fast at high offsets too"
9214
9215 test_81a() { # LU-456
9216         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9217         remote_ost_nodsh && skip "remote OST with nodsh"
9218
9219         # define OBD_FAIL_OST_MAPBLK_ENOSPC    0x228
9220         # MUST OR with the OBD_FAIL_ONCE (0x80000000)
9221         do_facet ost1 lctl set_param fail_loc=0x80000228
9222
9223         # write should trigger a retry and success
9224         $LFS setstripe -i 0 -c 1 $DIR/$tfile
9225         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
9226         RC=$?
9227         if [ $RC -ne 0 ] ; then
9228                 error "write should success, but failed for $RC"
9229         fi
9230 }
9231 run_test 81a "OST should retry write when get -ENOSPC ==============="
9232
9233 test_81b() { # LU-456
9234         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9235         remote_ost_nodsh && skip "remote OST with nodsh"
9236
9237         # define OBD_FAIL_OST_MAPBLK_ENOSPC    0x228
9238         # Don't OR with the OBD_FAIL_ONCE (0x80000000)
9239         do_facet ost1 lctl set_param fail_loc=0x228
9240
9241         # write should retry several times and return -ENOSPC finally
9242         $LFS setstripe -i 0 -c 1 $DIR/$tfile
9243         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
9244         RC=$?
9245         ENOSPC=28
9246         if [ $RC -ne $ENOSPC ] ; then
9247                 error "dd should fail for -ENOSPC, but succeed."
9248         fi
9249 }
9250 run_test 81b "OST should return -ENOSPC when retry still fails ======="
9251
9252 test_99() {
9253         [ -z "$(which cvs 2>/dev/null)" ] && skip_env "could not find cvs"
9254
9255         test_mkdir $DIR/$tdir.cvsroot
9256         chown $RUNAS_ID $DIR/$tdir.cvsroot
9257
9258         cd $TMP
9259         $RUNAS cvs -d $DIR/$tdir.cvsroot init || error "cvs init failed"
9260
9261         cd /etc/init.d
9262         # some versions of cvs import exit(1) when asked to import links or
9263         # files they can't read.  ignore those files.
9264         local toignore=$(find . -type l -printf '-I %f\n' -o \
9265                          ! -perm /4 -printf '-I %f\n')
9266         $RUNAS cvs -d $DIR/$tdir.cvsroot import -m "nomesg" $toignore \
9267                 $tdir.reposname vtag rtag
9268
9269         cd $DIR
9270         test_mkdir $DIR/$tdir.reposname
9271         chown $RUNAS_ID $DIR/$tdir.reposname
9272         $RUNAS cvs -d $DIR/$tdir.cvsroot co $tdir.reposname
9273
9274         cd $DIR/$tdir.reposname
9275         $RUNAS touch foo99
9276         $RUNAS cvs add -m 'addmsg' foo99
9277         $RUNAS cvs update
9278         $RUNAS cvs commit -m 'nomsg' foo99
9279         rm -fr $DIR/$tdir.cvsroot
9280 }
9281 run_test 99 "cvs strange file/directory operations"
9282
9283 test_100() {
9284         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9285         [[ "$NETTYPE" =~ tcp ]] ||
9286                 skip_env "TCP secure port test, not useful for NETTYPE=$NETTYPE"
9287         remote_ost_nodsh && skip "remote OST with nodsh"
9288         remote_mds_nodsh && skip "remote MDS with nodsh"
9289         remote_servers ||
9290                 skip "useless for local single node setup"
9291
9292         netstat -tna | ( rc=1; while read PROT SND RCV LOCAL REMOTE STAT; do
9293                 [ "$PROT" != "tcp" ] && continue
9294                 RPORT=$(echo $REMOTE | cut -d: -f2)
9295                 [ "$RPORT" != "$ACCEPTOR_PORT" ] && continue
9296
9297                 rc=0
9298                 LPORT=`echo $LOCAL | cut -d: -f2`
9299                 if [ $LPORT -ge 1024 ]; then
9300                         echo "bad: $PROT $SND $RCV $LOCAL $REMOTE $STAT"
9301                         netstat -tna
9302                         error_exit "local: $LPORT > 1024, remote: $RPORT"
9303                 fi
9304         done
9305         [ "$rc" = 0 ] || error_exit "privileged port not found" )
9306 }
9307 run_test 100 "check local port using privileged port ==========="
9308
9309 function get_named_value()
9310 {
9311     local tag
9312
9313     tag=$1
9314     while read ;do
9315         line=$REPLY
9316         case $line in
9317         $tag*)
9318             echo $line | sed "s/^$tag[ ]*//"
9319             break
9320             ;;
9321         esac
9322     done
9323 }
9324
9325 export CACHE_MAX=$($LCTL get_param -n llite.*.max_cached_mb |
9326                    awk '/^max_cached_mb/ { print $2 }')
9327
9328 cleanup_101a() {
9329         $LCTL set_param -n llite.*.max_cached_mb $CACHE_MAX
9330         trap 0
9331 }
9332
9333 test_101a() {
9334         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9335
9336         local s
9337         local discard
9338         local nreads=10000
9339         local cache_limit=32
9340
9341         $LCTL set_param -n osc.*-osc*.rpc_stats 0
9342         trap cleanup_101a EXIT
9343         $LCTL set_param -n llite.*.read_ahead_stats 0
9344         $LCTL set_param -n llite.*.max_cached_mb $cache_limit
9345
9346         #
9347         # randomly read 10000 of 64K chunks from file 3x 32MB in size
9348         #
9349         echo "nreads: $nreads file size: $((cache_limit * 3))MB"
9350         $READS -f $DIR/$tfile -s$((cache_limit * 3192 * 1024)) -b65536 -C -n$nreads -t 180
9351
9352         discard=0
9353         for s in $($LCTL get_param -n llite.*.read_ahead_stats |
9354                 get_named_value 'read but discarded' | cut -d" " -f1); do
9355                         discard=$(($discard + $s))
9356         done
9357         cleanup_101a
9358
9359         $LCTL get_param osc.*-osc*.rpc_stats
9360         $LCTL get_param llite.*.read_ahead_stats
9361
9362         # Discard is generally zero, but sometimes a few random reads line up
9363         # and trigger larger readahead, which is wasted & leads to discards.
9364         if [[ $(($discard)) -gt $nreads ]]; then
9365                 error "too many ($discard) discarded pages"
9366         fi
9367         rm -f $DIR/$tfile || true
9368 }
9369 run_test 101a "check read-ahead for random reads"
9370
9371 setup_test101bc() {
9372         test_mkdir $DIR/$tdir
9373         local ssize=$1
9374         local FILE_LENGTH=$2
9375         STRIPE_OFFSET=0
9376
9377         local FILE_SIZE_MB=$((FILE_LENGTH / ssize))
9378
9379         local list=$(comma_list $(osts_nodes))
9380         set_osd_param $list '' read_cache_enable 0
9381         set_osd_param $list '' writethrough_cache_enable 0
9382
9383         trap cleanup_test101bc EXIT
9384         # prepare the read-ahead file
9385         $LFS setstripe -S $ssize -i $STRIPE_OFFSET -c $OSTCOUNT $DIR/$tfile
9386
9387         dd if=/dev/zero of=$DIR/$tfile bs=$ssize \
9388                                 count=$FILE_SIZE_MB 2> /dev/null
9389
9390 }
9391
9392 cleanup_test101bc() {
9393         trap 0
9394         rm -rf $DIR/$tdir
9395         rm -f $DIR/$tfile
9396
9397         local list=$(comma_list $(osts_nodes))
9398         set_osd_param $list '' read_cache_enable 1
9399         set_osd_param $list '' writethrough_cache_enable 1
9400 }
9401
9402 calc_total() {
9403         awk 'BEGIN{total=0}; {total+=$1}; END{print total}'
9404 }
9405
9406 ra_check_101() {
9407         local READ_SIZE=$1
9408         local STRIPE_SIZE=$2
9409         local FILE_LENGTH=$3
9410         local RA_INC=1048576
9411         local STRIDE_LENGTH=$((STRIPE_SIZE/READ_SIZE))
9412         local discard_limit=$((((STRIDE_LENGTH - 1)*3/(STRIDE_LENGTH*OSTCOUNT))* \
9413                              (STRIDE_LENGTH*OSTCOUNT - STRIDE_LENGTH)))
9414         DISCARD=$($LCTL get_param -n llite.*.read_ahead_stats |
9415                         get_named_value 'read but discarded' |
9416                         cut -d" " -f1 | calc_total)
9417         if [[ $DISCARD -gt $discard_limit ]]; then
9418                 $LCTL get_param llite.*.read_ahead_stats
9419                 error "Too many ($DISCARD) discarded pages with size (${READ_SIZE})"
9420         else
9421                 echo "Read-ahead success for size ${READ_SIZE}"
9422         fi
9423 }
9424
9425 test_101b() {
9426         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9427         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
9428
9429         local STRIPE_SIZE=1048576
9430         local STRIDE_SIZE=$((STRIPE_SIZE*OSTCOUNT))
9431
9432         if [ $SLOW == "yes" ]; then
9433                 local FILE_LENGTH=$((STRIDE_SIZE * 64))
9434         else
9435                 local FILE_LENGTH=$((STRIDE_SIZE * 8))
9436         fi
9437
9438         local ITERATION=$((FILE_LENGTH / STRIDE_SIZE))
9439
9440         # prepare the read-ahead file
9441         setup_test101bc $STRIPE_SIZE $FILE_LENGTH
9442         cancel_lru_locks osc
9443         for BIDX in 2 4 8 16 32 64 128 256
9444         do
9445                 local BSIZE=$((BIDX*4096))
9446                 local READ_COUNT=$((STRIPE_SIZE/BSIZE))
9447                 local STRIDE_LENGTH=$((STRIDE_SIZE/BSIZE))
9448                 local OFFSET=$((STRIPE_SIZE/BSIZE*(OSTCOUNT - 1)))
9449                 $LCTL set_param -n llite.*.read_ahead_stats 0
9450                 $READS -f $DIR/$tfile  -l $STRIDE_LENGTH -o $OFFSET \
9451                               -s $FILE_LENGTH -b $STRIPE_SIZE -a $READ_COUNT -n $ITERATION
9452                 cancel_lru_locks osc
9453                 ra_check_101 $BSIZE $STRIPE_SIZE $FILE_LENGTH
9454         done
9455         cleanup_test101bc
9456         true
9457 }
9458 run_test 101b "check stride-io mode read-ahead ================="
9459
9460 test_101c() {
9461         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9462
9463         local STRIPE_SIZE=1048576
9464         local FILE_LENGTH=$((STRIPE_SIZE*100))
9465         local nreads=10000
9466         local rsize=65536
9467         local osc_rpc_stats
9468
9469         setup_test101bc $STRIPE_SIZE $FILE_LENGTH
9470
9471         cancel_lru_locks osc
9472         $LCTL set_param osc.*.rpc_stats 0
9473         $READS -f $DIR/$tfile -s$FILE_LENGTH -b$rsize -n$nreads -t 180
9474         $LCTL get_param osc.*.rpc_stats
9475         for osc_rpc_stats in $($LCTL get_param -N osc.*.rpc_stats); do
9476                 local stats=$($LCTL get_param -n $osc_rpc_stats)
9477                 local lines=$(echo "$stats" | awk 'END {print NR;}')
9478                 local size
9479
9480                 if [ $lines -le 20 ]; then
9481                         echo "continue debug"
9482                         continue
9483                 fi
9484                 for size in 1 2 4 8; do
9485                         local rpc=$(echo "$stats" |
9486                                     awk '($1 == "'$size':") {print $2; exit; }')
9487                         [ $rpc != 0 ] && ((size * PAGE_SIZE < rsize)) &&
9488                                 error "Small $((size*PAGE_SIZE)) read IO $rpc!"
9489                 done
9490                 echo "$osc_rpc_stats check passed!"
9491         done
9492         cleanup_test101bc
9493         true
9494 }
9495 run_test 101c "check stripe_size aligned read-ahead ================="
9496
9497 test_101d() {
9498         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9499
9500         local file=$DIR/$tfile
9501         local sz_MB=${FILESIZE_101d:-80}
9502         local ra_MB=${READAHEAD_MB:-40}
9503
9504         local free_MB=$(($(df -P $DIR | tail -n 1 | awk '{ print $4 }') / 1024))
9505         [ $free_MB -lt $sz_MB ] &&
9506                 skip "Need free space ${sz_MB}M, have ${free_MB}M"
9507
9508         echo "Create test file $file size ${sz_MB}M, ${free_MB}M free"
9509         $LFS setstripe -c -1 $file || error "setstripe failed"
9510
9511         dd if=/dev/zero of=$file bs=1M count=$sz_MB || error "dd failed"
9512         echo Cancel LRU locks on lustre client to flush the client cache
9513         cancel_lru_locks osc
9514
9515         echo Disable read-ahead
9516         local old_RA=$($LCTL get_param -n llite.*.max_read_ahead_mb | head -n 1)
9517         $LCTL set_param -n llite.*.max_read_ahead_mb=0
9518         stack_trap "$LCTL set_param -n llite.*.max_read_ahead_mb $old_RA" EXIT
9519         $LCTL get_param -n llite.*.max_read_ahead_mb
9520
9521         echo "Reading the test file $file with read-ahead disabled"
9522         local sz_KB=$((sz_MB * 1024 / 4))
9523         # 10485760 bytes transferred in 0.000938 secs (11179579337 bytes/sec)
9524         # 104857600 bytes (105 MB) copied, 0.00876352 s, 12.0 GB/s
9525         local raOFF=$(LANG=C dd if=$file of=/dev/null bs=4k count=$sz_KB |&
9526                       sed -e '/records/d' -e 's/.* \([0-9]*\.[0-9]*\) *s.*/\1/')
9527
9528         echo "Cancel LRU locks on lustre client to flush the client cache"
9529         cancel_lru_locks osc
9530         echo Enable read-ahead with ${ra_MB}MB
9531         $LCTL set_param -n llite.*.max_read_ahead_mb=$ra_MB
9532
9533         echo "Reading the test file $file with read-ahead enabled"
9534         local raON=$(LANG=C dd if=$file of=/dev/null bs=4k count=$sz_KB |&
9535                      sed -e '/records/d' -e 's/.* \([0-9]*\.[0-9]*\) *s.*/\1/')
9536
9537         echo "read-ahead disabled time read $raOFF"
9538         echo "read-ahead enabled time read $raON"
9539
9540         rm -f $file
9541         wait_delete_completed
9542
9543         # use awk for this check instead of bash because it handles decimals
9544         awk "{ exit !($raOFF < 1.0 || $raOFF > $raON) }" <<<"ignore_me" ||
9545                 error "readahead ${raON}s > no-readahead ${raOFF}s ${sz_MB}M"
9546 }
9547 run_test 101d "file read with and without read-ahead enabled"
9548
9549 test_101e() {
9550         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9551
9552         local file=$DIR/$tfile
9553         local size_KB=500  #KB
9554         local count=100
9555         local bsize=1024
9556
9557         local free_KB=$(df -P $DIR | tail -n 1 | awk '{ print $4 }')
9558         local need_KB=$((count * size_KB))
9559         [[ $free_KB -le $need_KB ]] &&
9560                 skip_env "Need free space $need_KB, have $free_KB"
9561
9562         echo "Creating $count ${size_KB}K test files"
9563         for ((i = 0; i < $count; i++)); do
9564                 dd if=/dev/zero of=$file.$i bs=$bsize count=$size_KB 2>/dev/null
9565         done
9566
9567         echo "Cancel LRU locks on lustre client to flush the client cache"
9568         cancel_lru_locks $OSC
9569
9570         echo "Reset readahead stats"
9571         $LCTL set_param -n llite.*.read_ahead_stats 0
9572
9573         for ((i = 0; i < $count; i++)); do
9574                 dd if=$file.$i of=/dev/null bs=$bsize count=$size_KB 2>/dev/null
9575         done
9576
9577         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
9578                      get_named_value 'misses' | cut -d" " -f1 | calc_total)
9579
9580         for ((i = 0; i < $count; i++)); do
9581                 rm -rf $file.$i 2>/dev/null
9582         done
9583
9584         #10000 means 20% reads are missing in readahead
9585         [[ $miss -lt 10000 ]] ||  error "misses too much for small reads"
9586 }
9587 run_test 101e "check read-ahead for small read(1k) for small files(500k)"
9588
9589 test_101f() {
9590         which iozone || skip_env "no iozone installed"
9591
9592         local old_debug=$($LCTL get_param debug)
9593         old_debug=${old_debug#*=}
9594         $LCTL set_param debug="reada mmap"
9595
9596         # create a test file
9597         iozone -i 0 -+n -r 1m -s 128m -w -f $DIR/$tfile > /dev/null 2>&1
9598
9599         echo Cancel LRU locks on lustre client to flush the client cache
9600         cancel_lru_locks osc
9601
9602         echo Reset readahead stats
9603         $LCTL set_param -n llite.*.read_ahead_stats 0
9604
9605         echo mmap read the file with small block size
9606         iozone -i 1 -u 1 -l 1 -+n -r 32k -s 128m -B -f $DIR/$tfile \
9607                 > /dev/null 2>&1
9608
9609         echo checking missing pages
9610         $LCTL get_param llite.*.read_ahead_stats
9611         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
9612                         get_named_value 'misses' | cut -d" " -f1 | calc_total)
9613
9614         $LCTL set_param debug="$old_debug"
9615         [ $miss -lt 3 ] || error "misses too much pages ('$miss')!"
9616         rm -f $DIR/$tfile
9617 }
9618 run_test 101f "check mmap read performance"
9619
9620 test_101g_brw_size_test() {
9621         local mb=$1
9622         local pages=$((mb * 1048576 / PAGE_SIZE))
9623         local file=$DIR/$tfile
9624
9625         $LCTL set_param osc.*.max_pages_per_rpc=${mb}M ||
9626                 { error "unable to set max_pages_per_rpc=${mb}M"; return 1; }
9627         for mp in $($LCTL get_param -n osc.*.max_pages_per_rpc); do
9628                 [ $mp -ne $pages ] && error "max_pages_per_rpc $mp != $pages" &&
9629                         return 2
9630         done
9631
9632         stack_trap "rm -f $file" EXIT
9633         $LCTL set_param -n osc.*.rpc_stats=0
9634
9635         # 10 RPCs should be enough for the test
9636         local count=10
9637         dd if=/dev/zero of=$file bs=${mb}M count=$count ||
9638                 { error "dd write ${mb} MB blocks failed"; return 3; }
9639         cancel_lru_locks osc
9640         dd of=/dev/null if=$file bs=${mb}M count=$count ||
9641                 { error "dd write ${mb} MB blocks failed"; return 4; }
9642
9643         # calculate number of full-sized read and write RPCs
9644         rpcs=($($LCTL get_param -n 'osc.*.rpc_stats' |
9645                 sed -n '/pages per rpc/,/^$/p' |
9646                 awk '/'$pages':/ { reads += $2; writes += $6 }; \
9647                 END { print reads,writes }'))
9648         # allow one extra full-sized read RPC for async readahead
9649         [[ ${rpcs[0]} == $count || ${rpcs[0]} == $((count + 1)) ]] ||
9650                 { error "${rpcs[0]} != $count read RPCs"; return 5; }
9651         [[ ${rpcs[1]} == $count ]] ||
9652                 { error "${rpcs[1]} != $count write RPCs"; return 6; }
9653 }
9654
9655 test_101g() {
9656         remote_ost_nodsh && skip "remote OST with nodsh"
9657
9658         local rpcs
9659         local osts=$(get_facets OST)
9660         local list=$(comma_list $(osts_nodes))
9661         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
9662         local brw_size="obdfilter.*.brw_size"
9663
9664         $LFS setstripe -i 0 -c 1 $DIR/$tfile
9665
9666         local orig_mb=$(do_facet ost1 $LCTL get_param -n $brw_size | head -n 1)
9667
9668         if { [ $OST1_VERSION -ge $(version_code 2.8.52) ] ||
9669                 { [ $OST1_VERSION -ge $(version_code 2.7.17) ] &&
9670                   [ $OST1_VERSION -lt $(version_code 2.7.50) ]; }; } &&
9671            { [ $CLIENT_VERSION -ge $(version_code 2.8.52) ] ||
9672                 { [ $CLIENT_VERSION -ge $(version_code 2.7.17) ] &&
9673                   [ $CLIENT_VERSION -lt $(version_code 2.7.50) ]; }; }; then
9674
9675                 [ $OST1_VERSION -ge $(version_code 2.9.52) ] &&
9676                         suffix="M"
9677
9678                 if [[ $orig_mb -lt 16 ]]; then
9679                         save_lustre_params $osts "$brw_size" > $p
9680                         do_nodes $list $LCTL set_param -n $brw_size=16$suffix ||
9681                                 error "set 16MB RPC size failed"
9682
9683                         echo "remount client to enable new RPC size"
9684                         remount_client $MOUNT || error "remount_client failed"
9685                 fi
9686
9687                 test_101g_brw_size_test 16 || error "16MB RPC test failed"
9688                 # should be able to set brw_size=12, but no rpc_stats for that
9689                 test_101g_brw_size_test 8 || error "8MB RPC test failed"
9690         fi
9691
9692         test_101g_brw_size_test 4 || error "4MB RPC test failed"
9693
9694         if [[ $orig_mb -lt 16 ]]; then
9695                 restore_lustre_params < $p
9696                 remount_client $MOUNT || error "remount_client restore failed"
9697         fi
9698
9699         rm -f $p $DIR/$tfile
9700 }
9701 run_test 101g "Big bulk(4/16 MiB) readahead"
9702
9703 test_101h() {
9704         $LFS setstripe -i 0 -c 1 $DIR/$tfile
9705
9706         dd if=/dev/zero of=$DIR/$tfile bs=1M count=70 ||
9707                 error "dd 70M file failed"
9708         echo Cancel LRU locks on lustre client to flush the client cache
9709         cancel_lru_locks osc
9710
9711         echo "Reset readahead stats"
9712         $LCTL set_param -n llite.*.read_ahead_stats 0
9713
9714         echo "Read 10M of data but cross 64M bundary"
9715         dd if=$DIR/$tfile of=/dev/null bs=10M skip=6 count=1
9716         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
9717                         get_named_value 'misses' | cut -d" " -f1 | calc_total)
9718         [ $miss -eq 1 ] || error "expected miss 1 but got $miss"
9719         rm -f $p $DIR/$tfile
9720 }
9721 run_test 101h "Readahead should cover current read window"
9722
9723 test_101i() {
9724         dd if=/dev/zero of=$DIR/$tfile bs=1M count=10 ||
9725                 error "dd 10M file failed"
9726
9727         local max_per_file_mb=$($LCTL get_param -n \
9728                 llite.*.max_read_ahead_per_file_mb 2>/dev/null)
9729         cancel_lru_locks osc
9730         stack_trap "$LCTL set_param llite.*.max_read_ahead_per_file_mb=$max_per_file_mb"
9731         $LCTL set_param llite.*.max_read_ahead_per_file_mb=1 ||
9732                 error "set max_read_ahead_per_file_mb to 1 failed"
9733
9734         echo "Reset readahead stats"
9735         $LCTL set_param llite.*.read_ahead_stats=0
9736
9737         dd if=$DIR/$tfile of=/dev/null bs=2M
9738
9739         $LCTL get_param llite.*.read_ahead_stats
9740         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
9741                      awk '/misses/ { print $2 }')
9742         [ $miss -eq 5 ] || error "expected misses 5 but got $miss"
9743         rm -f $DIR/$tfile
9744 }
9745 run_test 101i "allow current readahead to exceed reservation"
9746
9747 test_101j() {
9748         $LFS setstripe -i 0 -c 1 $DIR/$tfile ||
9749                 error "setstripe $DIR/$tfile failed"
9750         local file_size=$((1048576 * 16))
9751         local old_ra=$($LCTL get_param -n llite.*.max_read_ahead_mb | head -n 1)
9752         stack_trap "$LCTL set_param -n llite.*.max_read_ahead_mb $old_ra" EXIT
9753
9754         echo Disable read-ahead
9755         $LCTL set_param -n llite.*.max_read_ahead_mb=0
9756
9757         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$(($file_size / 1048576))
9758         for blk in $PAGE_SIZE 1048576 $file_size; do
9759                 cancel_lru_locks osc
9760                 echo "Reset readahead stats"
9761                 $LCTL set_param -n llite.*.read_ahead_stats=0
9762                 local count=$(($file_size / $blk))
9763                 dd if=$DIR/$tfile bs=$blk count=$count of=/dev/null
9764                 local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
9765                              get_named_value 'failed to fast read' |
9766                              cut -d" " -f1 | calc_total)
9767                 $LCTL get_param -n llite.*.read_ahead_stats
9768                 [ $miss -eq $count ] || error "expected $count got $miss"
9769         done
9770
9771         rm -f $p $DIR/$tfile
9772 }
9773 run_test 101j "A complete read block should be submitted when no RA"
9774
9775 setup_test102() {
9776         test_mkdir $DIR/$tdir
9777         chown $RUNAS_ID $DIR/$tdir
9778         STRIPE_SIZE=65536
9779         STRIPE_OFFSET=1
9780         STRIPE_COUNT=$OSTCOUNT
9781         [[ $OSTCOUNT -gt 4 ]] && STRIPE_COUNT=4
9782
9783         trap cleanup_test102 EXIT
9784         cd $DIR
9785         $1 $LFS setstripe -S $STRIPE_SIZE -i $STRIPE_OFFSET -c $STRIPE_COUNT $tdir
9786         cd $DIR/$tdir
9787         for num in 1 2 3 4; do
9788                 for count in $(seq 1 $STRIPE_COUNT); do
9789                         for idx in $(seq 0 $[$STRIPE_COUNT - 1]); do
9790                                 local size=`expr $STRIPE_SIZE \* $num`
9791                                 local file=file"$num-$idx-$count"
9792                                 $1 $LFS setstripe -S $size -i $idx -c $count $file
9793                         done
9794                 done
9795         done
9796
9797         cd $DIR
9798         $1 tar cf $TMP/f102.tar $tdir --xattrs
9799 }
9800
9801 cleanup_test102() {
9802         trap 0
9803         rm -f $TMP/f102.tar
9804         rm -rf $DIR/d0.sanity/d102
9805 }
9806
9807 test_102a() {
9808         [ "$UID" != 0 ] && skip "must run as root"
9809         [ -z "$(lctl get_param -n mdc.*-mdc-*.connect_flags | grep xattr)" ] &&
9810                 skip_env "must have user_xattr"
9811
9812         [ -z "$(which setfattr 2>/dev/null)" ] &&
9813                 skip_env "could not find setfattr"
9814
9815         local testfile=$DIR/$tfile
9816
9817         touch $testfile
9818         echo "set/get xattr..."
9819         setfattr -n trusted.name1 -v value1 $testfile ||
9820                 error "setfattr -n trusted.name1=value1 $testfile failed"
9821         getfattr -n trusted.name1 $testfile 2> /dev/null |
9822           grep "trusted.name1=.value1" ||
9823                 error "$testfile missing trusted.name1=value1"
9824
9825         setfattr -n user.author1 -v author1 $testfile ||
9826                 error "setfattr -n user.author1=author1 $testfile failed"
9827         getfattr -n user.author1 $testfile 2> /dev/null |
9828           grep "user.author1=.author1" ||
9829                 error "$testfile missing trusted.author1=author1"
9830
9831         echo "listxattr..."
9832         setfattr -n trusted.name2 -v value2 $testfile ||
9833                 error "$testfile unable to set trusted.name2"
9834         setfattr -n trusted.name3 -v value3 $testfile ||
9835                 error "$testfile unable to set trusted.name3"
9836         [ $(getfattr -d -m "^trusted" $testfile 2> /dev/null |
9837             grep "trusted.name" | wc -l) -eq 3 ] ||
9838                 error "$testfile missing 3 trusted.name xattrs"
9839
9840         setfattr -n user.author2 -v author2 $testfile ||
9841                 error "$testfile unable to set user.author2"
9842         setfattr -n user.author3 -v author3 $testfile ||
9843                 error "$testfile unable to set user.author3"
9844         [ $(getfattr -d -m "^user" $testfile 2> /dev/null |
9845             grep "user.author" | wc -l) -eq 3 ] ||
9846                 error "$testfile missing 3 user.author xattrs"
9847
9848         echo "remove xattr..."
9849         setfattr -x trusted.name1 $testfile ||
9850                 error "$testfile error deleting trusted.name1"
9851         getfattr -d -m trusted $testfile 2> /dev/null | grep "trusted.name1" &&
9852                 error "$testfile did not delete trusted.name1 xattr"
9853
9854         setfattr -x user.author1 $testfile ||
9855                 error "$testfile error deleting user.author1"
9856         echo "set lustre special xattr ..."
9857         $LFS setstripe -c1 $testfile
9858         local lovea=$(getfattr -n "trusted.lov" -e hex $testfile |
9859                 awk -F "=" '/trusted.lov/ { print $2 }' )
9860         setfattr -n "trusted.lov" -v $lovea $testfile ||
9861                 error "$testfile doesn't ignore setting trusted.lov again"
9862         setfattr -n "trusted.lov" -v "invalid_value" $testfile &&
9863                 error "$testfile allow setting invalid trusted.lov"
9864         rm -f $testfile
9865 }
9866 run_test 102a "user xattr test =================================="
9867
9868 check_102b_layout() {
9869         local layout="$*"
9870         local testfile=$DIR/$tfile
9871
9872         echo "test layout '$layout'"
9873         $LFS setstripe $layout $testfile || error "setstripe failed"
9874         $LFS getstripe -y $testfile
9875
9876         echo "get/set/list trusted.lov xattr ..." # b=10930
9877         local value=$(getfattr -n trusted.lov -e hex $testfile | grep trusted)
9878         [[ "$value" =~ "trusted.lov" ]] ||
9879                 error "can't get trusted.lov from $testfile"
9880         local stripe_count_orig=$($LFS getstripe -c $testfile) ||
9881                 error "getstripe failed"
9882
9883         $MCREATE $testfile.2 || error "mcreate $testfile.2 failed"
9884
9885         value=$(cut -d= -f2 <<<$value)
9886         # LU-13168: truncated xattr should fail if short lov_user_md header
9887         [ $CLIENT_VERSION -lt $(version_code 2.13.53) ] &&
9888                 lens="${#value}" || lens="$(seq 4 2 ${#value})"
9889         for len in $lens; do
9890                 echo "setfattr $len $testfile.2"
9891                 setfattr -n trusted.lov -v ${value:0:$len} $testfile.2 &&
9892                         [ $len -lt 66 ] && error "short xattr len=$len worked"
9893         done
9894         local stripe_size=$($LFS getstripe -S $testfile.2)
9895         local stripe_count=$($LFS getstripe -c $testfile.2)
9896         [[ $stripe_size -eq 65536 ]] ||
9897                 error "stripe size $stripe_size != 65536"
9898         [[ $stripe_count -eq $stripe_count_orig ]] ||
9899                 error "stripe count $stripe_count != $stripe_count_orig"
9900         rm $testfile $testfile.2
9901 }
9902
9903 test_102b() {
9904         [ -z "$(which setfattr 2>/dev/null)" ] &&
9905                 skip_env "could not find setfattr"
9906         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
9907
9908         # check plain layout
9909         check_102b_layout -S 65536 -i 1 -c $OSTCOUNT
9910
9911         # and also check composite layout
9912         check_102b_layout -E 1M -S 65536 -i 1 -c $OSTCOUNT -Eeof -S4M
9913
9914 }
9915 run_test 102b "getfattr/setfattr for trusted.lov EAs"
9916
9917 test_102c() {
9918         [ -z "$(which setfattr 2>/dev/null)" ] &&
9919                 skip_env "could not find setfattr"
9920         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
9921
9922         # b10930: get/set/list lustre.lov xattr
9923         echo "get/set/list lustre.lov xattr ..."
9924         test_mkdir $DIR/$tdir
9925         chown $RUNAS_ID $DIR/$tdir
9926         local testfile=$DIR/$tdir/$tfile
9927         $RUNAS $LFS setstripe -S 65536 -i 1 -c $OSTCOUNT $testfile ||
9928                 error "setstripe failed"
9929         local STRIPECOUNT=$($RUNAS $LFS getstripe -c $testfile) ||
9930                 error "getstripe failed"
9931         $RUNAS getfattr -d -m "^lustre" $testfile 2> /dev/null | \
9932         grep "lustre.lov" || error "can't get lustre.lov from $testfile"
9933
9934         local testfile2=${testfile}2
9935         local value=`getfattr -n lustre.lov $testfile 2> /dev/null | \
9936                      grep "lustre.lov" |sed -e 's/[^=]\+=//'  `
9937
9938         $RUNAS $MCREATE $testfile2
9939         $RUNAS setfattr -n lustre.lov -v $value $testfile2
9940         local stripe_size=$($RUNAS $LFS getstripe -S $testfile2)
9941         local stripe_count=$($RUNAS $LFS getstripe -c $testfile2)
9942         [ $stripe_size -eq 65536 ] || error "stripe size $stripe_size != 65536"
9943         [ $stripe_count -eq $STRIPECOUNT ] ||
9944                 error "stripe count $stripe_count != $STRIPECOUNT"
9945 }
9946 run_test 102c "non-root getfattr/setfattr for lustre.lov EAs ==========="
9947
9948 compare_stripe_info1() {
9949         local stripe_index_all_zero=true
9950
9951         for num in 1 2 3 4; do
9952                 for count in $(seq 1 $STRIPE_COUNT); do
9953                         for offset in $(seq 0 $[$STRIPE_COUNT - 1]); do
9954                                 local size=$((STRIPE_SIZE * num))
9955                                 local file=file"$num-$offset-$count"
9956                                 stripe_size=$($LFS getstripe -S $PWD/$file)
9957                                 [[ $stripe_size -ne $size ]] &&
9958                                     error "$file: size $stripe_size != $size"
9959                                 stripe_count=$($LFS getstripe -c $PWD/$file)
9960                                 # allow fewer stripes to be created, ORI-601
9961                                 [[ $stripe_count -lt $(((3 * count + 3) / 4)) ]] &&
9962                                     error "$file: count $stripe_count != $count"
9963                                 stripe_index=$($LFS getstripe -i $PWD/$file)
9964                                 [[ $stripe_index -ne 0 ]] &&
9965                                         stripe_index_all_zero=false
9966                         done
9967                 done
9968         done
9969         $stripe_index_all_zero &&
9970                 error "all files are being extracted starting from OST index 0"
9971         return 0
9972 }
9973
9974 have_xattrs_include() {
9975         tar --help | grep -q xattrs-include &&
9976                 echo --xattrs-include="lustre.*"
9977 }
9978
9979 test_102d() {
9980         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9981         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
9982
9983         XINC=$(have_xattrs_include)
9984         setup_test102
9985         tar xf $TMP/f102.tar -C $DIR/$tdir --xattrs $XINC
9986         cd $DIR/$tdir/$tdir
9987         compare_stripe_info1
9988 }
9989 run_test 102d "tar restore stripe info from tarfile,not keep osts"
9990
9991 test_102f() {
9992         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9993         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
9994
9995         XINC=$(have_xattrs_include)
9996         setup_test102
9997         test_mkdir $DIR/$tdir.restore
9998         cd $DIR
9999         tar cf - --xattrs $tdir | tar xf - \
10000                 -C $DIR/$tdir.restore --xattrs $XINC
10001         cd $DIR/$tdir.restore/$tdir
10002         compare_stripe_info1
10003 }
10004 run_test 102f "tar copy files, not keep osts"
10005
10006 grow_xattr() {
10007         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep xattr)" ] &&
10008                 skip "must have user_xattr"
10009         [ -z "$(which setfattr 2>/dev/null)" ] &&
10010                 skip_env "could not find setfattr"
10011         [ -z "$(which getfattr 2>/dev/null)" ] &&
10012                 skip_env "could not find getfattr"
10013
10014         local xsize=${1:-1024}  # in bytes
10015         local file=$DIR/$tfile
10016         local value="$(generate_string $xsize)"
10017         local xbig=trusted.big
10018         local toobig=$2
10019
10020         touch $file
10021         log "save $xbig on $file"
10022         if [ -z "$toobig" ]
10023         then
10024                 setfattr -n $xbig -v $value $file ||
10025                         error "saving $xbig on $file failed"
10026         else
10027                 setfattr -n $xbig -v $value $file &&
10028                         error "saving $xbig on $file succeeded"
10029                 return 0
10030         fi
10031
10032         local orig=$(get_xattr_value $xbig $file)
10033         [[ "$orig" != "$value" ]] && error "$xbig different after saving $xbig"
10034
10035         local xsml=trusted.sml
10036         log "save $xsml on $file"
10037         setfattr -n $xsml -v val $file || error "saving $xsml on $file failed"
10038
10039         local new=$(get_xattr_value $xbig $file)
10040         [[ "$new" != "$orig" ]] && error "$xbig different after saving $xsml"
10041
10042         log "grow $xsml on $file"
10043         setfattr -n $xsml -v "$value" $file ||
10044                 error "growing $xsml on $file failed"
10045
10046         new=$(get_xattr_value $xbig $file)
10047         [[ "$new" != "$orig" ]] && error "$xbig different after growing $xsml"
10048         log "$xbig still valid after growing $xsml"
10049
10050         rm -f $file
10051 }
10052
10053 test_102h() { # bug 15777
10054         grow_xattr 1024
10055 }
10056 run_test 102h "grow xattr from inside inode to external block"
10057
10058 test_102ha() {
10059         large_xattr_enabled || skip_env "ea_inode feature disabled"
10060
10061         echo "setting xattr of max xattr size: $(max_xattr_size)"
10062         grow_xattr $(max_xattr_size)
10063
10064         echo "setting xattr of > max xattr size: $(max_xattr_size) + 10"
10065         echo "This should fail:"
10066         grow_xattr $(($(max_xattr_size) + 10)) 1
10067 }
10068 run_test 102ha "grow xattr from inside inode to external inode"
10069
10070 test_102i() { # bug 17038
10071         [ -z "$(which getfattr 2>/dev/null)" ] &&
10072                 skip "could not find getfattr"
10073
10074         touch $DIR/$tfile
10075         ln -s $DIR/$tfile $DIR/${tfile}link
10076         getfattr -n trusted.lov $DIR/$tfile ||
10077                 error "lgetxattr on $DIR/$tfile failed"
10078         getfattr -h -n trusted.lov $DIR/${tfile}link 2>&1 |
10079                 grep -i "no such attr" ||
10080                 error "error for lgetxattr on $DIR/${tfile}link is not ENODATA"
10081         rm -f $DIR/$tfile $DIR/${tfile}link
10082 }
10083 run_test 102i "lgetxattr test on symbolic link ============"
10084
10085 test_102j() {
10086         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10087         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
10088
10089         XINC=$(have_xattrs_include)
10090         setup_test102 "$RUNAS"
10091         chown $RUNAS_ID $DIR/$tdir
10092         $RUNAS tar xf $TMP/f102.tar -C $DIR/$tdir --xattrs $XINC
10093         cd $DIR/$tdir/$tdir
10094         compare_stripe_info1 "$RUNAS"
10095 }
10096 run_test 102j "non-root tar restore stripe info from tarfile, not keep osts ==="
10097
10098 test_102k() {
10099         [ -z "$(which setfattr 2>/dev/null)" ] &&
10100                 skip "could not find setfattr"
10101
10102         touch $DIR/$tfile
10103         # b22187 just check that does not crash for regular file.
10104         setfattr -n trusted.lov $DIR/$tfile
10105         # b22187 'setfattr -n trusted.lov' should remove LOV EA for directories
10106         local test_kdir=$DIR/$tdir
10107         test_mkdir $test_kdir
10108         local default_size=$($LFS getstripe -S $test_kdir)
10109         local default_count=$($LFS getstripe -c $test_kdir)
10110         local default_offset=$($LFS getstripe -i $test_kdir)
10111         $LFS setstripe -S 65536 -i 0 -c $OSTCOUNT $test_kdir ||
10112                 error 'dir setstripe failed'
10113         setfattr -n trusted.lov $test_kdir
10114         local stripe_size=$($LFS getstripe -S $test_kdir)
10115         local stripe_count=$($LFS getstripe -c $test_kdir)
10116         local stripe_offset=$($LFS getstripe -i $test_kdir)
10117         [ $stripe_size -eq $default_size ] ||
10118                 error "stripe size $stripe_size != $default_size"
10119         [ $stripe_count -eq $default_count ] ||
10120                 error "stripe count $stripe_count != $default_count"
10121         [ $stripe_offset -eq $default_offset ] ||
10122                 error "stripe offset $stripe_offset != $default_offset"
10123         rm -rf $DIR/$tfile $test_kdir
10124 }
10125 run_test 102k "setfattr without parameter of value shouldn't cause a crash"
10126
10127 test_102l() {
10128         [ -z "$(which getfattr 2>/dev/null)" ] &&
10129                 skip "could not find getfattr"
10130
10131         # LU-532 trusted. xattr is invisible to non-root
10132         local testfile=$DIR/$tfile
10133
10134         touch $testfile
10135
10136         echo "listxattr as user..."
10137         chown $RUNAS_ID $testfile
10138         $RUNAS getfattr -d -m '.*' $testfile 2>&1 |
10139             grep -q "trusted" &&
10140                 error "$testfile trusted xattrs are user visible"
10141
10142         return 0;
10143 }
10144 run_test 102l "listxattr size test =================================="
10145
10146 test_102m() { # LU-3403 llite: error of listxattr when buffer is small
10147         local path=$DIR/$tfile
10148         touch $path
10149
10150         listxattr_size_check $path || error "listattr_size_check $path failed"
10151 }
10152 run_test 102m "Ensure listxattr fails on small bufffer ========"
10153
10154 cleanup_test102
10155
10156 getxattr() { # getxattr path name
10157         # Return the base64 encoding of the value of xattr name on path.
10158         local path=$1
10159         local name=$2
10160
10161         # # getfattr --absolute-names --encoding=base64 --name=trusted.lov $path
10162         # file: $path
10163         # trusted.lov=0s0AvRCwEAAAAGAAAAAAAAAAAEAAACAAAAAAAQAAEAA...AAAAAAAAA=
10164         #
10165         # We print just 0s0AvRCwEAAAAGAAAAAAAAAAAEAAACAAAAAAAQAAEAA...AAAAAAAAA=
10166
10167         getfattr --absolute-names --encoding=base64 --name=$name $path |
10168                 awk -F= -v name=$name '$1 == name {
10169                         print substr($0, index($0, "=") + 1);
10170         }'
10171 }
10172
10173 test_102n() { # LU-4101 mdt: protect internal xattrs
10174         [ -z "$(which setfattr 2>/dev/null)" ] &&
10175                 skip "could not find setfattr"
10176         if [ $MDS1_VERSION -lt $(version_code 2.5.50) ]
10177         then
10178                 skip "MDT < 2.5.50 allows setxattr on internal trusted xattrs"
10179         fi
10180
10181         local file0=$DIR/$tfile.0
10182         local file1=$DIR/$tfile.1
10183         local xattr0=$TMP/$tfile.0
10184         local xattr1=$TMP/$tfile.1
10185         local namelist="lov lma lmv link fid version som hsm"
10186         local name
10187         local value
10188
10189         rm -rf $file0 $file1 $xattr0 $xattr1
10190         touch $file0 $file1
10191
10192         # Get 'before' xattrs of $file1.
10193         getfattr --absolute-names --dump --match=- $file1 > $xattr0
10194
10195         [ $MDS1_VERSION -lt $(version_code 2.8.53) ] &&
10196                 namelist+=" lfsck_namespace"
10197         for name in $namelist; do
10198                 # Try to copy xattr from $file0 to $file1.
10199                 value=$(getxattr $file0 trusted.$name 2> /dev/null)
10200
10201                 setfattr --name=trusted.$name --value="$value" $file1 ||
10202                         error "setxattr 'trusted.$name' failed"
10203
10204                 # Try to set a garbage xattr.
10205                 value=0sVGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIGl0c2VsZi4=
10206
10207                 if [[ x$name == "xlov" ]]; then
10208                         setfattr --name=trusted.lov --value="$value" $file1 &&
10209                         error "setxattr invalid 'trusted.lov' success"
10210                 else
10211                         setfattr --name=trusted.$name --value="$value" $file1 ||
10212                                 error "setxattr invalid 'trusted.$name' failed"
10213                 fi
10214
10215                 # Try to remove the xattr from $file1. We don't care if this
10216                 # appears to succeed or fail, we just don't want there to be
10217                 # any changes or crashes.
10218                 setfattr --remove=$trusted.$name $file1 2> /dev/null
10219         done
10220
10221         if [ $MDS1_VERSION -gt $(version_code 2.6.50) ]
10222         then
10223                 name="lfsck_ns"
10224                 # Try to copy xattr from $file0 to $file1.
10225                 value=$(getxattr $file0 trusted.$name 2> /dev/null)
10226
10227                 setfattr --name=trusted.$name --value="$value" $file1 ||
10228                         error "setxattr 'trusted.$name' failed"
10229
10230                 # Try to set a garbage xattr.
10231                 value=0sVGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIGl0c2VsZi4=
10232
10233                 setfattr --name=trusted.$name --value="$value" $file1 ||
10234                         error "setxattr 'trusted.$name' failed"
10235
10236                 # Try to remove the xattr from $file1. We don't care if this
10237                 # appears to succeed or fail, we just don't want there to be
10238                 # any changes or crashes.
10239                 setfattr --remove=$trusted.$name $file1 2> /dev/null
10240         fi
10241
10242         # Get 'after' xattrs of file1.
10243         getfattr --absolute-names --dump --match=- $file1 > $xattr1
10244
10245         if ! diff $xattr0 $xattr1; then
10246                 error "before and after xattrs of '$file1' differ"
10247         fi
10248
10249         rm -rf $file0 $file1 $xattr0 $xattr1
10250
10251         return 0
10252 }
10253 run_test 102n "silently ignore setxattr on internal trusted xattrs"
10254
10255 test_102p() { # LU-4703 setxattr did not check ownership
10256         [ $MDS1_VERSION -lt $(version_code 2.5.56) ] &&
10257                 skip "MDS needs to be at least 2.5.56"
10258
10259         local testfile=$DIR/$tfile
10260
10261         touch $testfile
10262
10263         echo "setfacl as user..."
10264         $RUNAS setfacl -m "u:$RUNAS_ID:rwx" $testfile
10265         [ $? -ne 0 ] || error "setfacl by $RUNAS_ID was allowed on $testfile"
10266
10267         echo "setfattr as user..."
10268         setfacl -m "u:$RUNAS_ID:---" $testfile
10269         $RUNAS setfattr -x system.posix_acl_access $testfile
10270         [ $? -ne 0 ] || error "setfattr by $RUNAS_ID was allowed on $testfile"
10271 }
10272 run_test 102p "check setxattr(2) correctly fails without permission"
10273
10274 test_102q() {
10275         [ $MDS1_VERSION -lt $(version_code 2.6.92) ] &&
10276                 skip "MDS needs to be at least 2.6.92"
10277
10278         orphan_linkea_check $DIR/$tfile || error "orphan_linkea_check"
10279 }
10280 run_test 102q "flistxattr should not return trusted.link EAs for orphans"
10281
10282 test_102r() {
10283         [ $MDS1_VERSION -lt $(version_code 2.6.93) ] &&
10284                 skip "MDS needs to be at least 2.6.93"
10285
10286         touch $DIR/$tfile || error "touch"
10287         setfattr -n user.$(basename $tfile) $DIR/$tfile || error "setfattr"
10288         getfattr -n user.$(basename $tfile) $DIR/$tfile || error "getfattr"
10289         rm $DIR/$tfile || error "rm"
10290
10291         #normal directory
10292         mkdir -p $DIR/$tdir || error "mkdir"
10293         setfattr -n user.$(basename $tdir) $DIR/$tdir || error "setfattr dir"
10294         getfattr -n user.$(basename $tdir) $DIR/$tdir || error "getfattr dir"
10295         setfattr -x user.$(basename $tdir) $DIR/$tdir ||
10296                 error "$testfile error deleting user.author1"
10297         getfattr -d -m user.$(basename $tdir) 2> /dev/null |
10298                 grep "user.$(basename $tdir)" &&
10299                 error "$tdir did not delete user.$(basename $tdir)"
10300         rmdir $DIR/$tdir || error "rmdir"
10301
10302         #striped directory
10303         test_mkdir $DIR/$tdir
10304         setfattr -n user.$(basename $tdir) $DIR/$tdir || error "setfattr dir"
10305         getfattr -n user.$(basename $tdir) $DIR/$tdir || error "getfattr dir"
10306         setfattr -x user.$(basename $tdir) $DIR/$tdir ||
10307                 error "$testfile error deleting user.author1"
10308         getfattr -d -m user.$(basename $tdir) 2> /dev/null |
10309                 grep "user.$(basename $tdir)" &&
10310                 error "$tdir did not delete user.$(basename $tdir)"
10311         rmdir $DIR/$tdir || error "rm striped dir"
10312 }
10313 run_test 102r "set EAs with empty values"
10314
10315 test_102s() {
10316         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
10317                 skip "MDS needs to be at least 2.11.52"
10318
10319         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
10320
10321         save_lustre_params client "llite.*.xattr_cache" > $save
10322
10323         for cache in 0 1; do
10324                 lctl set_param llite.*.xattr_cache=$cache
10325
10326                 rm -f $DIR/$tfile
10327                 touch $DIR/$tfile || error "touch"
10328                 for prefix in lustre security system trusted user; do
10329                         # Note getxattr() may fail with 'Operation not
10330                         # supported' or 'No such attribute' depending
10331                         # on prefix and cache.
10332                         getfattr -n $prefix.n102s $DIR/$tfile &&
10333                                 error "getxattr '$prefix.n102s' should fail (cache = $cache)"
10334                 done
10335         done
10336
10337         restore_lustre_params < $save
10338 }
10339 run_test 102s "getting nonexistent xattrs should fail"
10340
10341 test_102t() {
10342         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
10343                 skip "MDS needs to be at least 2.11.52"
10344
10345         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
10346
10347         save_lustre_params client "llite.*.xattr_cache" > $save
10348
10349         for cache in 0 1; do
10350                 lctl set_param llite.*.xattr_cache=$cache
10351
10352                 for buf_size in 0 256; do
10353                         rm -f $DIR/$tfile
10354                         touch $DIR/$tfile || error "touch"
10355                         setfattr -n user.multiop $DIR/$tfile
10356                         $MULTIOP $DIR/$tfile oa$buf_size ||
10357                                 error "cannot get zero length xattr value (buf_size = $buf_size)"
10358                 done
10359         done
10360
10361         restore_lustre_params < $save
10362 }
10363 run_test 102t "zero length xattr values handled correctly"
10364
10365 run_acl_subtest()
10366 {
10367     $LUSTRE/tests/acl/run $LUSTRE/tests/acl/$1.test
10368     return $?
10369 }
10370
10371 test_103a() {
10372         [ "$UID" != 0 ] && skip "must run as root"
10373         $GSS && skip_env "could not run under gss"
10374         [ -z "$(lctl get_param -n mdc.*-mdc-*.connect_flags | grep acl)" ] &&
10375                 skip_env "must have acl enabled"
10376         [ -z "$(which setfacl 2>/dev/null)" ] &&
10377                 skip_env "could not find setfacl"
10378         remote_mds_nodsh && skip "remote MDS with nodsh"
10379
10380         gpasswd -a daemon bin                           # LU-5641
10381         do_facet $SINGLEMDS gpasswd -a daemon bin       # LU-5641
10382
10383         declare -a identity_old
10384
10385         for num in $(seq $MDSCOUNT); do
10386                 switch_identity $num true || identity_old[$num]=$?
10387         done
10388
10389         SAVE_UMASK=$(umask)
10390         umask 0022
10391         mkdir -p $DIR/$tdir
10392         cd $DIR/$tdir
10393
10394         echo "performing cp ..."
10395         run_acl_subtest cp || error "run_acl_subtest cp failed"
10396         echo "performing getfacl-noacl..."
10397         run_acl_subtest getfacl-noacl || error "getfacl-noacl test failed"
10398         echo "performing misc..."
10399         run_acl_subtest misc || error  "misc test failed"
10400         echo "performing permissions..."
10401         run_acl_subtest permissions || error "permissions failed"
10402         # LU-1482 mdd: Setting xattr are properly checked with and without ACLs
10403         if [ $MDS1_VERSION -gt $(version_code 2.8.55) ] ||
10404                 { [ $MDS1_VERSION -lt $(version_code 2.6) ] &&
10405                         [ $MDS1_VERSION -ge $(version_code 2.5.29) ]; }
10406         then
10407                 echo "performing permissions xattr..."
10408                 run_acl_subtest permissions_xattr ||
10409                         error "permissions_xattr failed"
10410         fi
10411         echo "performing setfacl..."
10412         run_acl_subtest setfacl || error  "setfacl test failed"
10413
10414         # inheritance test got from HP
10415         echo "performing inheritance..."
10416         cp $LUSTRE/tests/acl/make-tree . || error "cannot copy make-tree"
10417         chmod +x make-tree || error "chmod +x failed"
10418         run_acl_subtest inheritance || error "inheritance test failed"
10419         rm -f make-tree
10420
10421         echo "LU-974 ignore umask when acl is enabled..."
10422         run_acl_subtest 974 || error "LU-974 umask test failed"
10423         if [ $MDSCOUNT -ge 2 ]; then
10424                 run_acl_subtest 974_remote ||
10425                         error "LU-974 umask test failed under remote dir"
10426         fi
10427
10428         echo "LU-2561 newly created file is same size as directory..."
10429         if [ "$mds1_FSTYPE" != "zfs" ]; then
10430                 run_acl_subtest 2561 || error "LU-2561 test failed"
10431         else
10432                 run_acl_subtest 2561_zfs || error "LU-2561 zfs test failed"
10433         fi
10434
10435         run_acl_subtest 4924 || error "LU-4924 test failed"
10436
10437         cd $SAVE_PWD
10438         umask $SAVE_UMASK
10439
10440         for num in $(seq $MDSCOUNT); do
10441                 if [ "${identity_old[$num]}" = 1 ]; then
10442                         switch_identity $num false || identity_old[$num]=$?
10443                 fi
10444         done
10445 }
10446 run_test 103a "acl test"
10447
10448 test_103b() {
10449         declare -a pids
10450         local U
10451
10452         for U in {0..511}; do
10453                 {
10454                 local O=$(printf "%04o" $U)
10455
10456                 umask $(printf "%04o" $((511 ^ $O)))
10457                 $LFS setstripe -c 1 $DIR/$tfile.s$O
10458                 local S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.s$O))
10459
10460                 (( $S == ($O & 0666) )) ||
10461                         error "lfs setstripe $DIR/$tfile.s$O '$S' != '$O'"
10462
10463                 $LFS setstripe -E16M -c 1 -E1G -S4M $DIR/$tfile.p$O
10464                 S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.p$O))
10465                 (( $S == ($O & 0666) )) ||
10466                         error "lfs setstripe -E $DIR/$tfile.p$O '$S' != '$O'"
10467
10468                 $LFS setstripe -N2 -c 1 $DIR/$tfile.m$O
10469                 S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.m$O))
10470                 (( $S == ($O & 0666) )) ||
10471                         error "lfs setstripe -N2 $DIR/$tfile.m$O '$S' != '$O'"
10472                 rm -f $DIR/$tfile.[smp]$0
10473                 } &
10474                 local pid=$!
10475
10476                 # limit the concurrently running threads to 64. LU-11878
10477                 local idx=$((U % 64))
10478                 [ -z "${pids[idx]}" ] || wait ${pids[idx]}
10479                 pids[idx]=$pid
10480         done
10481         wait
10482 }
10483 run_test 103b "umask lfs setstripe"
10484
10485 test_103c() {
10486         mkdir -p $DIR/$tdir
10487         cp -rp $DIR/$tdir $DIR/$tdir.bak
10488
10489         [ -n "$(getfattr -d -m. $DIR/$tdir | grep posix_acl_default)" ] &&
10490                 error "$DIR/$tdir shouldn't contain default ACL"
10491         [ -n "$(getfattr -d -m. $DIR/$tdir.bak | grep posix_acl_default)" ] &&
10492                 error "$DIR/$tdir.bak shouldn't contain default ACL"
10493         true
10494 }
10495 run_test 103c "'cp -rp' won't set empty acl"
10496
10497 test_104a() {
10498         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10499
10500         touch $DIR/$tfile
10501         lfs df || error "lfs df failed"
10502         lfs df -ih || error "lfs df -ih failed"
10503         lfs df -h $DIR || error "lfs df -h $DIR failed"
10504         lfs df -i $DIR || error "lfs df -i $DIR failed"
10505         lfs df $DIR/$tfile || error "lfs df $DIR/$tfile failed"
10506         lfs df -ih $DIR/$tfile || error "lfs df -ih $DIR/$tfile failed"
10507
10508         local OSC=$(lctl dl | grep OST0000-osc-[^M] | awk '{ print $4 }')
10509         lctl --device %$OSC deactivate
10510         lfs df || error "lfs df with deactivated OSC failed"
10511         lctl --device %$OSC activate
10512         # wait the osc back to normal
10513         wait_osc_import_ready client ost
10514
10515         lfs df || error "lfs df with reactivated OSC failed"
10516         rm -f $DIR/$tfile
10517 }
10518 run_test 104a "lfs df [-ih] [path] test ========================="
10519
10520 test_104b() {
10521         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10522         [ $RUNAS_ID -eq $UID ] &&
10523                 skip_env "RUNAS_ID = UID = $UID -- skipping"
10524
10525         denied_cnt=$(($($RUNAS $LFS check servers 2>&1 |
10526                         grep "Permission denied" | wc -l)))
10527         if [ $denied_cnt -ne 0 ]; then
10528                 error "lfs check servers test failed"
10529         fi
10530 }
10531 run_test 104b "$RUNAS lfs check servers test ===================="
10532
10533 test_105a() {
10534         # doesn't work on 2.4 kernels
10535         touch $DIR/$tfile
10536         if $(flock_is_enabled); then
10537                 flocks_test 1 on -f $DIR/$tfile || error "fail flock on"
10538         else
10539                 flocks_test 1 off -f $DIR/$tfile || error "fail flock off"
10540         fi
10541         rm -f $DIR/$tfile
10542 }
10543 run_test 105a "flock when mounted without -o flock test ========"
10544
10545 test_105b() {
10546         touch $DIR/$tfile
10547         if $(flock_is_enabled); then
10548                 flocks_test 1 on -c $DIR/$tfile || error "fail flock on"
10549         else
10550                 flocks_test 1 off -c $DIR/$tfile || error "fail flock off"
10551         fi
10552         rm -f $DIR/$tfile
10553 }
10554 run_test 105b "fcntl when mounted without -o flock test ========"
10555
10556 test_105c() {
10557         touch $DIR/$tfile
10558         if $(flock_is_enabled); then
10559                 flocks_test 1 on -l $DIR/$tfile || error "fail flock on"
10560         else
10561                 flocks_test 1 off -l $DIR/$tfile || error "fail flock off"
10562         fi
10563         rm -f $DIR/$tfile
10564 }
10565 run_test 105c "lockf when mounted without -o flock test"
10566
10567 test_105d() { # bug 15924
10568         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10569
10570         test_mkdir $DIR/$tdir
10571         flock_is_enabled || skip_env "mount w/o flock enabled"
10572         #define OBD_FAIL_LDLM_CP_CB_WAIT  0x315
10573         $LCTL set_param fail_loc=0x80000315
10574         flocks_test 2 $DIR/$tdir
10575 }
10576 run_test 105d "flock race (should not freeze) ========"
10577
10578 test_105e() { # bug 22660 && 22040
10579         flock_is_enabled || skip_env "mount w/o flock enabled"
10580
10581         touch $DIR/$tfile
10582         flocks_test 3 $DIR/$tfile
10583 }
10584 run_test 105e "Two conflicting flocks from same process"
10585
10586 test_106() { #bug 10921
10587         test_mkdir $DIR/$tdir
10588         $DIR/$tdir && error "exec $DIR/$tdir succeeded"
10589         chmod 777 $DIR/$tdir || error "chmod $DIR/$tdir failed"
10590 }
10591 run_test 106 "attempt exec of dir followed by chown of that dir"
10592
10593 test_107() {
10594         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10595
10596         CDIR=`pwd`
10597         local file=core
10598
10599         cd $DIR
10600         rm -f $file
10601
10602         local save_pattern=$(sysctl -n kernel.core_pattern)
10603         local save_uses_pid=$(sysctl -n kernel.core_uses_pid)
10604         sysctl -w kernel.core_pattern=$file
10605         sysctl -w kernel.core_uses_pid=0
10606
10607         ulimit -c unlimited
10608         sleep 60 &
10609         SLEEPPID=$!
10610
10611         sleep 1
10612
10613         kill -s 11 $SLEEPPID
10614         wait $SLEEPPID
10615         if [ -e $file ]; then
10616                 size=`stat -c%s $file`
10617                 [ $size -eq 0 ] && error "Fail to create core file $file"
10618         else
10619                 error "Fail to create core file $file"
10620         fi
10621         rm -f $file
10622         sysctl -w kernel.core_pattern=$save_pattern
10623         sysctl -w kernel.core_uses_pid=$save_uses_pid
10624         cd $CDIR
10625 }
10626 run_test 107 "Coredump on SIG"
10627
10628 test_110() {
10629         test_mkdir $DIR/$tdir
10630         test_mkdir $DIR/$tdir/$(str_repeat 'a' 255)
10631         $LFS mkdir -c $MDSCOUNT $DIR/$tdir/$(str_repeat 'b' 256) &&
10632                 error "mkdir with 256 char should fail, but did not"
10633         touch $DIR/$tdir/$(str_repeat 'x' 255) ||
10634                 error "create with 255 char failed"
10635         touch $DIR/$tdir/$(str_repeat 'y' 256) &&
10636                 error "create with 256 char should fail, but did not"
10637
10638         ls -l $DIR/$tdir
10639         rm -rf $DIR/$tdir
10640 }
10641 run_test 110 "filename length checking"
10642
10643 #
10644 # Purpose: To verify dynamic thread (OSS) creation.
10645 #
10646 test_115() {
10647         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10648         remote_ost_nodsh && skip "remote OST with nodsh"
10649
10650         # Lustre does not stop service threads once they are started.
10651         # Reset number of running threads to default.
10652         stopall
10653         setupall
10654
10655         local OSTIO_pre
10656         local save_params="$TMP/sanity-$TESTNAME.parameters"
10657
10658         # Get ll_ost_io count before I/O
10659         OSTIO_pre=$(do_facet ost1 \
10660                 "$LCTL get_param ost.OSS.ost_io.threads_started | cut -d= -f2")
10661         # Exit if lustre is not running (ll_ost_io not running).
10662         [ -z "$OSTIO_pre" ] && error "no OSS threads"
10663
10664         echo "Starting with $OSTIO_pre threads"
10665         local thread_max=$((OSTIO_pre * 2))
10666         local rpc_in_flight=$((thread_max * 2))
10667         # Number of I/O Process proposed to be started.
10668         local nfiles
10669         local facets=$(get_facets OST)
10670
10671         save_lustre_params client "osc.*OST*.max_rpcs_in_flight" > $save_params
10672         save_lustre_params $facets "ost.OSS.ost_io.threads_max" >> $save_params
10673
10674         # Set in_flight to $rpc_in_flight
10675         $LCTL set_param osc.*OST*.max_rpcs_in_flight=$rpc_in_flight ||
10676                 error "Failed to set max_rpcs_in_flight to $rpc_in_flight"
10677         nfiles=${rpc_in_flight}
10678         # Set ost thread_max to $thread_max
10679         do_facet ost1 "$LCTL set_param ost.OSS.ost_io.threads_max=$thread_max"
10680
10681         # 5 Minutes should be sufficient for max number of OSS
10682         # threads(thread_max) to be created.
10683         local timeout=300
10684
10685         # Start I/O.
10686         local WTL=${WTL:-"$LUSTRE/tests/write_time_limit"}
10687         test_mkdir $DIR/$tdir
10688         for i in $(seq $nfiles); do
10689                 local file=$DIR/$tdir/${tfile}-$i
10690                 $LFS setstripe -c -1 -i 0 $file
10691                 ($WTL $file $timeout)&
10692         done
10693
10694         # I/O Started - Wait for thread_started to reach thread_max or report
10695         # error if thread_started is more than thread_max.
10696         echo "Waiting for thread_started to reach thread_max"
10697         local thread_started=0
10698         local end_time=$((SECONDS + timeout))
10699
10700         while [ $SECONDS -le $end_time ] ; do
10701                 echo -n "."
10702                 # Get ost i/o thread_started count.
10703                 thread_started=$(do_facet ost1 \
10704                         "$LCTL get_param \
10705                         ost.OSS.ost_io.threads_started | cut -d= -f2")
10706                 # Break out if thread_started is equal/greater than thread_max
10707                 if [[ $thread_started -ge $thread_max ]]; then
10708                         echo ll_ost_io thread_started $thread_started, \
10709                                 equal/greater than thread_max $thread_max
10710                         break
10711                 fi
10712                 sleep 1
10713         done
10714
10715         # Cleanup - We have the numbers, Kill i/o jobs if running.
10716         jobcount=($(jobs -p))
10717         for i in $(seq 0 $((${#jobcount[@]}-1)))
10718         do
10719                 kill -9 ${jobcount[$i]}
10720                 if [ $? -ne 0 ] ; then
10721                         echo Warning: \
10722                         Failed to Kill \'WTL\(I/O\)\' with pid ${jobcount[$i]}
10723                 fi
10724         done
10725
10726         # Cleanup files left by WTL binary.
10727         for i in $(seq $nfiles); do
10728                 local file=$DIR/$tdir/${tfile}-$i
10729                 rm -rf $file
10730                 if [ $? -ne 0 ] ; then
10731                         echo "Warning: Failed to delete file $file"
10732                 fi
10733         done
10734
10735         restore_lustre_params <$save_params
10736         rm -f $save_params || echo "Warning: delete file '$save_params' failed"
10737
10738         # Error out if no new thread has started or Thread started is greater
10739         # than thread max.
10740         if [[ $thread_started -le $OSTIO_pre ||
10741                         $thread_started -gt $thread_max ]]; then
10742                 error "ll_ost_io: thread_started $thread_started" \
10743                       "OSTIO_pre $OSTIO_pre, thread_max $thread_max." \
10744                       "No new thread started or thread started greater " \
10745                       "than thread_max."
10746         fi
10747 }
10748 run_test 115 "verify dynamic thread creation===================="
10749
10750 free_min_max () {
10751         wait_delete_completed
10752         AVAIL=($(lctl get_param -n osc.*[oO][sS][cC]-[^M]*.kbytesavail))
10753         echo "OST kbytes available: ${AVAIL[@]}"
10754         MAXV=${AVAIL[0]}
10755         MAXI=0
10756         MINV=${AVAIL[0]}
10757         MINI=0
10758         for ((i = 0; i < ${#AVAIL[@]}; i++)); do
10759                 #echo OST $i: ${AVAIL[i]}kb
10760                 if [[ ${AVAIL[i]} -gt $MAXV ]]; then
10761                         MAXV=${AVAIL[i]}
10762                         MAXI=$i
10763                 fi
10764                 if [[ ${AVAIL[i]} -lt $MINV ]]; then
10765                         MINV=${AVAIL[i]}
10766                         MINI=$i
10767                 fi
10768         done
10769         echo "Min free space: OST $MINI: $MINV"
10770         echo "Max free space: OST $MAXI: $MAXV"
10771 }
10772
10773 test_116a() { # was previously test_116()
10774         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10775         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
10776         remote_mds_nodsh && skip "remote MDS with nodsh"
10777
10778         echo -n "Free space priority "
10779         do_facet $SINGLEMDS lctl get_param -n lo[vd].*-mdtlov.qos_prio_free |
10780                 head -n1
10781         declare -a AVAIL
10782         free_min_max
10783
10784         [ $MINV -eq 0 ] && skip "no free space in OST$MINI, skip"
10785         [ $MINV -gt 10000000 ] && skip "too much free space in OST$MINI, skip"
10786         trap simple_cleanup_common EXIT
10787
10788         # Check if we need to generate uneven OSTs
10789         test_mkdir -p $DIR/$tdir/OST${MINI}
10790         local FILL=$((MINV / 4))
10791         local DIFF=$((MAXV - MINV))
10792         local DIFF2=$((DIFF * 100 / MINV))
10793
10794         local threshold=$(do_facet $SINGLEMDS \
10795                 lctl get_param -n *.*MDT0000-mdtlov.qos_threshold_rr | head -n1)
10796         threshold=${threshold%%%}
10797         echo -n "Check for uneven OSTs: "
10798         echo -n "diff=${DIFF}KB (${DIFF2}%) must be > ${threshold}% ..."
10799
10800         if [[ $DIFF2 -gt $threshold ]]; then
10801                 echo "ok"
10802                 echo "Don't need to fill OST$MINI"
10803         else
10804                 # generate uneven OSTs. Write 2% over the QOS threshold value
10805                 echo "no"
10806                 DIFF=$((threshold - DIFF2 + 2))
10807                 DIFF2=$((MINV * DIFF / 100))
10808                 echo "Fill $DIFF% remaining space in OST$MINI with ${DIFF2}KB"
10809                 $LFS setstripe -i $MINI -c 1 $DIR/$tdir/OST${MINI} ||
10810                         error "setstripe failed"
10811                 DIFF=$((DIFF2 / 2048))
10812                 i=0
10813                 while [ $i -lt $DIFF ]; do
10814                         i=$((i + 1))
10815                         dd if=/dev/zero of=$DIR/$tdir/OST${MINI}/$tfile-$i \
10816                                 bs=2M count=1 2>/dev/null
10817                         echo -n .
10818                 done
10819                 echo .
10820                 sync
10821                 sleep_maxage
10822                 free_min_max
10823         fi
10824
10825         DIFF=$((MAXV - MINV))
10826         DIFF2=$((DIFF * 100 / MINV))
10827         echo -n "diff=$DIFF=$DIFF2% must be > $threshold% for QOS mode..."
10828         if [ $DIFF2 -gt $threshold ]; then
10829                 echo "ok"
10830         else
10831                 echo "failed - QOS mode won't be used"
10832                 simple_cleanup_common
10833                 skip "QOS imbalance criteria not met"
10834         fi
10835
10836         MINI1=$MINI
10837         MINV1=$MINV
10838         MAXI1=$MAXI
10839         MAXV1=$MAXV
10840
10841         # now fill using QOS
10842         $LFS setstripe -c 1 $DIR/$tdir
10843         FILL=$((FILL / 200))
10844         if [ $FILL -gt 600 ]; then
10845                 FILL=600
10846         fi
10847         echo "writing $FILL files to QOS-assigned OSTs"
10848         i=0
10849         while [ $i -lt $FILL ]; do
10850                 i=$((i + 1))
10851                 dd if=/dev/zero of=$DIR/$tdir/$tfile-$i bs=200k \
10852                         count=1 2>/dev/null
10853                 echo -n .
10854         done
10855         echo "wrote $i 200k files"
10856         sync
10857         sleep_maxage
10858
10859         echo "Note: free space may not be updated, so measurements might be off"
10860         free_min_max
10861         DIFF2=$((MAXV - MINV))
10862         echo "free space delta: orig $DIFF final $DIFF2"
10863         [ $DIFF2 -gt $DIFF ] && echo "delta got worse!"
10864         DIFF=$((MINV1 - ${AVAIL[$MINI1]}))
10865         echo "Wrote ${DIFF}KB to smaller OST $MINI1"
10866         DIFF2=$((MAXV1 - ${AVAIL[$MAXI1]}))
10867         echo "Wrote ${DIFF2}KB to larger OST $MAXI1"
10868         if [[ $DIFF -gt 0 ]]; then
10869                 FILL=$((DIFF2 * 100 / DIFF - 100))
10870                 echo "Wrote ${FILL}% more data to larger OST $MAXI1"
10871         fi
10872
10873         # Figure out which files were written where
10874         UUID=$(lctl get_param -n lov.${FSNAME}-clilov-*.target_obd |
10875                awk '/'$MINI1': / {print $2; exit}')
10876         echo $UUID
10877         MINC=$($LFS getstripe --ost $UUID $DIR/$tdir | grep $DIR | wc -l)
10878         echo "$MINC files created on smaller OST $MINI1"
10879         UUID=$(lctl get_param -n lov.${FSNAME}-clilov-*.target_obd |
10880                awk '/'$MAXI1': / {print $2; exit}')
10881         echo $UUID
10882         MAXC=$($LFS getstripe --ost $UUID $DIR/$tdir | grep $DIR | wc -l)
10883         echo "$MAXC files created on larger OST $MAXI1"
10884         if [[ $MINC -gt 0 ]]; then
10885                 FILL=$((MAXC * 100 / MINC - 100))
10886                 echo "Wrote ${FILL}% more files to larger OST $MAXI1"
10887         fi
10888         [[ $MAXC -gt $MINC ]] ||
10889                 error_ignore LU-9 "stripe QOS didn't balance free space"
10890         simple_cleanup_common
10891 }
10892 run_test 116a "stripe QOS: free space balance ==================="
10893
10894 test_116b() { # LU-2093
10895         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10896         remote_mds_nodsh && skip "remote MDS with nodsh"
10897
10898 #define OBD_FAIL_MDS_OSC_CREATE_FAIL     0x147
10899         local old_rr=$(do_facet $SINGLEMDS lctl get_param -n \
10900                        lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr | head -1)
10901         [ -z "$old_rr" ] && skip "no QOS"
10902         do_facet $SINGLEMDS lctl set_param \
10903                 lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr=0
10904         mkdir -p $DIR/$tdir
10905         do_facet $SINGLEMDS lctl set_param fail_loc=0x147
10906         createmany -o $DIR/$tdir/f- 20 || error "can't create"
10907         do_facet $SINGLEMDS lctl set_param fail_loc=0
10908         rm -rf $DIR/$tdir
10909         do_facet $SINGLEMDS lctl set_param \
10910                 lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr=$old_rr
10911 }
10912 run_test 116b "QoS shouldn't LBUG if not enough OSTs found on the 2nd pass"
10913
10914 test_117() # bug 10891
10915 {
10916         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10917
10918         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
10919         #define OBD_FAIL_OST_SETATTR_CREDITS 0x21e
10920         lctl set_param fail_loc=0x21e
10921         > $DIR/$tfile || error "truncate failed"
10922         lctl set_param fail_loc=0
10923         echo "Truncate succeeded."
10924         rm -f $DIR/$tfile
10925 }
10926 run_test 117 "verify osd extend =========="
10927
10928 NO_SLOW_RESENDCOUNT=4
10929 export OLD_RESENDCOUNT=""
10930 set_resend_count () {
10931         local PROC_RESENDCOUNT="osc.${FSNAME}-OST*-osc-*.resend_count"
10932         OLD_RESENDCOUNT=$(lctl get_param -n $PROC_RESENDCOUNT | head -n1)
10933         lctl set_param -n $PROC_RESENDCOUNT $1
10934         echo resend_count is set to $(lctl get_param -n $PROC_RESENDCOUNT)
10935 }
10936
10937 # for reduce test_118* time (b=14842)
10938 [ "$SLOW" = "no" ] && set_resend_count $NO_SLOW_RESENDCOUNT
10939
10940 # Reset async IO behavior after error case
10941 reset_async() {
10942         FILE=$DIR/reset_async
10943
10944         # Ensure all OSCs are cleared
10945         $LFS setstripe -c -1 $FILE
10946         dd if=/dev/zero of=$FILE bs=64k count=$OSTCOUNT
10947         sync
10948         rm $FILE
10949 }
10950
10951 test_118a() #bug 11710
10952 {
10953         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10954
10955         reset_async
10956
10957         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
10958         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
10959         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
10960
10961         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
10962                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
10963                 return 1;
10964         fi
10965         rm -f $DIR/$tfile
10966 }
10967 run_test 118a "verify O_SYNC works =========="
10968
10969 test_118b()
10970 {
10971         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10972         remote_ost_nodsh && skip "remote OST with nodsh"
10973
10974         reset_async
10975
10976         #define OBD_FAIL_SRV_ENOENT 0x217
10977         set_nodes_failloc "$(osts_nodes)" 0x217
10978         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
10979         RC=$?
10980         set_nodes_failloc "$(osts_nodes)" 0
10981         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
10982         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
10983                     grep -c writeback)
10984
10985         if [[ $RC -eq 0 ]]; then
10986                 error "Must return error due to dropped pages, rc=$RC"
10987                 return 1;
10988         fi
10989
10990         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
10991                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
10992                 return 1;
10993         fi
10994
10995         echo "Dirty pages not leaked on ENOENT"
10996
10997         # Due to the above error the OSC will issue all RPCs syncronously
10998         # until a subsequent RPC completes successfully without error.
10999         $MULTIOP $DIR/$tfile Ow4096yc
11000         rm -f $DIR/$tfile
11001
11002         return 0
11003 }
11004 run_test 118b "Reclaim dirty pages on fatal error =========="
11005
11006 test_118c()
11007 {
11008         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11009
11010         # for 118c, restore the original resend count, LU-1940
11011         [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] &&
11012                                 set_resend_count $OLD_RESENDCOUNT
11013         remote_ost_nodsh && skip "remote OST with nodsh"
11014
11015         reset_async
11016
11017         #define OBD_FAIL_OST_EROFS               0x216
11018         set_nodes_failloc "$(osts_nodes)" 0x216
11019
11020         # multiop should block due to fsync until pages are written
11021         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
11022         MULTIPID=$!
11023         sleep 1
11024
11025         if [[ `ps h -o comm -p $MULTIPID` != "multiop" ]]; then
11026                 error "Multiop failed to block on fsync, pid=$MULTIPID"
11027         fi
11028
11029         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
11030                     grep -c writeback)
11031         if [[ $WRITEBACK -eq 0 ]]; then
11032                 error "No page in writeback, writeback=$WRITEBACK"
11033         fi
11034
11035         set_nodes_failloc "$(osts_nodes)" 0
11036         wait $MULTIPID
11037         RC=$?
11038         if [[ $RC -ne 0 ]]; then
11039                 error "Multiop fsync failed, rc=$RC"
11040         fi
11041
11042         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
11043         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
11044                     grep -c writeback)
11045         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
11046                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
11047         fi
11048
11049         rm -f $DIR/$tfile
11050         echo "Dirty pages flushed via fsync on EROFS"
11051         return 0
11052 }
11053 run_test 118c "Fsync blocks on EROFS until dirty pages are flushed =========="
11054
11055 # continue to use small resend count to reduce test_118* time (b=14842)
11056 [ "$SLOW" = "no" ] && set_resend_count $NO_SLOW_RESENDCOUNT
11057
11058 test_118d()
11059 {
11060         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11061         remote_ost_nodsh && skip "remote OST with nodsh"
11062
11063         reset_async
11064
11065         #define OBD_FAIL_OST_BRW_PAUSE_BULK
11066         set_nodes_failloc "$(osts_nodes)" 0x214
11067         # multiop should block due to fsync until pages are written
11068         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
11069         MULTIPID=$!
11070         sleep 1
11071
11072         if [[ `ps h -o comm -p $MULTIPID` != "multiop" ]]; then
11073                 error "Multiop failed to block on fsync, pid=$MULTIPID"
11074         fi
11075
11076         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
11077                     grep -c writeback)
11078         if [[ $WRITEBACK -eq 0 ]]; then
11079                 error "No page in writeback, writeback=$WRITEBACK"
11080         fi
11081
11082         wait $MULTIPID || error "Multiop fsync failed, rc=$?"
11083         set_nodes_failloc "$(osts_nodes)" 0
11084
11085         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
11086         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
11087                     grep -c writeback)
11088         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
11089                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
11090         fi
11091
11092         rm -f $DIR/$tfile
11093         echo "Dirty pages gaurenteed flushed via fsync"
11094         return 0
11095 }
11096 run_test 118d "Fsync validation inject a delay of the bulk =========="
11097
11098 test_118f() {
11099         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11100
11101         reset_async
11102
11103         #define OBD_FAIL_OSC_BRW_PREP_REQ2        0x40a
11104         lctl set_param fail_loc=0x8000040a
11105
11106         # Should simulate EINVAL error which is fatal
11107         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
11108         RC=$?
11109         if [[ $RC -eq 0 ]]; then
11110                 error "Must return error due to dropped pages, rc=$RC"
11111         fi
11112
11113         lctl set_param fail_loc=0x0
11114
11115         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
11116         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
11117         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
11118                     grep -c writeback)
11119         if [[ $LOCKED -ne 0 ]]; then
11120                 error "Locked pages remain in cache, locked=$LOCKED"
11121         fi
11122
11123         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
11124                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
11125         fi
11126
11127         rm -f $DIR/$tfile
11128         echo "No pages locked after fsync"
11129
11130         reset_async
11131         return 0
11132 }
11133 run_test 118f "Simulate unrecoverable OSC side error =========="
11134
11135 test_118g() {
11136         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11137
11138         reset_async
11139
11140         #define OBD_FAIL_OSC_BRW_PREP_REQ        0x406
11141         lctl set_param fail_loc=0x406
11142
11143         # simulate local -ENOMEM
11144         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
11145         RC=$?
11146
11147         lctl set_param fail_loc=0
11148         if [[ $RC -eq 0 ]]; then
11149                 error "Must return error due to dropped pages, rc=$RC"
11150         fi
11151
11152         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
11153         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
11154         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
11155                         grep -c writeback)
11156         if [[ $LOCKED -ne 0 ]]; then
11157                 error "Locked pages remain in cache, locked=$LOCKED"
11158         fi
11159
11160         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
11161                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
11162         fi
11163
11164         rm -f $DIR/$tfile
11165         echo "No pages locked after fsync"
11166
11167         reset_async
11168         return 0
11169 }
11170 run_test 118g "Don't stay in wait if we got local -ENOMEM  =========="
11171
11172 test_118h() {
11173         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11174         remote_ost_nodsh && skip "remote OST with nodsh"
11175
11176         reset_async
11177
11178         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
11179         set_nodes_failloc "$(osts_nodes)" 0x20e
11180         # Should simulate ENOMEM error which is recoverable and should be handled by timeout
11181         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
11182         RC=$?
11183
11184         set_nodes_failloc "$(osts_nodes)" 0
11185         if [[ $RC -eq 0 ]]; then
11186                 error "Must return error due to dropped pages, rc=$RC"
11187         fi
11188
11189         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
11190         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
11191         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
11192                     grep -c writeback)
11193         if [[ $LOCKED -ne 0 ]]; then
11194                 error "Locked pages remain in cache, locked=$LOCKED"
11195         fi
11196
11197         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
11198                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
11199         fi
11200
11201         rm -f $DIR/$tfile
11202         echo "No pages locked after fsync"
11203
11204         return 0
11205 }
11206 run_test 118h "Verify timeout in handling recoverables errors  =========="
11207
11208 [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] && set_resend_count $OLD_RESENDCOUNT
11209
11210 test_118i() {
11211         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11212         remote_ost_nodsh && skip "remote OST with nodsh"
11213
11214         reset_async
11215
11216         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
11217         set_nodes_failloc "$(osts_nodes)" 0x20e
11218
11219         # Should simulate ENOMEM error which is recoverable and should be handled by timeout
11220         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
11221         PID=$!
11222         sleep 5
11223         set_nodes_failloc "$(osts_nodes)" 0
11224
11225         wait $PID
11226         RC=$?
11227         if [[ $RC -ne 0 ]]; then
11228                 error "got error, but should be not, rc=$RC"
11229         fi
11230
11231         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
11232         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
11233         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
11234         if [[ $LOCKED -ne 0 ]]; then
11235                 error "Locked pages remain in cache, locked=$LOCKED"
11236         fi
11237
11238         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
11239                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
11240         fi
11241
11242         rm -f $DIR/$tfile
11243         echo "No pages locked after fsync"
11244
11245         return 0
11246 }
11247 run_test 118i "Fix error before timeout in recoverable error  =========="
11248
11249 [ "$SLOW" = "no" ] && set_resend_count 4
11250
11251 test_118j() {
11252         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11253         remote_ost_nodsh && skip "remote OST with nodsh"
11254
11255         reset_async
11256
11257         #define OBD_FAIL_OST_BRW_WRITE_BULK2     0x220
11258         set_nodes_failloc "$(osts_nodes)" 0x220
11259
11260         # return -EIO from OST
11261         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
11262         RC=$?
11263         set_nodes_failloc "$(osts_nodes)" 0x0
11264         if [[ $RC -eq 0 ]]; then
11265                 error "Must return error due to dropped pages, rc=$RC"
11266         fi
11267
11268         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
11269         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
11270         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
11271         if [[ $LOCKED -ne 0 ]]; then
11272                 error "Locked pages remain in cache, locked=$LOCKED"
11273         fi
11274
11275         # in recoverable error on OST we want resend and stay until it finished
11276         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
11277                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
11278         fi
11279
11280         rm -f $DIR/$tfile
11281         echo "No pages locked after fsync"
11282
11283         return 0
11284 }
11285 run_test 118j "Simulate unrecoverable OST side error =========="
11286
11287 test_118k()
11288 {
11289         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11290         remote_ost_nodsh && skip "remote OSTs with nodsh"
11291
11292         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
11293         set_nodes_failloc "$(osts_nodes)" 0x20e
11294         test_mkdir $DIR/$tdir
11295
11296         for ((i=0;i<10;i++)); do
11297                 (dd if=/dev/zero of=$DIR/$tdir/$tfile-$i bs=1M count=10 || \
11298                         error "dd to $DIR/$tdir/$tfile-$i failed" )&
11299                 SLEEPPID=$!
11300                 sleep 0.500s
11301                 kill $SLEEPPID
11302                 wait $SLEEPPID
11303         done
11304
11305         set_nodes_failloc "$(osts_nodes)" 0
11306         rm -rf $DIR/$tdir
11307 }
11308 run_test 118k "bio alloc -ENOMEM and IO TERM handling ========="
11309
11310 test_118l() # LU-646
11311 {
11312         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11313
11314         test_mkdir $DIR/$tdir
11315         $MULTIOP $DIR/$tdir Dy || error "fsync dir failed"
11316         rm -rf $DIR/$tdir
11317 }
11318 run_test 118l "fsync dir"
11319
11320 test_118m() # LU-3066
11321 {
11322         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11323
11324         test_mkdir $DIR/$tdir
11325         $MULTIOP $DIR/$tdir DY || error "fdatasync dir failed"
11326         rm -rf $DIR/$tdir
11327 }
11328 run_test 118m "fdatasync dir ========="
11329
11330 [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] && set_resend_count $OLD_RESENDCOUNT
11331
11332 test_118n()
11333 {
11334         local begin
11335         local end
11336
11337         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11338         remote_ost_nodsh && skip "remote OSTs with nodsh"
11339
11340         # Sleep to avoid a cached response.
11341         #define OBD_STATFS_CACHE_SECONDS 1
11342         sleep 2
11343
11344         # Inject a 10 second delay in the OST_STATFS handler.
11345         #define OBD_FAIL_OST_STATFS_DELAY 0x242
11346         set_nodes_failloc "$(osts_nodes)" 0x242
11347
11348         begin=$SECONDS
11349         stat --file-system $MOUNT > /dev/null
11350         end=$SECONDS
11351
11352         set_nodes_failloc "$(osts_nodes)" 0
11353
11354         if ((end - begin > 20)); then
11355             error "statfs took $((end - begin)) seconds, expected 10"
11356         fi
11357 }
11358 run_test 118n "statfs() sends OST_STATFS requests in parallel"
11359
11360 test_119a() # bug 11737
11361 {
11362         BSIZE=$((512 * 1024))
11363         directio write $DIR/$tfile 0 1 $BSIZE
11364         # We ask to read two blocks, which is more than a file size.
11365         # directio will indicate an error when requested and actual
11366         # sizes aren't equeal (a normal situation in this case) and
11367         # print actual read amount.
11368         NOB=`directio read $DIR/$tfile 0 2 $BSIZE | awk '/error/ {print $6}'`
11369         if [ "$NOB" != "$BSIZE" ]; then
11370                 error "read $NOB bytes instead of $BSIZE"
11371         fi
11372         rm -f $DIR/$tfile
11373 }
11374 run_test 119a "Short directIO read must return actual read amount"
11375
11376 test_119b() # bug 11737
11377 {
11378         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11379
11380         $LFS setstripe -c 2 $DIR/$tfile || error "setstripe failed"
11381         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=1 || error "dd failed"
11382         sync
11383         $MULTIOP $DIR/$tfile oO_RDONLY:O_DIRECT:r$((2048 * 1024)) ||
11384                 error "direct read failed"
11385         rm -f $DIR/$tfile
11386 }
11387 run_test 119b "Sparse directIO read must return actual read amount"
11388
11389 test_119c() # bug 13099
11390 {
11391         BSIZE=1048576
11392         directio write $DIR/$tfile 3 1 $BSIZE || error "direct write failed"
11393         directio readhole $DIR/$tfile 0 2 $BSIZE || error "reading hole failed"
11394         rm -f $DIR/$tfile
11395 }
11396 run_test 119c "Testing for direct read hitting hole"
11397
11398 test_119d() # bug 15950
11399 {
11400         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11401
11402         MAX_RPCS_IN_FLIGHT=`$LCTL get_param -n osc.*OST0000-osc-[^mM]*.max_rpcs_in_flight`
11403         $LCTL set_param -n osc.*OST0000-osc-[^mM]*.max_rpcs_in_flight 1
11404         BSIZE=1048576
11405         $LFS setstripe $DIR/$tfile -i 0 -c 1 || error "setstripe failed"
11406         $DIRECTIO write $DIR/$tfile 0 1 $BSIZE || error "first directio failed"
11407         #define OBD_FAIL_OSC_DIO_PAUSE           0x40d
11408         lctl set_param fail_loc=0x40d
11409         $DIRECTIO write $DIR/$tfile 1 4 $BSIZE &
11410         pid_dio=$!
11411         sleep 1
11412         cat $DIR/$tfile > /dev/null &
11413         lctl set_param fail_loc=0
11414         pid_reads=$!
11415         wait $pid_dio
11416         log "the DIO writes have completed, now wait for the reads (should not block very long)"
11417         sleep 2
11418         [ -n "`ps h -p $pid_reads -o comm`" ] && \
11419         error "the read rpcs have not completed in 2s"
11420         rm -f $DIR/$tfile
11421         $LCTL set_param -n osc.*OST0000-osc-[^mM]*.max_rpcs_in_flight $MAX_RPCS_IN_FLIGHT
11422 }
11423 run_test 119d "The DIO path should try to send a new rpc once one is completed"
11424
11425 test_120a() {
11426         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11427         remote_mds_nodsh && skip "remote MDS with nodsh"
11428         test_mkdir -i0 -c1 $DIR/$tdir
11429         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
11430                 skip_env "no early lock cancel on server"
11431
11432         lru_resize_disable mdc
11433         lru_resize_disable osc
11434         cancel_lru_locks mdc
11435         # asynchronous object destroy at MDT could cause bl ast to client
11436         cancel_lru_locks osc
11437
11438         stat $DIR/$tdir > /dev/null
11439         can1=$(do_facet mds1 \
11440                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11441                awk '/ldlm_cancel/ {print $2}')
11442         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11443                awk '/ldlm_bl_callback/ {print $2}')
11444         test_mkdir -i0 -c1 $DIR/$tdir/d1
11445         can2=$(do_facet mds1 \
11446                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11447                awk '/ldlm_cancel/ {print $2}')
11448         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11449                awk '/ldlm_bl_callback/ {print $2}')
11450         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
11451         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
11452         lru_resize_enable mdc
11453         lru_resize_enable osc
11454 }
11455 run_test 120a "Early Lock Cancel: mkdir test"
11456
11457 test_120b() {
11458         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11459         remote_mds_nodsh && skip "remote MDS with nodsh"
11460         test_mkdir $DIR/$tdir
11461         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
11462                 skip_env "no early lock cancel on server"
11463
11464         lru_resize_disable mdc
11465         lru_resize_disable osc
11466         cancel_lru_locks mdc
11467         stat $DIR/$tdir > /dev/null
11468         can1=$(do_facet $SINGLEMDS \
11469                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11470                awk '/ldlm_cancel/ {print $2}')
11471         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11472                awk '/ldlm_bl_callback/ {print $2}')
11473         touch $DIR/$tdir/f1
11474         can2=$(do_facet $SINGLEMDS \
11475                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11476                awk '/ldlm_cancel/ {print $2}')
11477         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11478                awk '/ldlm_bl_callback/ {print $2}')
11479         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
11480         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
11481         lru_resize_enable mdc
11482         lru_resize_enable osc
11483 }
11484 run_test 120b "Early Lock Cancel: create test"
11485
11486 test_120c() {
11487         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11488         remote_mds_nodsh && skip "remote MDS with nodsh"
11489         test_mkdir -i0 -c1 $DIR/$tdir
11490         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
11491                 skip "no early lock cancel on server"
11492
11493         lru_resize_disable mdc
11494         lru_resize_disable osc
11495         test_mkdir -i0 -c1 $DIR/$tdir/d1
11496         test_mkdir -i0 -c1 $DIR/$tdir/d2
11497         touch $DIR/$tdir/d1/f1
11498         cancel_lru_locks mdc
11499         stat $DIR/$tdir/d1 $DIR/$tdir/d2 $DIR/$tdir/d1/f1 > /dev/null
11500         can1=$(do_facet mds1 \
11501                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11502                awk '/ldlm_cancel/ {print $2}')
11503         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11504                awk '/ldlm_bl_callback/ {print $2}')
11505         ln $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2
11506         can2=$(do_facet mds1 \
11507                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11508                awk '/ldlm_cancel/ {print $2}')
11509         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11510                awk '/ldlm_bl_callback/ {print $2}')
11511         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
11512         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
11513         lru_resize_enable mdc
11514         lru_resize_enable osc
11515 }
11516 run_test 120c "Early Lock Cancel: link test"
11517
11518 test_120d() {
11519         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11520         remote_mds_nodsh && skip "remote MDS with nodsh"
11521         test_mkdir -i0 -c1 $DIR/$tdir
11522         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
11523                 skip_env "no early lock cancel on server"
11524
11525         lru_resize_disable mdc
11526         lru_resize_disable osc
11527         touch $DIR/$tdir
11528         cancel_lru_locks mdc
11529         stat $DIR/$tdir > /dev/null
11530         can1=$(do_facet mds1 \
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         chmod a+x $DIR/$tdir
11536         can2=$(do_facet mds1 \
11537                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11538                awk '/ldlm_cancel/ {print $2}')
11539         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11540                awk '/ldlm_bl_callback/ {print $2}')
11541         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
11542         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
11543         lru_resize_enable mdc
11544         lru_resize_enable osc
11545 }
11546 run_test 120d "Early Lock Cancel: setattr test"
11547
11548 test_120e() {
11549         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11550         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
11551                 skip_env "no early lock cancel on server"
11552         remote_mds_nodsh && skip "remote MDS with nodsh"
11553
11554         local dlmtrace_set=false
11555
11556         test_mkdir -i0 -c1 $DIR/$tdir
11557         lru_resize_disable mdc
11558         lru_resize_disable osc
11559         ! $LCTL get_param debug | grep -q dlmtrace &&
11560                 $LCTL set_param debug=+dlmtrace && dlmtrace_set=true
11561         dd if=/dev/zero of=$DIR/$tdir/f1 count=1
11562         cancel_lru_locks mdc
11563         cancel_lru_locks osc
11564         dd if=$DIR/$tdir/f1 of=/dev/null
11565         stat $DIR/$tdir $DIR/$tdir/f1 > /dev/null
11566         # XXX client can not do early lock cancel of OST lock
11567         # during unlink (LU-4206), so cancel osc lock now.
11568         sleep 2
11569         cancel_lru_locks osc
11570         can1=$(do_facet mds1 \
11571                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11572                awk '/ldlm_cancel/ {print $2}')
11573         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11574                awk '/ldlm_bl_callback/ {print $2}')
11575         unlink $DIR/$tdir/f1
11576         sleep 5
11577         can2=$(do_facet mds1 \
11578                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11579                awk '/ldlm_cancel/ {print $2}')
11580         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11581                awk '/ldlm_bl_callback/ {print $2}')
11582         [ $can1 -ne $can2 ] && error "$((can2 - can1)) cancel RPC occured" &&
11583                 $LCTL dk $TMP/cancel.debug.txt
11584         [ $blk1 -ne $blk2 ] && error "$((blk2 - blk1)) blocking RPC occured" &&
11585                 $LCTL dk $TMP/blocking.debug.txt
11586         $dlmtrace_set && $LCTL set_param debug=-dlmtrace
11587         lru_resize_enable mdc
11588         lru_resize_enable osc
11589 }
11590 run_test 120e "Early Lock Cancel: unlink test"
11591
11592 test_120f() {
11593         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11594         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
11595                 skip_env "no early lock cancel on server"
11596         remote_mds_nodsh && skip "remote MDS with nodsh"
11597
11598         test_mkdir -i0 -c1 $DIR/$tdir
11599         lru_resize_disable mdc
11600         lru_resize_disable osc
11601         test_mkdir -i0 -c1 $DIR/$tdir/d1
11602         test_mkdir -i0 -c1 $DIR/$tdir/d2
11603         dd if=/dev/zero of=$DIR/$tdir/d1/f1 count=1
11604         dd if=/dev/zero of=$DIR/$tdir/d2/f2 count=1
11605         cancel_lru_locks mdc
11606         cancel_lru_locks osc
11607         dd if=$DIR/$tdir/d1/f1 of=/dev/null
11608         dd if=$DIR/$tdir/d2/f2 of=/dev/null
11609         stat $DIR/$tdir/d1 $DIR/$tdir/d2 $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2 > /dev/null
11610         # XXX client can not do early lock cancel of OST lock
11611         # during rename (LU-4206), so cancel osc lock now.
11612         sleep 2
11613         cancel_lru_locks osc
11614         can1=$(do_facet mds1 \
11615                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11616                awk '/ldlm_cancel/ {print $2}')
11617         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11618                awk '/ldlm_bl_callback/ {print $2}')
11619         mrename $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2
11620         sleep 5
11621         can2=$(do_facet mds1 \
11622                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11623                awk '/ldlm_cancel/ {print $2}')
11624         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11625                awk '/ldlm_bl_callback/ {print $2}')
11626         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
11627         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
11628         lru_resize_enable mdc
11629         lru_resize_enable osc
11630 }
11631 run_test 120f "Early Lock Cancel: rename test"
11632
11633 test_120g() {
11634         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11635         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
11636                 skip_env "no early lock cancel on server"
11637         remote_mds_nodsh && skip "remote MDS with nodsh"
11638
11639         lru_resize_disable mdc
11640         lru_resize_disable osc
11641         count=10000
11642         echo create $count files
11643         test_mkdir $DIR/$tdir
11644         cancel_lru_locks mdc
11645         cancel_lru_locks osc
11646         t0=$(date +%s)
11647
11648         can0=$(do_facet $SINGLEMDS \
11649                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11650                awk '/ldlm_cancel/ {print $2}')
11651         blk0=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11652                awk '/ldlm_bl_callback/ {print $2}')
11653         createmany -o $DIR/$tdir/f $count
11654         sync
11655         can1=$(do_facet $SINGLEMDS \
11656                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11657                awk '/ldlm_cancel/ {print $2}')
11658         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11659                awk '/ldlm_bl_callback/ {print $2}')
11660         t1=$(date +%s)
11661         echo total: $((can1-can0)) cancels, $((blk1-blk0)) blockings
11662         echo rm $count files
11663         rm -r $DIR/$tdir
11664         sync
11665         can2=$(do_facet $SINGLEMDS \
11666                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
11667                awk '/ldlm_cancel/ {print $2}')
11668         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
11669                awk '/ldlm_bl_callback/ {print $2}')
11670         t2=$(date +%s)
11671         echo total: $count removes in $((t2-t1))
11672         echo total: $((can2-can1)) cancels, $((blk2-blk1)) blockings
11673         sleep 2
11674         # wait for commitment of removal
11675         lru_resize_enable mdc
11676         lru_resize_enable osc
11677 }
11678 run_test 120g "Early Lock Cancel: performance test"
11679
11680 test_121() { #bug #10589
11681         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11682
11683         rm -rf $DIR/$tfile
11684         writes=$(LANG=C dd if=/dev/zero of=$DIR/$tfile count=1 2>&1 | awk -F '+' '/out$/ {print $1}')
11685 #define OBD_FAIL_LDLM_CANCEL_RACE        0x310
11686         lctl set_param fail_loc=0x310
11687         cancel_lru_locks osc > /dev/null
11688         reads=$(LANG=C dd if=$DIR/$tfile of=/dev/null 2>&1 | awk -F '+' '/in$/ {print $1}')
11689         lctl set_param fail_loc=0
11690         [[ $reads -eq $writes ]] ||
11691                 error "read $reads blocks, must be $writes blocks"
11692 }
11693 run_test 121 "read cancel race ========="
11694
11695 test_123a_base() { # was test 123, statahead(bug 11401)
11696         local lsx="$1"
11697
11698         SLOWOK=0
11699         if ! grep -q "processor.*: 1" /proc/cpuinfo; then
11700                 log "testing UP system. Performance may be lower than expected."
11701                 SLOWOK=1
11702         fi
11703
11704         rm -rf $DIR/$tdir
11705         test_mkdir $DIR/$tdir
11706         NUMFREE=$(df -i -P $DIR | tail -n 1 | awk '{ print $4 }')
11707         [[ $NUMFREE -gt 100000 ]] && NUMFREE=100000 || NUMFREE=$((NUMFREE-1000))
11708         MULT=10
11709         for ((i=100, j=0; i<=$NUMFREE; j=$i, i=$((i * MULT)) )); do
11710                 createmany -o $DIR/$tdir/$tfile $j $((i - j))
11711
11712                 max=$(lctl get_param -n llite.*.statahead_max | head -n 1)
11713                 lctl set_param -n llite.*.statahead_max 0
11714                 lctl get_param llite.*.statahead_max
11715                 cancel_lru_locks mdc
11716                 cancel_lru_locks osc
11717                 stime=$(date +%s)
11718                 time $lsx $DIR/$tdir | wc -l
11719                 etime=$(date +%s)
11720                 delta=$((etime - stime))
11721                 log "$lsx $i files without statahead: $delta sec"
11722                 lctl set_param llite.*.statahead_max=$max
11723
11724                 swrong=$(lctl get_param -n llite.*.statahead_stats |
11725                         grep "statahead wrong:" | awk '{print $3}')
11726                 lctl get_param -n llite.*.statahead_max | grep '[0-9]'
11727                 cancel_lru_locks mdc
11728                 cancel_lru_locks osc
11729                 stime=$(date +%s)
11730                 time $lsx $DIR/$tdir | wc -l
11731                 etime=$(date +%s)
11732                 delta_sa=$((etime - stime))
11733                 log "$lsx $i files with statahead: $delta_sa sec"
11734                 lctl get_param -n llite.*.statahead_stats
11735                 ewrong=$(lctl get_param -n llite.*.statahead_stats |
11736                         grep "statahead wrong:" | awk '{print $3}')
11737
11738                 [[ $swrong -lt $ewrong ]] &&
11739                         log "statahead was stopped, maybe too many locks held!"
11740                 [[ $delta -eq 0 || $delta_sa -eq 0 ]] && continue
11741
11742                 if [ $((delta_sa * 100)) -gt $((delta * 105)) -a $delta_sa -gt $((delta + 2)) ]; then
11743                         max=$(lctl get_param -n llite.*.statahead_max |
11744                                 head -n 1)
11745                         lctl set_param -n llite.*.statahead_max 0
11746                         lctl get_param llite.*.statahead_max
11747                         cancel_lru_locks mdc
11748                         cancel_lru_locks osc
11749                         stime=$(date +%s)
11750                         time $lsx $DIR/$tdir | wc -l
11751                         etime=$(date +%s)
11752                         delta=$((etime - stime))
11753                         log "$lsx $i files again without statahead: $delta sec"
11754                         lctl set_param llite.*.statahead_max=$max
11755                         if [ $((delta_sa * 100 > delta * 105 && delta_sa > delta + 2)) ]; then
11756                                 if [  $SLOWOK -eq 0 ]; then
11757                                         error "$lsx $i files is slower with statahead!"
11758                                 else
11759                                         log "$lsx $i files is slower with statahead!"
11760                                 fi
11761                                 break
11762                         fi
11763                 fi
11764
11765                 [ $delta -gt 20 ] && break
11766                 [ $delta -gt 8 ] && MULT=$((50 / delta))
11767                 [ "$SLOW" = "no" -a $delta -gt 5 ] && break
11768         done
11769         log "$lsx done"
11770
11771         stime=$(date +%s)
11772         rm -r $DIR/$tdir
11773         sync
11774         etime=$(date +%s)
11775         delta=$((etime - stime))
11776         log "rm -r $DIR/$tdir/: $delta seconds"
11777         log "rm done"
11778         lctl get_param -n llite.*.statahead_stats
11779 }
11780
11781 test_123aa() {
11782         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11783
11784         test_123a_base "ls -l"
11785 }
11786 run_test 123aa "verify statahead work"
11787
11788 test_123ab() {
11789         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11790
11791         statx_supported || skip_env "Test must be statx() syscall supported"
11792
11793         test_123a_base "$STATX -l"
11794 }
11795 run_test 123ab "verify statahead work by using statx"
11796
11797 test_123ac() {
11798         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11799
11800         statx_supported || skip_env "Test must be statx() syscall supported"
11801
11802         local rpcs_before
11803         local rpcs_after
11804         local agl_before
11805         local agl_after
11806
11807         cancel_lru_locks $OSC
11808         rpcs_before=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
11809         agl_before=$($LCTL get_param -n llite.*.statahead_stats |
11810                 awk '/agl.total:/ {print $3}')
11811         test_123a_base "$STATX -c \"%n %i %A %h %u %g %W %X %Z\" -D"
11812         test_123a_base "$STATX --cached=always -D"
11813         agl_after=$($LCTL get_param -n llite.*.statahead_stats |
11814                 awk '/agl.total:/ {print $3}')
11815         [ $agl_before -eq $agl_after ] ||
11816                 error "Should not trigger AGL thread - $agl_before:$agl_after"
11817         rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
11818         [ $rpcs_after -eq $rpcs_before ] ||
11819                 error "$STATX should not send glimpse RPCs to $OSC"
11820 }
11821 run_test 123ac "verify statahead work by using statx without glimpse RPCs"
11822
11823 test_123b () { # statahead(bug 15027)
11824         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11825
11826         test_mkdir $DIR/$tdir
11827         createmany -o $DIR/$tdir/$tfile-%d 1000
11828
11829         cancel_lru_locks mdc
11830         cancel_lru_locks osc
11831
11832 #define OBD_FAIL_MDC_GETATTR_ENQUEUE     0x803
11833         lctl set_param fail_loc=0x80000803
11834         ls -lR $DIR/$tdir > /dev/null
11835         log "ls done"
11836         lctl set_param fail_loc=0x0
11837         lctl get_param -n llite.*.statahead_stats
11838         rm -r $DIR/$tdir
11839         sync
11840
11841 }
11842 run_test 123b "not panic with network error in statahead enqueue (bug 15027)"
11843
11844 test_123c() {
11845         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
11846
11847         test_mkdir -i 0 -c 1 $DIR/$tdir.0
11848         test_mkdir -i 1 -c 1 $DIR/$tdir.1
11849         touch $DIR/$tdir.1/{1..3}
11850         mv $DIR/$tdir.1/{1..3} $DIR/$tdir.0
11851
11852         remount_client $MOUNT
11853
11854         $MULTIOP $DIR/$tdir.0 Q
11855
11856         # let statahead to complete
11857         ls -l $DIR/$tdir.0 > /dev/null
11858
11859         testid=$(echo $TESTNAME | tr '_' ' ')
11860         dmesg | tac | sed "/$testid/,$ d" | grep "Can not initialize inode" &&
11861                 error "statahead warning" || true
11862 }
11863 run_test 123c "Can not initialize inode warning on DNE statahead"
11864
11865 test_124a() {
11866         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11867         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
11868                 skip_env "no lru resize on server"
11869
11870         local NR=2000
11871
11872         test_mkdir $DIR/$tdir
11873
11874         log "create $NR files at $DIR/$tdir"
11875         createmany -o $DIR/$tdir/f $NR ||
11876                 error "failed to create $NR files in $DIR/$tdir"
11877
11878         cancel_lru_locks mdc
11879         ls -l $DIR/$tdir > /dev/null
11880
11881         local NSDIR=""
11882         local LRU_SIZE=0
11883         for VALUE in $($LCTL get_param ldlm.namespaces.*mdc-*.lru_size); do
11884                 local PARAM=$(echo ${VALUE[0]} | cut -d "=" -f1)
11885                 LRU_SIZE=$($LCTL get_param -n $PARAM)
11886                 if [[ $LRU_SIZE -gt $(default_lru_size) ]]; then
11887                         NSDIR=$(echo $PARAM | cut -d "." -f1-3)
11888                         log "NSDIR=$NSDIR"
11889                         log "NS=$(basename $NSDIR)"
11890                         break
11891                 fi
11892         done
11893
11894         if [[ -z "$NSDIR" || $LRU_SIZE -lt $(default_lru_size) ]]; then
11895                 skip "Not enough cached locks created!"
11896         fi
11897         log "LRU=$LRU_SIZE"
11898
11899         local SLEEP=30
11900
11901         # We know that lru resize allows one client to hold $LIMIT locks
11902         # for 10h. After that locks begin to be killed by client.
11903         local MAX_HRS=10
11904         local LIMIT=$($LCTL get_param -n $NSDIR.pool.limit)
11905         log "LIMIT=$LIMIT"
11906         if [ $LIMIT -lt $LRU_SIZE ]; then
11907                 skip "Limit is too small $LIMIT"
11908         fi
11909
11910         # Make LVF so higher that sleeping for $SLEEP is enough to _start_
11911         # killing locks. Some time was spent for creating locks. This means
11912         # that up to the moment of sleep finish we must have killed some of
11913         # them (10-100 locks). This depends on how fast ther were created.
11914         # Many of them were touched in almost the same moment and thus will
11915         # be killed in groups.
11916         local LVF=$(($MAX_HRS * 60 * 60 / $SLEEP * $LIMIT / $LRU_SIZE * 100))
11917
11918         # Use $LRU_SIZE_B here to take into account real number of locks
11919         # created in the case of CMD, LRU_SIZE_B != $NR in most of cases
11920         local LRU_SIZE_B=$LRU_SIZE
11921         log "LVF=$LVF"
11922         local OLD_LVF=$($LCTL get_param -n $NSDIR.pool.lock_volume_factor)
11923         log "OLD_LVF=$OLD_LVF"
11924         $LCTL set_param -n $NSDIR.pool.lock_volume_factor $LVF
11925
11926         # Let's make sure that we really have some margin. Client checks
11927         # cached locks every 10 sec.
11928         SLEEP=$((SLEEP+20))
11929         log "Sleep ${SLEEP} sec"
11930         local SEC=0
11931         while ((SEC<$SLEEP)); do
11932                 echo -n "..."
11933                 sleep 5
11934                 SEC=$((SEC+5))
11935                 LRU_SIZE=$($LCTL get_param -n $NSDIR/lru_size)
11936                 echo -n "$LRU_SIZE"
11937         done
11938         echo ""
11939         $LCTL set_param -n $NSDIR.pool.lock_volume_factor $OLD_LVF
11940         local LRU_SIZE_A=$($LCTL get_param -n $NSDIR.lru_size)
11941
11942         [[ $LRU_SIZE_B -gt $LRU_SIZE_A ]] || {
11943                 error "No locks dropped in ${SLEEP}s. LRU size: $LRU_SIZE_A"
11944                 unlinkmany $DIR/$tdir/f $NR
11945                 return
11946         }
11947
11948         log "Dropped "$((LRU_SIZE_B-LRU_SIZE_A))" locks in ${SLEEP}s"
11949         log "unlink $NR files at $DIR/$tdir"
11950         unlinkmany $DIR/$tdir/f $NR
11951 }
11952 run_test 124a "lru resize ======================================="
11953
11954 get_max_pool_limit()
11955 {
11956         local limit=$($LCTL get_param \
11957                       -n ldlm.namespaces.*-MDT0000-mdc-*.pool.limit)
11958         local max=0
11959         for l in $limit; do
11960                 if [[ $l -gt $max ]]; then
11961                         max=$l
11962                 fi
11963         done
11964         echo $max
11965 }
11966
11967 test_124b() {
11968         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11969         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
11970                 skip_env "no lru resize on server"
11971
11972         LIMIT=$(get_max_pool_limit)
11973
11974         NR=$(($(default_lru_size)*20))
11975         if [[ $NR -gt $LIMIT ]]; then
11976                 log "Limit lock number by $LIMIT locks"
11977                 NR=$LIMIT
11978         fi
11979
11980         IFree=$(mdsrate_inodes_available)
11981         if [ $IFree -lt $NR ]; then
11982                 log "Limit lock number by $IFree inodes"
11983                 NR=$IFree
11984         fi
11985
11986         lru_resize_disable mdc
11987         test_mkdir -p $DIR/$tdir/disable_lru_resize
11988
11989         createmany -o $DIR/$tdir/disable_lru_resize/f $NR
11990         log "doing ls -la $DIR/$tdir/disable_lru_resize 3 times"
11991         cancel_lru_locks mdc
11992         stime=`date +%s`
11993         PID=""
11994         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
11995         PID="$PID $!"
11996         sleep 2
11997         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
11998         PID="$PID $!"
11999         sleep 2
12000         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
12001         PID="$PID $!"
12002         wait $PID
12003         etime=`date +%s`
12004         nolruresize_delta=$((etime-stime))
12005         log "ls -la time: $nolruresize_delta seconds"
12006         log "lru_size = $(lctl get_param -n ldlm.namespaces.*mdc*.lru_size)"
12007         unlinkmany $DIR/$tdir/disable_lru_resize/f $NR
12008
12009         lru_resize_enable mdc
12010         test_mkdir -p $DIR/$tdir/enable_lru_resize
12011
12012         createmany -o $DIR/$tdir/enable_lru_resize/f $NR
12013         log "doing ls -la $DIR/$tdir/enable_lru_resize 3 times"
12014         cancel_lru_locks mdc
12015         stime=`date +%s`
12016         PID=""
12017         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
12018         PID="$PID $!"
12019         sleep 2
12020         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
12021         PID="$PID $!"
12022         sleep 2
12023         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
12024         PID="$PID $!"
12025         wait $PID
12026         etime=`date +%s`
12027         lruresize_delta=$((etime-stime))
12028         log "ls -la time: $lruresize_delta seconds"
12029         log "lru_size = $(lctl get_param -n ldlm.namespaces.*mdc*.lru_size)"
12030
12031         if [ $lruresize_delta -gt $nolruresize_delta ]; then
12032                 log "ls -la is $(((lruresize_delta - $nolruresize_delta) * 100 / $nolruresize_delta))% slower with lru resize enabled"
12033         elif [ $nolruresize_delta -gt $lruresize_delta ]; then
12034                 log "ls -la is $(((nolruresize_delta - $lruresize_delta) * 100 / $nolruresize_delta))% faster with lru resize enabled"
12035         else
12036                 log "lru resize performs the same with no lru resize"
12037         fi
12038         unlinkmany $DIR/$tdir/enable_lru_resize/f $NR
12039 }
12040 run_test 124b "lru resize (performance test) ======================="
12041
12042 test_124c() {
12043         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12044         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
12045                 skip_env "no lru resize on server"
12046
12047         # cache ununsed locks on client
12048         local nr=100
12049         cancel_lru_locks mdc
12050         test_mkdir $DIR/$tdir
12051         createmany -o $DIR/$tdir/f $nr ||
12052                 error "failed to create $nr files in $DIR/$tdir"
12053         ls -l $DIR/$tdir > /dev/null
12054
12055         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
12056         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
12057         local max_age=$($LCTL get_param -n $nsdir.lru_max_age)
12058         local recalc_p=$($LCTL get_param -n $nsdir.pool.recalc_period)
12059         echo "unused=$unused, max_age=$max_age, recalc_p=$recalc_p"
12060
12061         # set lru_max_age to 1 sec
12062         $LCTL set_param $nsdir.lru_max_age=1000 # milliseconds
12063         echo "sleep $((recalc_p * 2)) seconds..."
12064         sleep $((recalc_p * 2))
12065
12066         local remaining=$($LCTL get_param -n $nsdir.lock_unused_count)
12067         # restore lru_max_age
12068         $LCTL set_param -n $nsdir.lru_max_age $max_age
12069         [ $remaining -eq 0 ] || error "$remaining locks are not canceled"
12070         unlinkmany $DIR/$tdir/f $nr
12071 }
12072 run_test 124c "LRUR cancel very aged locks"
12073
12074 test_124d() {
12075         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12076         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
12077                 skip_env "no lru resize on server"
12078
12079         # cache ununsed locks on client
12080         local nr=100
12081
12082         lru_resize_disable mdc
12083         stack_trap "lru_resize_enable mdc" EXIT
12084
12085         cancel_lru_locks mdc
12086
12087         # asynchronous object destroy at MDT could cause bl ast to client
12088         test_mkdir $DIR/$tdir
12089         createmany -o $DIR/$tdir/f $nr ||
12090                 error "failed to create $nr files in $DIR/$tdir"
12091         stack_trap "unlinkmany $DIR/$tdir/f $nr" EXIT
12092
12093         ls -l $DIR/$tdir > /dev/null
12094
12095         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
12096         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
12097         local max_age=$($LCTL get_param -n $nsdir.lru_max_age)
12098         local recalc_p=$($LCTL get_param -n $nsdir.pool.recalc_period)
12099
12100         echo "unused=$unused, max_age=$max_age, recalc_p=$recalc_p"
12101
12102         # set lru_max_age to 1 sec
12103         $LCTL set_param $nsdir.lru_max_age=1000 # milliseconds
12104         stack_trap "$LCTL set_param -n $nsdir.lru_max_age $max_age" EXIT
12105
12106         echo "sleep $((recalc_p * 2)) seconds..."
12107         sleep $((recalc_p * 2))
12108
12109         local remaining=$($LCTL get_param -n $nsdir.lock_unused_count)
12110
12111         [ $remaining -eq 0 ] || error "$remaining locks are not canceled"
12112 }
12113 run_test 124d "cancel very aged locks if lru-resize diasbaled"
12114
12115 test_125() { # 13358
12116         $LCTL get_param -n llite.*.client_type | grep -q local ||
12117                 skip "must run as local client"
12118         $LCTL get_param -n mdc.*-mdc-*.connect_flags | grep -q acl ||
12119                 skip_env "must have acl enabled"
12120         [ -z "$(which setfacl)" ] && skip_env "must have setfacl tool"
12121
12122         test_mkdir $DIR/$tdir
12123         $LFS setstripe -S 65536 -c -1 $DIR/$tdir || error "setstripe failed"
12124         setfacl -R -m u:bin:rwx $DIR/$tdir || error "setfacl $DIR/$tdir failed"
12125         ls -ld $DIR/$tdir || error "cannot access $DIR/$tdir"
12126 }
12127 run_test 125 "don't return EPROTO when a dir has a non-default striping and ACLs"
12128
12129 test_126() { # bug 12829/13455
12130         $GSS && skip_env "must run as gss disabled"
12131         $LCTL get_param -n llite.*.client_type | grep -q local ||
12132                 skip "must run as local client"
12133         [ "$UID" != 0 ] && skip "must run as root, not UID $UID"
12134
12135         $RUNAS -u 0 -g 1 touch $DIR/$tfile || error "touch failed"
12136         gid=`ls -n $DIR/$tfile | awk '{print $4}'`
12137         rm -f $DIR/$tfile
12138         [ $gid -eq "1" ] || error "gid is set to" $gid "instead of 1"
12139 }
12140 run_test 126 "check that the fsgid provided by the client is taken into account"
12141
12142 test_127a() { # bug 15521
12143         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12144         local name count samp unit min max sum sumsq
12145
12146         $LFS setstripe -i 0 -c 1 $DIR/$tfile || error "setstripe failed"
12147         echo "stats before reset"
12148         $LCTL get_param osc.*.stats
12149         $LCTL set_param osc.*.stats=0
12150         local fsize=$((2048 * 1024))
12151
12152         dd if=/dev/zero of=$DIR/$tfile bs=$fsize count=1
12153         cancel_lru_locks osc
12154         dd if=$DIR/$tfile of=/dev/null bs=$fsize
12155
12156         $LCTL get_param osc.*0000-osc-*.stats | grep samples > $DIR/$tfile.tmp
12157         stack_trap "rm -f $TMP/$tfile.tmp"
12158         while read name count samp unit min max sum sumsq; do
12159                 echo "got name=$name count=$count unit=$unit min=$min max=$max"
12160                 [ ! $min ] && error "Missing min value for $name proc entry"
12161                 eval $name=$count || error "Wrong proc format"
12162
12163                 case $name in
12164                 read_bytes|write_bytes)
12165                         [[ "$unit" =~ "bytes" ]] ||
12166                                 error "unit is not 'bytes': $unit"
12167                         (( $min >= 4096 )) || error "min is too small: $min"
12168                         (( $min <= $fsize )) || error "min is too big: $min"
12169                         (( $max >= 4096 )) || error "max is too small: $max"
12170                         (( $max <= $fsize )) || error "max is too big: $max"
12171                         (( $sum == $fsize )) || error "sum is wrong: $sum"
12172                         (( $sumsq >= ($fsize / 4096) * (4096 * 4096) )) ||
12173                                 error "sumsquare is too small: $sumsq"
12174                         (( $sumsq <= $fsize * $fsize )) ||
12175                                 error "sumsquare is too big: $sumsq"
12176                         ;;
12177                 ost_read|ost_write)
12178                         [[ "$unit" =~ "usec" ]] ||
12179                                 error "unit is not 'usec': $unit"
12180                         ;;
12181                 *)      ;;
12182                 esac
12183         done < $DIR/$tfile.tmp
12184
12185         #check that we actually got some stats
12186         [ "$read_bytes" ] || error "Missing read_bytes stats"
12187         [ "$write_bytes" ] || error "Missing write_bytes stats"
12188         [ "$read_bytes" != 0 ] || error "no read done"
12189         [ "$write_bytes" != 0 ] || error "no write done"
12190 }
12191 run_test 127a "verify the client stats are sane"
12192
12193 test_127b() { # bug LU-333
12194         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12195         local name count samp unit min max sum sumsq
12196
12197         echo "stats before reset"
12198         $LCTL get_param llite.*.stats
12199         $LCTL set_param llite.*.stats=0
12200
12201         # perform 2 reads and writes so MAX is different from SUM.
12202         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1
12203         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1
12204         cancel_lru_locks osc
12205         dd if=$DIR/$tfile of=/dev/null bs=$PAGE_SIZE count=1
12206         dd if=$DIR/$tfile of=/dev/null bs=$PAGE_SIZE count=1
12207
12208         $LCTL get_param llite.*.stats | grep samples > $TMP/$tfile.tmp
12209         stack_trap "rm -f $TMP/$tfile.tmp"
12210         while read name count samp unit min max sum sumsq; do
12211                 echo "got name=$name count=$count unit=$unit min=$min max=$max"
12212                 eval $name=$count || error "Wrong proc format"
12213
12214                 case $name in
12215                 read_bytes|write_bytes)
12216                         [[ "$unit" =~ "bytes" ]] ||
12217                                 error "unit is not 'bytes': $unit"
12218                         (( $count == 2 )) || error "count is not 2: $count"
12219                         (( $min == $PAGE_SIZE )) ||
12220                                 error "min is not $PAGE_SIZE: $min"
12221                         (( $max == $PAGE_SIZE )) ||
12222                                 error "max is not $PAGE_SIZE: $max"
12223                         (( $sum == $PAGE_SIZE * 2 )) ||
12224                                 error "sum is not $((PAGE_SIZE * 2)): $sum"
12225                         ;;
12226                 read|write)
12227                         [[ "$unit" =~ "usec" ]] ||
12228                                 error "unit is not 'usec': $unit"
12229                         ;;
12230                 *)      ;;
12231                 esac
12232         done < $TMP/$tfile.tmp
12233
12234         #check that we actually got some stats
12235         [ "$read_bytes" ] || error "Missing read_bytes stats"
12236         [ "$write_bytes" ] || error "Missing write_bytes stats"
12237         [ "$read_bytes" != 0 ] || error "no read done"
12238         [ "$write_bytes" != 0 ] || error "no write done"
12239 }
12240 run_test 127b "verify the llite client stats are sane"
12241
12242 test_127c() { # LU-12394
12243         [ "$OSTCOUNT" -lt "2" ] && skip_env "needs >= 2 OSTs"
12244         local size
12245         local bsize
12246         local reads
12247         local writes
12248         local count
12249
12250         $LCTL set_param llite.*.extents_stats=1
12251         stack_trap "$LCTL set_param llite.*.extents_stats=0" EXIT
12252
12253         # Use two stripes so there is enough space in default config
12254         $LFS setstripe -c 2 $DIR/$tfile
12255
12256         # Extent stats start at 0-4K and go in power of two buckets
12257         # LL_HIST_START = 12 --> 2^12 = 4K
12258         # We do 3K*2^i, so 3K, 6K, 12K, 24K... hitting each bucket.
12259         # We do not do buckets larger than 64 MiB to avoid ENOSPC issues on
12260         # small configs
12261         for size in 3K 6K 12K 24K 48K 96K 192K 384K 768K 1536K 3M 6M 12M 24M 48M;
12262                 do
12263                 # Write and read, 2x each, second time at a non-zero offset
12264                 dd if=/dev/zero of=$DIR/$tfile bs=$size count=1
12265                 dd if=/dev/zero of=$DIR/$tfile bs=$size count=1 seek=10
12266                 dd if=$DIR/$tfile of=/dev/null bs=$size count=1
12267                 dd if=$DIR/$tfile of=/dev/null bs=$size count=1 seek=10
12268                 rm -f $DIR/$tfile
12269         done
12270
12271         $LCTL get_param llite.*.extents_stats
12272
12273         count=2
12274         for bsize in 4K 8K 16K 32K 64K 128K 256K 512K 1M 2M 4M 8M 16M 32M 64M;
12275                 do
12276                 local bucket=$($LCTL get_param -n llite.*.extents_stats |
12277                                 grep -m 1 $bsize)
12278                 reads=$(echo $bucket | awk '{print $5}')
12279                 writes=$(echo $bucket | awk '{print $9}')
12280                 [ "$reads" -eq $count ] ||
12281                         error "$reads reads in < $bsize bucket, expect $count"
12282                 [ "$writes" -eq $count ] ||
12283                         error "$writes writes in < $bsize bucket, expect $count"
12284         done
12285
12286         # Test mmap write and read
12287         $LCTL set_param llite.*.extents_stats=c
12288         size=512
12289         dd if=/dev/zero of=$DIR/$tfile bs=${size}K count=1
12290         $MULTIOP $DIR/$tfile OSMRUc || error "$MULTIOP $DIR/$tfile failed"
12291         $MULTIOP $DIR/$tfile OSMWUc || error "$MULTIOP $DIR/$tfile failed"
12292
12293         $LCTL get_param llite.*.extents_stats
12294
12295         count=$(((size*1024) / PAGE_SIZE))
12296
12297         bsize=$((2 * PAGE_SIZE / 1024))K
12298
12299         bucket=$($LCTL get_param -n llite.*.extents_stats |
12300                         grep -m 1 $bsize)
12301         reads=$(echo $bucket | awk '{print $5}')
12302         writes=$(echo $bucket | awk '{print $9}')
12303         # mmap writes fault in the page first, creating an additonal read
12304         [ "$reads" -eq $((2 * count)) ] ||
12305                 error "$reads reads in < $bsize bucket, expect $count"
12306         [ "$writes" -eq $count ] ||
12307                 error "$writes writes in < $bsize bucket, expect $count"
12308 }
12309 run_test 127c "test llite extent stats with regular & mmap i/o"
12310
12311 test_128() { # bug 15212
12312         touch $DIR/$tfile
12313         $LFS 2>&1 <<-EOF | tee $TMP/$tfile.log
12314                 find $DIR/$tfile
12315                 find $DIR/$tfile
12316         EOF
12317
12318         result=$(grep error $TMP/$tfile.log)
12319         rm -f $DIR/$tfile $TMP/$tfile.log
12320         [ -z "$result" ] ||
12321                 error "consecutive find's under interactive lfs failed"
12322 }
12323 run_test 128 "interactive lfs for 2 consecutive find's"
12324
12325 set_dir_limits () {
12326         local mntdev
12327         local canondev
12328         local node
12329
12330         local ldproc=/proc/fs/ldiskfs
12331         local facets=$(get_facets MDS)
12332
12333         for facet in ${facets//,/ }; do
12334                 canondev=$(ldiskfs_canon \
12335                            *.$(convert_facet2label $facet).mntdev $facet)
12336                 do_facet $facet "test -e $ldproc/$canondev/max_dir_size" ||
12337                         ldproc=/sys/fs/ldiskfs
12338                 do_facet $facet "echo $1 >$ldproc/$canondev/max_dir_size"
12339                 do_facet $facet "echo $2 >$ldproc/$canondev/warning_dir_size"
12340         done
12341 }
12342
12343 check_mds_dmesg() {
12344         local facets=$(get_facets MDS)
12345         for facet in ${facets//,/ }; do
12346                 do_facet $facet "dmesg | tail -3 | grep $1" && return 0
12347         done
12348         return 1
12349 }
12350
12351 test_129() {
12352         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12353         [[ $MDS1_VERSION -ge $(version_code 2.5.56) ]] ||
12354                 skip "Need MDS version with at least 2.5.56"
12355         if [ "$mds1_FSTYPE" != ldiskfs ]; then
12356                 skip_env "ldiskfs only test"
12357         fi
12358         remote_mds_nodsh && skip "remote MDS with nodsh"
12359
12360         local ENOSPC=28
12361         local has_warning=false
12362
12363         rm -rf $DIR/$tdir
12364         mkdir -p $DIR/$tdir
12365
12366         # block size of mds1
12367         local maxsize=$(($($LCTL get_param -n mdc.*MDT0000*.blocksize) * 8))
12368         set_dir_limits $maxsize $((maxsize * 6 / 8))
12369         stack_trap "set_dir_limits 0 0"
12370         stack_trap "unlinkmany $DIR/$tdir/file_base_ 2000 || true"
12371         local dirsize=$(stat -c%s "$DIR/$tdir")
12372         local nfiles=0
12373         while (( $dirsize <= $maxsize )); do
12374                 $MCREATE $DIR/$tdir/file_base_$nfiles
12375                 rc=$?
12376                 # check two errors:
12377                 # ENOSPC for ext4 max_dir_size, which has been used since
12378                 # kernel v3.6-rc1-8-gdf981d03ee, lustre v2_4_50_0-79-gaed82035c0
12379                 if (( rc == ENOSPC )); then
12380                         set_dir_limits 0 0
12381                         echo "rc=$rc returned as expected after $nfiles files"
12382
12383                         createmany -o $DIR/$tdir/file_extra_$nfiles. 5 ||
12384                                 error "create failed w/o dir size limit"
12385
12386                         # messages may be rate limited if test is run repeatedly
12387                         check_mds_dmesg '"is approaching max"' ||
12388                                 echo "warning message should be output"
12389                         check_mds_dmesg '"has reached max"' ||
12390                                 echo "reached message should be output"
12391
12392                         dirsize=$(stat -c%s "$DIR/$tdir")
12393
12394                         [[ $dirsize -ge $maxsize ]] && return 0
12395                         error "dirsize $dirsize < $maxsize after $nfiles files"
12396                 elif (( rc != 0 )); then
12397                         break
12398                 fi
12399                 nfiles=$((nfiles + 1))
12400                 dirsize=$(stat -c%s "$DIR/$tdir")
12401         done
12402
12403         error "rc=$rc, size=$dirsize/$maxsize, mdt=$MDSCOUNT, nfiles=$nfiles"
12404 }
12405 run_test 129 "test directory size limit ========================"
12406
12407 OLDIFS="$IFS"
12408 cleanup_130() {
12409         trap 0
12410         IFS="$OLDIFS"
12411 }
12412
12413 test_130a() {
12414         local filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
12415         [ -n "$filefrag_op" ] && skip_env "filefrag does not support FIEMAP"
12416
12417         trap cleanup_130 EXIT RETURN
12418
12419         local fm_file=$DIR/$tfile
12420         $LFS setstripe -S 65536 -c 1 $fm_file || error "setstripe on $fm_file"
12421         dd if=/dev/zero of=$fm_file bs=65536 count=1 ||
12422                 error "dd failed for $fm_file"
12423
12424         # LU-1795: test filefrag/FIEMAP once, even if unsupported
12425         filefrag -ves $fm_file
12426         RC=$?
12427         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
12428                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
12429         [ $RC != 0 ] && error "filefrag $fm_file failed"
12430
12431         filefrag_op=$(filefrag -ve -k $fm_file |
12432                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
12433         lun=$($LFS getstripe -i $fm_file)
12434
12435         start_blk=`echo $filefrag_op | cut -d: -f2 | cut -d. -f1`
12436         IFS=$'\n'
12437         tot_len=0
12438         for line in $filefrag_op
12439         do
12440                 frag_lun=`echo $line | cut -d: -f5`
12441                 ext_len=`echo $line | cut -d: -f4`
12442                 if (( $frag_lun != $lun )); then
12443                         cleanup_130
12444                         error "FIEMAP on 1-stripe file($fm_file) failed"
12445                         return
12446                 fi
12447                 (( tot_len += ext_len ))
12448         done
12449
12450         if (( lun != frag_lun || start_blk != 0 || tot_len != 64 )); then
12451                 cleanup_130
12452                 error "FIEMAP on 1-stripe file($fm_file) failed;"
12453                 return
12454         fi
12455
12456         cleanup_130
12457
12458         echo "FIEMAP on single striped file succeeded"
12459 }
12460 run_test 130a "FIEMAP (1-stripe file)"
12461
12462 test_130b() {
12463         [ "$OSTCOUNT" -lt "2" ] && skip_env "needs >= 2 OSTs"
12464
12465         local filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
12466         [ -n "$filefrag_op" ] && skip_env "filefrag does not support FIEMAP"
12467
12468         trap cleanup_130 EXIT RETURN
12469
12470         local fm_file=$DIR/$tfile
12471         $LFS setstripe -S 65536 -c $OSTCOUNT $fm_file ||
12472                         error "setstripe on $fm_file"
12473         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
12474                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
12475
12476         dd if=/dev/zero of=$fm_file bs=1M count=$OSTCOUNT ||
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 != $OSTCOUNT || 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 $OSTCOUNT-stripe file succeeded"
12518 }
12519 run_test 130b "FIEMAP ($OSTCOUNT-stripe file)"
12520
12521 test_130c() {
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 "filefrag does not support FIEMAP"
12526
12527         trap cleanup_130 EXIT RETURN
12528
12529         local fm_file=$DIR/$tfile
12530         $LFS setstripe -S 65536 -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         dd if=/dev/zero of=$fm_file seek=1 bs=1M count=1 ||
12535                         error "dd failed on $fm_file"
12536
12537         filefrag -ves $fm_file || error "filefrag $fm_file failed"
12538         filefrag_op=$(filefrag -ve -k $fm_file |
12539                 sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
12540
12541         last_lun=$(echo $filefrag_op | cut -d: -f5 |
12542                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
12543
12544         IFS=$'\n'
12545         tot_len=0
12546         num_luns=1
12547         for line in $filefrag_op
12548         do
12549                 frag_lun=$(echo $line | cut -d: -f5 |
12550                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
12551                 ext_len=$(echo $line | cut -d: -f4)
12552                 if (( $frag_lun != $last_lun )); then
12553                         logical=`echo $line | cut -d: -f2 | cut -d. -f1`
12554                         if (( logical != 512 )); then
12555                                 cleanup_130
12556                                 error "FIEMAP on $fm_file failed; returned " \
12557                                 "logical start for lun $logical instead of 512"
12558                                 return
12559                         fi
12560                         if (( tot_len != 512 )); then
12561                                 cleanup_130
12562                                 error "FIEMAP on $fm_file failed; returned " \
12563                                 "len $tot_len for OST $last_lun instead of 1024"
12564                                 return
12565                         else
12566                                 (( num_luns += 1 ))
12567                                 tot_len=0
12568                         fi
12569                 fi
12570                 (( tot_len += ext_len ))
12571                 last_lun=$frag_lun
12572         done
12573         if (( num_luns != 2 || tot_len != 512 )); then
12574                 cleanup_130
12575                 error "FIEMAP on $fm_file failed; returned wrong number of " \
12576                         "luns or wrong len for OST $last_lun"
12577                 return
12578         fi
12579
12580         cleanup_130
12581
12582         echo "FIEMAP on 2-stripe file with hole succeeded"
12583 }
12584 run_test 130c "FIEMAP (2-stripe file with hole)"
12585
12586 test_130d() {
12587         [[ $OSTCOUNT -lt 3 ]] && skip_env "needs >= 3 OSTs"
12588
12589         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
12590         [ -n "$filefrag_op" ] && skip "filefrag does not support FIEMAP"
12591
12592         trap cleanup_130 EXIT RETURN
12593
12594         local fm_file=$DIR/$tfile
12595         $LFS setstripe -S 65536 -c $OSTCOUNT $fm_file ||
12596                         error "setstripe on $fm_file"
12597         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
12598                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
12599
12600         local actual_stripe_count=$($LFS getstripe -c $fm_file)
12601         dd if=/dev/zero of=$fm_file bs=1M count=$actual_stripe_count ||
12602                 error "dd failed on $fm_file"
12603
12604         filefrag -ves $fm_file || error "filefrag $fm_file failed"
12605         filefrag_op=$(filefrag -ve -k $fm_file |
12606                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
12607
12608         last_lun=$(echo $filefrag_op | cut -d: -f5 |
12609                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
12610
12611         IFS=$'\n'
12612         tot_len=0
12613         num_luns=1
12614         for line in $filefrag_op
12615         do
12616                 frag_lun=$(echo $line | cut -d: -f5 |
12617                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
12618                 ext_len=$(echo $line | cut -d: -f4)
12619                 if (( $frag_lun != $last_lun )); then
12620                         if (( tot_len != 1024 )); then
12621                                 cleanup_130
12622                                 error "FIEMAP on $fm_file failed; returned " \
12623                                 "len $tot_len for OST $last_lun instead of 1024"
12624                                 return
12625                         else
12626                                 (( num_luns += 1 ))
12627                                 tot_len=0
12628                         fi
12629                 fi
12630                 (( tot_len += ext_len ))
12631                 last_lun=$frag_lun
12632         done
12633         if (( num_luns != actual_stripe_count || tot_len != 1024 )); then
12634                 cleanup_130
12635                 error "FIEMAP on $fm_file failed; returned wrong number of " \
12636                         "luns or wrong len for OST $last_lun"
12637                 return
12638         fi
12639
12640         cleanup_130
12641
12642         echo "FIEMAP on N-stripe file succeeded"
12643 }
12644 run_test 130d "FIEMAP (N-stripe file)"
12645
12646 test_130e() {
12647         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
12648
12649         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
12650         [ -n "$filefrag_op" ] && skip_env "filefrag does not support FIEMAP"
12651
12652         trap cleanup_130 EXIT RETURN
12653
12654         local fm_file=$DIR/$tfile
12655         $LFS setstripe -S 131072 -c 2 $fm_file || error "setstripe on $fm_file"
12656         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
12657                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
12658
12659         NUM_BLKS=512
12660         EXPECTED_LEN=$(( (NUM_BLKS / 2) * 64 ))
12661         for ((i = 0; i < $NUM_BLKS; i++))
12662         do
12663                 dd if=/dev/zero of=$fm_file count=1 bs=64k seek=$((2*$i)) conv=notrunc > /dev/null 2>&1
12664         done
12665
12666         filefrag -ves $fm_file || error "filefrag $fm_file failed"
12667         filefrag_op=$(filefrag -ve -k $fm_file |
12668                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
12669
12670         last_lun=$(echo $filefrag_op | cut -d: -f5 |
12671                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
12672
12673         IFS=$'\n'
12674         tot_len=0
12675         num_luns=1
12676         for line in $filefrag_op
12677         do
12678                 frag_lun=$(echo $line | cut -d: -f5 |
12679                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
12680                 ext_len=$(echo $line | cut -d: -f4)
12681                 if (( $frag_lun != $last_lun )); then
12682                         if (( tot_len != $EXPECTED_LEN )); then
12683                                 cleanup_130
12684                                 error "FIEMAP on $fm_file failed; returned " \
12685                                 "len $tot_len for OST $last_lun instead " \
12686                                 "of $EXPECTED_LEN"
12687                                 return
12688                         else
12689                                 (( num_luns += 1 ))
12690                                 tot_len=0
12691                         fi
12692                 fi
12693                 (( tot_len += ext_len ))
12694                 last_lun=$frag_lun
12695         done
12696         if (( num_luns != 2 || tot_len != $EXPECTED_LEN )); then
12697                 cleanup_130
12698                 error "FIEMAP on $fm_file failed; returned wrong number " \
12699                         "of luns or wrong len for OST $last_lun"
12700                 return
12701         fi
12702
12703         cleanup_130
12704
12705         echo "FIEMAP with continuation calls succeeded"
12706 }
12707 run_test 130e "FIEMAP (test continuation FIEMAP calls)"
12708
12709 test_130f() {
12710         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
12711         [ -n "$filefrag_op" ] && skip "filefrag does not support FIEMAP"
12712
12713         local fm_file=$DIR/$tfile
12714         $MULTIOP $fm_file oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:T33554432c ||
12715                 error "multiop create with lov_delay_create on $fm_file"
12716
12717         filefrag -ves $fm_file || error "filefrag $fm_file failed"
12718         filefrag_extents=$(filefrag -vek $fm_file |
12719                            awk '/extents? found/ { print $2 }')
12720         if [[ "$filefrag_extents" != "0" ]]; then
12721                 error "FIEMAP on $fm_file failed; " \
12722                       "returned $filefrag_extents expected 0"
12723         fi
12724
12725         rm -f $fm_file
12726 }
12727 run_test 130f "FIEMAP (unstriped file)"
12728
12729 # Test for writev/readv
12730 test_131a() {
12731         rwv -f $DIR/$tfile -w -n 3 524288 1048576 1572864 ||
12732                 error "writev test failed"
12733         rwv -f $DIR/$tfile -r -v -n 2 1572864 1048576 ||
12734                 error "readv failed"
12735         rm -f $DIR/$tfile
12736 }
12737 run_test 131a "test iov's crossing stripe boundary for writev/readv"
12738
12739 test_131b() {
12740         local fsize=$((524288 + 1048576 + 1572864))
12741         rwv -f $DIR/$tfile -w -a -n 3 524288 1048576 1572864 &&
12742                 $CHECKSTAT -t file $DIR/$tfile -s $fsize ||
12743                         error "append writev test failed"
12744
12745         ((fsize += 1572864 + 1048576))
12746         rwv -f $DIR/$tfile -w -a -n 2 1572864 1048576 &&
12747                 $CHECKSTAT -t file $DIR/$tfile -s $fsize ||
12748                         error "append writev test failed"
12749         rm -f $DIR/$tfile
12750 }
12751 run_test 131b "test append writev"
12752
12753 test_131c() {
12754         rwv -f $DIR/$tfile -w -d -n 1 1048576 || return 0
12755         error "NOT PASS"
12756 }
12757 run_test 131c "test read/write on file w/o objects"
12758
12759 test_131d() {
12760         rwv -f $DIR/$tfile -w -n 1 1572864
12761         NOB=`rwv -f $DIR/$tfile -r -n 3 524288 524288 1048576 | awk '/error/ {print $6}'`
12762         if [ "$NOB" != 1572864 ]; then
12763                 error "Short read filed: read $NOB bytes instead of 1572864"
12764         fi
12765         rm -f $DIR/$tfile
12766 }
12767 run_test 131d "test short read"
12768
12769 test_131e() {
12770         rwv -f $DIR/$tfile -w -s 1048576 -n 1 1048576
12771         rwv -f $DIR/$tfile -r -z -s 0 -n 1 524288 || \
12772         error "read hitting hole failed"
12773         rm -f $DIR/$tfile
12774 }
12775 run_test 131e "test read hitting hole"
12776
12777 check_stats() {
12778         local facet=$1
12779         local op=$2
12780         local want=${3:-0}
12781         local res
12782
12783         case $facet in
12784         mds*) res=$(do_facet $facet \
12785                    $LCTL get_param mdt.$FSNAME-MDT0000.md_stats | grep "$op")
12786                  ;;
12787         ost*) res=$(do_facet $facet \
12788                    $LCTL get_param obdfilter.$FSNAME-OST0000.stats | grep "$op")
12789                  ;;
12790         *) error "Wrong facet '$facet'" ;;
12791         esac
12792         [ "$res" ] || error "The counter for $op on $facet was not incremented"
12793         # if the argument $3 is zero, it means any stat increment is ok.
12794         if [[ $want -gt 0 ]]; then
12795                 local count=$(echo $res | awk '{ print $2 }')
12796                 [[ $count -ne $want ]] &&
12797                         error "The $op counter on $facet is $count, not $want"
12798         fi
12799 }
12800
12801 test_133a() {
12802         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12803         remote_ost_nodsh && skip "remote OST with nodsh"
12804         remote_mds_nodsh && skip "remote MDS with nodsh"
12805         do_facet $SINGLEMDS $LCTL list_param mdt.*.rename_stats ||
12806                 skip_env "MDS doesn't support rename stats"
12807
12808         local testdir=$DIR/${tdir}/stats_testdir
12809
12810         mkdir -p $DIR/${tdir}
12811
12812         # clear stats.
12813         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
12814         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
12815
12816         # verify mdt stats first.
12817         mkdir ${testdir} || error "mkdir failed"
12818         check_stats $SINGLEMDS "mkdir" 1
12819         touch ${testdir}/${tfile} || error "touch failed"
12820         check_stats $SINGLEMDS "open" 1
12821         check_stats $SINGLEMDS "close" 1
12822         [ $MDS1_VERSION -ge $(version_code 2.8.54) ] && {
12823                 mknod ${testdir}/${tfile}-pipe p || error "mknod failed"
12824                 check_stats $SINGLEMDS "mknod" 2
12825         }
12826         rm -f ${testdir}/${tfile}-pipe || error "pipe remove failed"
12827         check_stats $SINGLEMDS "unlink" 1
12828         rm -f ${testdir}/${tfile} || error "file remove failed"
12829         check_stats $SINGLEMDS "unlink" 2
12830
12831         # remove working dir and check mdt stats again.
12832         rmdir ${testdir} || error "rmdir failed"
12833         check_stats $SINGLEMDS "rmdir" 1
12834
12835         local testdir1=$DIR/${tdir}/stats_testdir1
12836         mkdir -p ${testdir}
12837         mkdir -p ${testdir1}
12838         touch ${testdir1}/test1
12839         mv ${testdir1}/test1 ${testdir} || error "file crossdir rename"
12840         check_stats $SINGLEMDS "crossdir_rename" 1
12841
12842         mv ${testdir}/test1 ${testdir}/test0 || error "file samedir rename"
12843         check_stats $SINGLEMDS "samedir_rename" 1
12844
12845         rm -rf $DIR/${tdir}
12846 }
12847 run_test 133a "Verifying MDT stats ========================================"
12848
12849 test_133b() {
12850         local res
12851
12852         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12853         remote_ost_nodsh && skip "remote OST with nodsh"
12854         remote_mds_nodsh && skip "remote MDS with nodsh"
12855
12856         local testdir=$DIR/${tdir}/stats_testdir
12857
12858         mkdir -p ${testdir} || error "mkdir failed"
12859         touch ${testdir}/${tfile} || error "touch failed"
12860         cancel_lru_locks mdc
12861
12862         # clear stats.
12863         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
12864         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
12865
12866         # extra mdt stats verification.
12867         chmod 444 ${testdir}/${tfile} || error "chmod failed"
12868         check_stats $SINGLEMDS "setattr" 1
12869         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
12870         if [ $MDS1_VERSION -ne $(version_code 2.2.0) ]
12871         then            # LU-1740
12872                 ls -l ${testdir}/${tfile} > /dev/null|| error "ls failed"
12873                 check_stats $SINGLEMDS "getattr" 1
12874         fi
12875         rm -rf $DIR/${tdir}
12876
12877         # when DNE is enabled, MDT uses STATFS RPC to ping other targets
12878         # so the check below is not reliable
12879         [ $MDSCOUNT -eq 1 ] || return 0
12880
12881         # Sleep to avoid a cached response.
12882         #define OBD_STATFS_CACHE_SECONDS 1
12883         sleep 2
12884         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
12885         do_facet ost1 $LCTL set_param obdfilter.*.exports.*.stats=clear
12886         $LFS df || error "lfs failed"
12887         check_stats $SINGLEMDS "statfs" 1
12888
12889         # check aggregated statfs (LU-10018)
12890         [ $MDS1_VERSION -lt $(version_code 2.11.54) ] &&
12891                 return 0
12892         [ $CLIENT_VERSION -lt $(version_code 2.11.54) ] &&
12893                 return 0
12894         sleep 2
12895         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
12896         do_facet ost1 $LCTL set_param obdfilter.*.exports.*.stats=clear
12897         df $DIR
12898         check_stats $SINGLEMDS "statfs" 1
12899
12900         # We want to check that the client didn't send OST_STATFS to
12901         # ost1 but the MDT also uses OST_STATFS for precreate. So some
12902         # extra care is needed here.
12903         if remote_mds; then
12904                 local nid=$($LCTL list_nids | head -1 | sed  "s/\./\\\./g")
12905                 local param="obdfilter.$FSNAME-OST0000.exports.'$nid'.stats"
12906
12907                 res=$(do_facet ost1 $LCTL get_param $param | grep statfs)
12908                 [ "$res" ] && error "OST got STATFS"
12909         fi
12910
12911         return 0
12912 }
12913 run_test 133b "Verifying extra MDT stats =================================="
12914
12915 test_133c() {
12916         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12917         remote_ost_nodsh && skip "remote OST with nodsh"
12918         remote_mds_nodsh && skip "remote MDS with nodsh"
12919
12920         local testdir=$DIR/$tdir/stats_testdir
12921
12922         test_mkdir -p $testdir
12923
12924         # verify obdfilter stats.
12925         $LFS setstripe -c 1 -i 0 $testdir/$tfile
12926         sync
12927         cancel_lru_locks osc
12928         wait_delete_completed
12929
12930         # clear stats.
12931         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
12932         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
12933
12934         dd if=/dev/zero of=$testdir/$tfile conv=notrunc bs=512k count=1 ||
12935                 error "dd failed"
12936         sync
12937         cancel_lru_locks osc
12938         check_stats ost1 "write" 1
12939
12940         dd if=$testdir/$tfile of=/dev/null bs=1k count=1 || error "dd failed"
12941         check_stats ost1 "read" 1
12942
12943         > $testdir/$tfile || error "truncate failed"
12944         check_stats ost1 "punch" 1
12945
12946         rm -f $testdir/$tfile || error "file remove failed"
12947         wait_delete_completed
12948         check_stats ost1 "destroy" 1
12949
12950         rm -rf $DIR/$tdir
12951 }
12952 run_test 133c "Verifying OST stats ========================================"
12953
12954 order_2() {
12955         local value=$1
12956         local orig=$value
12957         local order=1
12958
12959         while [ $value -ge 2 ]; do
12960                 order=$((order*2))
12961                 value=$((value/2))
12962         done
12963
12964         if [ $orig -gt $order ]; then
12965                 order=$((order*2))
12966         fi
12967         echo $order
12968 }
12969
12970 size_in_KMGT() {
12971     local value=$1
12972     local size=('K' 'M' 'G' 'T');
12973     local i=0
12974     local size_string=$value
12975
12976     while [ $value -ge 1024 ]; do
12977         if [ $i -gt 3 ]; then
12978             #T is the biggest unit we get here, if that is bigger,
12979             #just return XXXT
12980             size_string=${value}T
12981             break
12982         fi
12983         value=$((value >> 10))
12984         if [ $value -lt 1024 ]; then
12985             size_string=${value}${size[$i]}
12986             break
12987         fi
12988         i=$((i + 1))
12989     done
12990
12991     echo $size_string
12992 }
12993
12994 get_rename_size() {
12995         local size=$1
12996         local context=${2:-.}
12997         local sample=$(do_facet $SINGLEMDS $LCTL \
12998                 get_param mdt.$FSNAME-MDT0000.rename_stats |
12999                 grep -A1 $context |
13000                 awk '/ '${size}'/ {print $4}' | sed -e "s/,//g")
13001         echo $sample
13002 }
13003
13004 test_133d() {
13005         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13006         remote_ost_nodsh && skip "remote OST with nodsh"
13007         remote_mds_nodsh && skip "remote MDS with nodsh"
13008         do_facet $SINGLEMDS $LCTL list_param mdt.*.rename_stats ||
13009                 skip_env "MDS doesn't support rename stats"
13010
13011         local testdir1=$DIR/${tdir}/stats_testdir1
13012         local testdir2=$DIR/${tdir}/stats_testdir2
13013         mkdir -p $DIR/${tdir}
13014
13015         do_facet $SINGLEMDS $LCTL set_param mdt.*.rename_stats=clear
13016
13017         lfs mkdir -i 0 -c 1 ${testdir1} || error "mkdir failed"
13018         lfs mkdir -i 0 -c 1 ${testdir2} || error "mkdir failed"
13019
13020         createmany -o $testdir1/test 512 || error "createmany failed"
13021
13022         # check samedir rename size
13023         mv ${testdir1}/test0 ${testdir1}/test_0
13024
13025         local testdir1_size=$(ls -l $DIR/${tdir} |
13026                 awk '/stats_testdir1/ {print $5}')
13027         local testdir2_size=$(ls -l $DIR/${tdir} |
13028                 awk '/stats_testdir2/ {print $5}')
13029
13030         testdir1_size=$(order_2 $testdir1_size)
13031         testdir2_size=$(order_2 $testdir2_size)
13032
13033         testdir1_size=$(size_in_KMGT $testdir1_size)
13034         testdir2_size=$(size_in_KMGT $testdir2_size)
13035
13036         echo "source rename dir size: ${testdir1_size}"
13037         echo "target rename dir size: ${testdir2_size}"
13038
13039         local cmd="do_facet $SINGLEMDS $LCTL "
13040         cmd+="get_param mdt.$FSNAME-MDT0000.rename_stats"
13041
13042         eval $cmd || error "$cmd failed"
13043         local samedir=$($cmd | grep 'same_dir')
13044         local same_sample=$(get_rename_size $testdir1_size)
13045         [ -z "$samedir" ] && error "samedir_rename_size count error"
13046         [[ $same_sample -eq 1 ]] ||
13047                 error "samedir_rename_size error $same_sample"
13048         echo "Check same dir rename stats success"
13049
13050         do_facet $SINGLEMDS $LCTL set_param mdt.*.rename_stats=clear
13051
13052         # check crossdir rename size
13053         mv ${testdir1}/test_0 ${testdir2}/test_0
13054
13055         testdir1_size=$(ls -l $DIR/${tdir} |
13056                 awk '/stats_testdir1/ {print $5}')
13057         testdir2_size=$(ls -l $DIR/${tdir} |
13058                 awk '/stats_testdir2/ {print $5}')
13059
13060         testdir1_size=$(order_2 $testdir1_size)
13061         testdir2_size=$(order_2 $testdir2_size)
13062
13063         testdir1_size=$(size_in_KMGT $testdir1_size)
13064         testdir2_size=$(size_in_KMGT $testdir2_size)
13065
13066         echo "source rename dir size: ${testdir1_size}"
13067         echo "target rename dir size: ${testdir2_size}"
13068
13069         eval $cmd || error "$cmd failed"
13070         local crossdir=$($cmd | grep 'crossdir')
13071         local src_sample=$(get_rename_size $testdir1_size crossdir_src)
13072         local tgt_sample=$(get_rename_size $testdir2_size crossdir_tgt)
13073         [ -z "$crossdir" ] && error "crossdir_rename_size count error"
13074         [[ $src_sample -eq 1 ]] ||
13075                 error "crossdir_rename_size error $src_sample"
13076         [[ $tgt_sample -eq 1 ]] ||
13077                 error "crossdir_rename_size error $tgt_sample"
13078         echo "Check cross dir rename stats success"
13079         rm -rf $DIR/${tdir}
13080 }
13081 run_test 133d "Verifying rename_stats ========================================"
13082
13083 test_133e() {
13084         remote_mds_nodsh && skip "remote MDS with nodsh"
13085         remote_ost_nodsh && skip "remote OST with nodsh"
13086         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13087
13088         local testdir=$DIR/${tdir}/stats_testdir
13089         local ctr f0 f1 bs=32768 count=42 sum
13090
13091         mkdir -p ${testdir} || error "mkdir failed"
13092
13093         $LFS setstripe -c 1 -i 0 ${testdir}/${tfile}
13094
13095         for ctr in {write,read}_bytes; do
13096                 sync
13097                 cancel_lru_locks osc
13098
13099                 do_facet ost1 $LCTL set_param -n \
13100                         "obdfilter.*.exports.clear=clear"
13101
13102                 if [ $ctr = write_bytes ]; then
13103                         f0=/dev/zero
13104                         f1=${testdir}/${tfile}
13105                 else
13106                         f0=${testdir}/${tfile}
13107                         f1=/dev/null
13108                 fi
13109
13110                 dd if=$f0 of=$f1 conv=notrunc bs=$bs count=$count || \
13111                         error "dd failed"
13112                 sync
13113                 cancel_lru_locks osc
13114
13115                 sum=$(do_facet ost1 $LCTL get_param \
13116                         "obdfilter.*.exports.*.stats" |
13117                         awk -v ctr=$ctr 'BEGIN { sum = 0 }
13118                                 $1 == ctr { sum += $7 }
13119                                 END { printf("%0.0f", sum) }')
13120
13121                 if ((sum != bs * count)); then
13122                         error "Bad $ctr sum, expected $((bs * count)), got $sum"
13123                 fi
13124         done
13125
13126         rm -rf $DIR/${tdir}
13127 }
13128 run_test 133e "Verifying OST {read,write}_bytes nid stats ================="
13129
13130 test_133f() {
13131         [[ $(lustre_version_code $facet) -ge $(version_code 2.7.65) ]] ||
13132                 skip "too old lustre for get_param -R ($facet_ver)"
13133
13134         # verifying readability.
13135         $LCTL get_param -R '*' &> /dev/null
13136
13137         # Verifing writability with badarea_io.
13138         $LCTL list_param -FR '*' | grep '=' | tr -d = |
13139                 egrep -v 'force_lbug|changelog_mask' | xargs badarea_io ||
13140                 error "client badarea_io failed"
13141
13142         # remount the FS in case writes/reads /proc break the FS
13143         cleanup || error "failed to unmount"
13144         setup || error "failed to setup"
13145 }
13146 run_test 133f "Check reads/writes of client lustre proc files with bad area io"
13147
13148 test_133g() {
13149         remote_mds_nodsh && skip "remote MDS with nodsh"
13150         remote_ost_nodsh && skip "remote OST with nodsh"
13151
13152         local facet
13153         for facet in mds1 ost1; do
13154                 local facet_ver=$(lustre_version_code $facet)
13155                 if [ $facet_ver -ge $(version_code 2.7.65) ]; then
13156                         do_facet $facet "$LCTL get_param -R '*'" &> /dev/null
13157                 else
13158                         log "$facet: too old lustre for get_param -R"
13159                 fi
13160                 if [ $facet_ver -ge $(version_code 2.5.54) ]; then
13161                         do_facet $facet "$LCTL list_param -FR '*' | grep '=' |
13162                                 tr -d = | egrep -v 'force_lbug|changelog_mask' |
13163                                 xargs badarea_io" ||
13164                                         error "$facet badarea_io failed"
13165                 else
13166                         skip_noexit "$facet: too old lustre for get_param -R"
13167                 fi
13168         done
13169
13170         # remount the FS in case writes/reads /proc break the FS
13171         cleanup || error "failed to unmount"
13172         setup || error "failed to setup"
13173 }
13174 run_test 133g "Check reads/writes of server lustre proc files with bad area io"
13175
13176 test_133h() {
13177         remote_mds_nodsh && skip "remote MDS with nodsh"
13178         remote_ost_nodsh && skip "remote OST with nodsh"
13179         [[ $MDS1_VERSION -lt $(version_code 2.9.54) ]] &&
13180                 skip "Need MDS version at least 2.9.54"
13181
13182         local facet
13183         for facet in client mds1 ost1; do
13184                 # Get the list of files that are missing the terminating newline
13185                 local plist=$(do_facet $facet
13186                         $LCTL list_param -FR '*' | grep '=' | tr -d =)
13187                 local ent
13188                 for ent in $plist; do
13189                         local missing=$(do_facet $facet $LCTL get_param $ent \|\
13190                                 awk -v FS='\v' -v RS='\v\v' \
13191                                 "'END { if(NR>0 && \\\$NF !~ /.*\\\n\$/) \
13192                                         print FILENAME}'" 2>/dev/null)
13193                         [ -z $missing ] || {
13194                                 do_facet $facet $LCTL get_param $ent | od -An -tx1
13195                                 error "file does not end with newline: $facet-$ent"
13196                         }
13197                 done
13198         done
13199 }
13200 run_test 133h "Proc files should end with newlines"
13201
13202 test_134a() {
13203         remote_mds_nodsh && skip "remote MDS with nodsh"
13204         [[ $MDS1_VERSION -lt $(version_code 2.7.54) ]] &&
13205                 skip "Need MDS version at least 2.7.54"
13206
13207         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
13208         cancel_lru_locks mdc
13209
13210         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
13211         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
13212         [ $unused -eq 0 ] || error "$unused locks are not cleared"
13213
13214         local nr=1000
13215         createmany -o $DIR/$tdir/f $nr ||
13216                 error "failed to create $nr files in $DIR/$tdir"
13217         unused=$($LCTL get_param -n $nsdir.lock_unused_count)
13218
13219         #define OBD_FAIL_LDLM_WATERMARK_LOW     0x327
13220         do_facet mds1 $LCTL set_param fail_loc=0x327
13221         do_facet mds1 $LCTL set_param fail_val=500
13222         touch $DIR/$tdir/m
13223
13224         echo "sleep 10 seconds ..."
13225         sleep 10
13226         local lck_cnt=$($LCTL get_param -n $nsdir.lock_unused_count)
13227
13228         do_facet mds1 $LCTL set_param fail_loc=0
13229         do_facet mds1 $LCTL set_param fail_val=0
13230         [ $lck_cnt -lt $unused ] ||
13231                 error "No locks reclaimed, before:$unused, after:$lck_cnt"
13232
13233         rm $DIR/$tdir/m
13234         unlinkmany $DIR/$tdir/f $nr
13235 }
13236 run_test 134a "Server reclaims locks when reaching lock_reclaim_threshold"
13237
13238 test_134b() {
13239         remote_mds_nodsh && skip "remote MDS with nodsh"
13240         [[ $MDS1_VERSION -lt $(version_code 2.7.54) ]] &&
13241                 skip "Need MDS version at least 2.7.54"
13242
13243         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
13244         cancel_lru_locks mdc
13245
13246         local low_wm=$(do_facet mds1 $LCTL get_param -n \
13247                         ldlm.lock_reclaim_threshold_mb)
13248         # disable reclaim temporarily
13249         do_facet mds1 $LCTL set_param ldlm.lock_reclaim_threshold_mb=0
13250
13251         #define OBD_FAIL_LDLM_WATERMARK_HIGH     0x328
13252         do_facet mds1 $LCTL set_param fail_loc=0x328
13253         do_facet mds1 $LCTL set_param fail_val=500
13254
13255         $LCTL set_param debug=+trace
13256
13257         local nr=600
13258         createmany -o $DIR/$tdir/f $nr &
13259         local create_pid=$!
13260
13261         echo "Sleep $TIMEOUT seconds ..."
13262         sleep $TIMEOUT
13263         if ! ps -p $create_pid  > /dev/null 2>&1; then
13264                 do_facet mds1 $LCTL set_param fail_loc=0
13265                 do_facet mds1 $LCTL set_param fail_val=0
13266                 do_facet mds1 $LCTL set_param \
13267                         ldlm.lock_reclaim_threshold_mb=${low_wm}m
13268                 error "createmany finished incorrectly!"
13269         fi
13270         do_facet mds1 $LCTL set_param fail_loc=0
13271         do_facet mds1 $LCTL set_param fail_val=0
13272         do_facet mds1 $LCTL set_param ldlm.lock_reclaim_threshold_mb=${low_wm}m
13273         wait $create_pid || return 1
13274
13275         unlinkmany $DIR/$tdir/f $nr
13276 }
13277 run_test 134b "Server rejects lock request when reaching lock_limit_mb"
13278
13279 test_135() {
13280         remote_mds_nodsh && skip "remote MDS with nodsh"
13281         [[ $MDS1_VERSION -lt $(version_code 2.13.50) ]] &&
13282                 skip "Need MDS version at least 2.13.50"
13283         local fname
13284
13285         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
13286
13287 #define OBD_FAIL_PLAIN_RECORDS 0x1319
13288         #set only one record at plain llog
13289         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x1319 fail_val=1
13290
13291         #fill already existed plain llog each 64767
13292         #wrapping whole catalog
13293         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 1))
13294
13295         createmany -o $DIR/$tdir/$tfile_ 64700
13296         for (( i = 0; i < 64700; i = i + 2 ))
13297         do
13298                 rm $DIR/$tdir/$tfile_$i &
13299                 rm $DIR/$tdir/$tfile_$((i + 1)) &
13300                 local pid=$!
13301                 wait $pid
13302         done
13303
13304         #waiting osp synchronization
13305         wait_delete_completed
13306 }
13307 run_test 135 "Race catalog processing"
13308
13309 test_136() {
13310         remote_mds_nodsh && skip "remote MDS with nodsh"
13311         [[ $MDS1_VERSION -lt $(version_code 2.13.50) ]] &&
13312                 skip "Need MDS version at least 2.13.50"
13313         local fname
13314
13315         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
13316         $LFS setstripe -c 1 -i 0 $DIR/$tdir || error "failed to set striping"
13317         #set only one record at plain llog
13318 #define OBD_FAIL_CATALOG_FULL_CHECK                0x131a
13319         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x131a fail_val=1
13320
13321         #fill already existed 2 plain llogs each 64767
13322         #wrapping whole catalog
13323         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 1))
13324         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 3 / 2))
13325         wait_delete_completed
13326
13327         createmany -o $DIR/$tdir/$tfile_ 10
13328         sleep 25
13329
13330         do_facet $SINGLEMDS $LCTL set_param fail_val=3
13331         for (( i = 0; i < 10; i = i + 3 ))
13332         do
13333                 rm $DIR/$tdir/$tfile_$i &
13334                 rm $DIR/$tdir/$tfile_$((i + 1)) &
13335                 local pid=$!
13336                 wait $pid
13337                 sleep 7
13338                 rm $DIR/$tdir/$tfile_$((i + 2)) &
13339         done
13340
13341         #waiting osp synchronization
13342         wait_delete_completed
13343 }
13344 run_test 136 "Race catalog processing 2"
13345
13346 test_140() { #bug-17379
13347         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13348
13349         test_mkdir $DIR/$tdir
13350         cd $DIR/$tdir || error "Changing to $DIR/$tdir"
13351         cp $(which stat) . || error "Copying stat to $DIR/$tdir"
13352
13353         # VFS limits max symlink depth to 5(4KSTACK) or 7(8KSTACK) or 8
13354         # For kernel > 3.5, bellow only tests consecutive symlink (MAX 40)
13355         local i=0
13356         while i=$((i + 1)); do
13357                 test_mkdir $i
13358                 cd $i || error "Changing to $i"
13359                 ln -s ../stat stat || error "Creating stat symlink"
13360                 # Read the symlink until ELOOP present,
13361                 # not LBUGing the system is considered success,
13362                 # we didn't overrun the stack.
13363                 $OPENFILE -f O_RDONLY stat >/dev/null 2>&1; ret=$?
13364                 if [ $ret -ne 0 ]; then
13365                         if [ $ret -eq 40 ]; then
13366                                 break  # -ELOOP
13367                         else
13368                                 error "Open stat symlink"
13369                                         return
13370                         fi
13371                 fi
13372         done
13373         i=$((i - 1))
13374         echo "The symlink depth = $i"
13375         [ $i -eq 5 ] || [ $i -eq 7 ] || [ $i -eq 8 ] || [ $i -eq 40 ] ||
13376                 error "Invalid symlink depth"
13377
13378         # Test recursive symlink
13379         ln -s symlink_self symlink_self
13380         $OPENFILE -f O_RDONLY symlink_self >/dev/null 2>&1; ret=$?
13381         echo "open symlink_self returns $ret"
13382         [ $ret -eq 40 ] || error "recursive symlink doesn't return -ELOOP"
13383 }
13384 run_test 140 "Check reasonable stack depth (shouldn't LBUG) ===="
13385
13386 test_150a() {
13387         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13388
13389         local TF="$TMP/$tfile"
13390
13391         dd if=/dev/urandom of=$TF bs=6096 count=1 || error "dd failed"
13392         cp $TF $DIR/$tfile
13393         cancel_lru_locks $OSC
13394         cmp $TF $DIR/$tfile || error "$TMP/$tfile $DIR/$tfile differ"
13395         remount_client $MOUNT
13396         df -P $MOUNT
13397         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (remount)"
13398
13399         $TRUNCATE $TF 6000
13400         $TRUNCATE $DIR/$tfile 6000
13401         cancel_lru_locks $OSC
13402         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (truncate1)"
13403
13404         echo "12345" >>$TF
13405         echo "12345" >>$DIR/$tfile
13406         cancel_lru_locks $OSC
13407         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (append1)"
13408
13409         echo "12345" >>$TF
13410         echo "12345" >>$DIR/$tfile
13411         cancel_lru_locks $OSC
13412         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (append2)"
13413
13414         rm -f $TF
13415         true
13416 }
13417 run_test 150a "truncate/append tests"
13418
13419 test_150b() {
13420         [ "$ost1_FSTYPE" != ldiskfs ] && skip "non-ldiskfs backend"
13421         [ $OST1_VERSION -lt $(version_code 2.13.50) ] &&
13422                 skip "Need OST version at least 2.13.53"
13423         touch $DIR/$tfile
13424         check_fallocate $DIR/$tfile || error "fallocate failed"
13425 }
13426 run_test 150b "Verify fallocate (prealloc) functionality"
13427
13428 test_150c() {
13429         local bytes
13430         local want
13431
13432         [ "$ost1_FSTYPE" != ldiskfs ] && skip "non-ldiskfs backend"
13433         [ $OST1_VERSION -lt $(version_code 2.13.50) ] &&
13434                 skip "Need OST version at least 2.13.53"
13435
13436         $LFS setstripe -c $OSTCOUNT -S1M $DIR/$tfile || error "setstripe failed"
13437         fallocate -l ${OSTCOUNT}m $DIR/$tfile || error "fallocate failed"
13438         sync; sync_all_data
13439         cancel_lru_locks $OSC
13440         sleep 5
13441         bytes=$(($(stat -c '%b * %B' $DIR/$tfile)))
13442         want=$((OSTCOUNT * 1048576))
13443
13444         # Must allocate all requested space, not more than 5% extra
13445         (( $bytes >= $want && $bytes < $want * 105 / 100 )) ||
13446                 error "bytes $bytes is not $want"
13447
13448         rm -f $DIR/$tfile
13449         # verify fallocate on PFL file
13450         $LFS setstripe -E1M -c1 -E16M -c3 -Eeof -c 4 $DIR/$tfile ||
13451                 error "Create $DIR/$tfile failed"
13452         fallocate -l $((1048576 * 1024)) $DIR/$tfile ||
13453                         error "fallocate failed"
13454         sync; sync_all_data
13455         cancel_lru_locks $OSC
13456         sleep 5
13457         bytes=$(($(stat -c '%b * %B' $DIR/$tfile)))
13458         want=$((1024 * 1048576))
13459
13460         # Must allocate all requested space, not more than 5% extra
13461         (( $bytes >= $want && $bytes < $want * 105 / 100 )) ||
13462                 error "bytes $bytes is not $want"
13463 }
13464 run_test 150c "Verify fallocate Size and Blocks"
13465
13466 test_150d() {
13467         local bytes
13468         local want
13469
13470         [ "$ost1_FSTYPE" != ldiskfs ] && skip "non-ldiskfs backend"
13471         [ $OST1_VERSION -lt $(version_code 2.13.50) ] &&
13472                 skip "Need OST version at least 2.13.53"
13473
13474         $LFS setstripe -c $OSTCOUNT -S1M $DIR/$tdir || error "setstripe failed"
13475         fallocate -o 1G -l ${OSTCOUNT}m $DIR/$tdir || error "fallocate failed"
13476         sync; sync_all_data
13477         cancel_lru_locks $OSC
13478         sleep 5
13479         bytes=$(($(stat -c '%b * %B' $DIR/$tdir)))
13480         want=$((OSTCOUNT * 1048576))
13481
13482         # Must allocate all requested space, not more than 5% extra
13483         (( $bytes >= $want && $bytes < $want * 105 / 100 )) ||
13484                 error "bytes $bytes is not $want"
13485 }
13486 run_test 150d "Verify fallocate Size and Blocks - Non zero start"
13487
13488 test_150e() {
13489         [ "$ost1_FSTYPE" != ldiskfs ] && skip "non-ldiskfs backend"
13490         [ $OST1_VERSION -ge $(version_code 2.13.55) ] ||
13491                 skip "Need OST version at least 2.13.55"
13492
13493         echo "df before:"
13494         $LFS df
13495         $LFS setstripe -c${OSTCOUNT} $DIR/$tfile ||
13496                 error "$LFS setstripe -c${OSTCOUNT} $DIR/$tfile failed"
13497
13498         # Find OST with Minimum Size
13499         min_size_ost=$($LFS df | awk "/$FSNAME-OST/ { print \$4 }" |
13500                        sort -un | head -1)
13501
13502         # Get 90% of the available space
13503         local space=$(((min_size_ost * 90)/100 * OSTCOUNT))
13504
13505         fallocate -l${space}k $DIR/$tfile ||
13506                 error "fallocate ${space}k $DIR/$tfile failed"
13507         echo "'fallocate -l ${space}k $DIR/$tfile' succeeded"
13508
13509         # get size immediately after fallocate. This should be correctly
13510         # updated
13511         local size=$(stat -c '%s' $DIR/$tfile)
13512         local used=$(( $(stat -c '%b * %B' $DIR/$tfile) / 1024))
13513
13514         # Sleep for a while for statfs to get updated. And not pull from cache.
13515         sleep 2
13516
13517         echo "df after fallocate:"
13518         $LFS df
13519
13520         (( size / 1024 == space )) || error "size $size != requested $space"
13521         [ "$ost1_FSTYPE" != ldiskfs ] || (( used >= space )) ||
13522                 error "used $used < space $space"
13523
13524         rm $DIR/$tfile || error "rm failed"
13525         sync
13526         wait_delete_completed
13527
13528         echo "df after unlink:"
13529         $LFS df
13530 }
13531 run_test 150e "Verify 90% of available OST space consumed by fallocate"
13532
13533 #LU-2902 roc_hit was not able to read all values from lproc
13534 function roc_hit_init() {
13535         local list=$(comma_list $(osts_nodes))
13536         local dir=$DIR/$tdir-check
13537         local file=$dir/$tfile
13538         local BEFORE
13539         local AFTER
13540         local idx
13541
13542         test_mkdir $dir
13543         #use setstripe to do a write to every ost
13544         for i in $(seq 0 $((OSTCOUNT-1))); do
13545                 $LFS setstripe -c 1 -i $i $dir || error "$LFS setstripe $file failed"
13546                 dd if=/dev/urandom of=$file bs=4k count=4 2>&1 > /dev/null
13547                 idx=$(printf %04x $i)
13548                 BEFORE=$(get_osd_param $list *OST*$idx stats |
13549                         awk '$1 == "cache_access" {sum += $7}
13550                                 END { printf("%0.0f", sum) }')
13551
13552                 cancel_lru_locks osc
13553                 cat $file >/dev/null
13554
13555                 AFTER=$(get_osd_param $list *OST*$idx stats |
13556                         awk '$1 == "cache_access" {sum += $7}
13557                                 END { printf("%0.0f", sum) }')
13558
13559                 echo BEFORE:$BEFORE AFTER:$AFTER
13560                 if ! let "AFTER - BEFORE == 4"; then
13561                         rm -rf $dir
13562                         error "roc_hit is not safe to use"
13563                 fi
13564                 rm $file
13565         done
13566
13567         rm -rf $dir
13568 }
13569
13570 function roc_hit() {
13571         local list=$(comma_list $(osts_nodes))
13572         echo $(get_osd_param $list '' stats |
13573                 awk '$1 == "cache_hit" {sum += $7}
13574                         END { printf("%0.0f", sum) }')
13575 }
13576
13577 function set_cache() {
13578         local on=1
13579
13580         if [ "$2" == "off" ]; then
13581                 on=0;
13582         fi
13583         local list=$(comma_list $(osts_nodes))
13584         set_osd_param $list '' $1_cache_enable $on
13585
13586         cancel_lru_locks osc
13587 }
13588
13589 test_151() {
13590         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13591         remote_ost_nodsh && skip "remote OST with nodsh"
13592
13593         local CPAGES=3
13594         local list=$(comma_list $(osts_nodes))
13595
13596         # check whether obdfilter is cache capable at all
13597         if ! get_osd_param $list '' read_cache_enable >/dev/null; then
13598                 skip "not cache-capable obdfilter"
13599         fi
13600
13601         # check cache is enabled on all obdfilters
13602         if get_osd_param $list '' read_cache_enable | grep 0; then
13603                 skip "oss cache is disabled"
13604         fi
13605
13606         set_osd_param $list '' writethrough_cache_enable 1
13607
13608         # check write cache is enabled on all obdfilters
13609         if get_osd_param $list '' writethrough_cache_enable | grep 0; then
13610                 skip "oss write cache is NOT enabled"
13611         fi
13612
13613         roc_hit_init
13614
13615         #define OBD_FAIL_OBD_NO_LRU  0x609
13616         do_nodes $list $LCTL set_param fail_loc=0x609
13617
13618         # pages should be in the case right after write
13619         dd if=/dev/urandom of=$DIR/$tfile bs=4k count=$CPAGES ||
13620                 error "dd failed"
13621
13622         local BEFORE=$(roc_hit)
13623         cancel_lru_locks osc
13624         cat $DIR/$tfile >/dev/null
13625         local AFTER=$(roc_hit)
13626
13627         do_nodes $list $LCTL set_param fail_loc=0
13628
13629         if ! let "AFTER - BEFORE == CPAGES"; then
13630                 error "NOT IN CACHE: before: $BEFORE, after: $AFTER"
13631         fi
13632
13633         cancel_lru_locks osc
13634         # invalidates OST cache
13635         do_nodes $list "echo 1 > /proc/sys/vm/drop_caches"
13636         set_osd_param $list '' read_cache_enable 0
13637         cat $DIR/$tfile >/dev/null
13638
13639         # now data shouldn't be found in the cache
13640         BEFORE=$(roc_hit)
13641         cancel_lru_locks osc
13642         cat $DIR/$tfile >/dev/null
13643         AFTER=$(roc_hit)
13644         if let "AFTER - BEFORE != 0"; then
13645                 error "IN CACHE: before: $BEFORE, after: $AFTER"
13646         fi
13647
13648         set_osd_param $list '' read_cache_enable 1
13649         rm -f $DIR/$tfile
13650 }
13651 run_test 151 "test cache on oss and controls ==============================="
13652
13653 test_152() {
13654         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13655
13656         local TF="$TMP/$tfile"
13657
13658         # simulate ENOMEM during write
13659 #define OBD_FAIL_OST_NOMEM      0x226
13660         lctl set_param fail_loc=0x80000226
13661         dd if=/dev/urandom of=$TF bs=6096 count=1 || error "dd failed"
13662         cp $TF $DIR/$tfile
13663         sync || error "sync failed"
13664         lctl set_param fail_loc=0
13665
13666         # discard client's cache
13667         cancel_lru_locks osc
13668
13669         # simulate ENOMEM during read
13670         lctl set_param fail_loc=0x80000226
13671         cmp $TF $DIR/$tfile || error "cmp failed"
13672         lctl set_param fail_loc=0
13673
13674         rm -f $TF
13675 }
13676 run_test 152 "test read/write with enomem ============================"
13677
13678 test_153() {
13679         $MULTIOP $DIR/$tfile Ow4096Ycu || error "multiop failed"
13680 }
13681 run_test 153 "test if fdatasync does not crash ======================="
13682
13683 dot_lustre_fid_permission_check() {
13684         local fid=$1
13685         local ffid=$MOUNT/.lustre/fid/$fid
13686         local test_dir=$2
13687
13688         echo "stat fid $fid"
13689         stat $ffid > /dev/null || error "stat $ffid failed."
13690         echo "touch fid $fid"
13691         touch $ffid || error "touch $ffid failed."
13692         echo "write to fid $fid"
13693         cat /etc/hosts > $ffid || error "write $ffid failed."
13694         echo "read fid $fid"
13695         diff /etc/hosts $ffid || error "read $ffid failed."
13696         echo "append write to fid $fid"
13697         cat /etc/hosts >> $ffid || error "append write $ffid failed."
13698         echo "rename fid $fid"
13699         mv $ffid $test_dir/$tfile.1 &&
13700                 error "rename $ffid to $tfile.1 should fail."
13701         touch $test_dir/$tfile.1
13702         mv $test_dir/$tfile.1 $ffid &&
13703                 error "rename $tfile.1 to $ffid should fail."
13704         rm -f $test_dir/$tfile.1
13705         echo "truncate fid $fid"
13706         $TRUNCATE $ffid 777 || error "truncate $ffid failed."
13707         echo "link fid $fid"
13708         ln -f $ffid $test_dir/tfile.lnk || error "link $ffid failed."
13709         if [[ $($LCTL get_param -n mdc.*-mdc-*.connect_flags) =~ acl ]]; then
13710                 echo "setfacl fid $fid"
13711                 setfacl -R -m u:bin:rwx $ffid || error "setfacl $ffid failed."
13712                 echo "getfacl fid $fid"
13713                 getfacl $ffid >/dev/null || error "getfacl $ffid failed."
13714         fi
13715         echo "unlink fid $fid"
13716         unlink $MOUNT/.lustre/fid/$fid && error "unlink $ffid should fail."
13717         echo "mknod fid $fid"
13718         mknod $ffid c 1 3 && error "mknod $ffid should fail."
13719
13720         fid=[0xf00000400:0x1:0x0]
13721         ffid=$MOUNT/.lustre/fid/$fid
13722
13723         echo "stat non-exist fid $fid"
13724         stat $ffid > /dev/null && error "stat non-exist $ffid should fail."
13725         echo "write to non-exist fid $fid"
13726         cat /etc/hosts > $ffid && error "write non-exist $ffid should fail."
13727         echo "link new fid $fid"
13728         ln $test_dir/$tfile $ffid && error "link $ffid should fail."
13729
13730         mkdir -p $test_dir/$tdir
13731         touch $test_dir/$tdir/$tfile
13732         fid=$($LFS path2fid $test_dir/$tdir)
13733         rc=$?
13734         [ $rc -ne 0 ] &&
13735                 error "error: could not get fid for $test_dir/$dir/$tfile."
13736
13737         ffid=$MOUNT/.lustre/fid/$fid
13738
13739         echo "ls $fid"
13740         ls $ffid > /dev/null || error "ls $ffid failed."
13741         echo "touch $fid/$tfile.1"
13742         touch $ffid/$tfile.1 || error "touch $ffid/$tfile.1 failed."
13743
13744         echo "touch $MOUNT/.lustre/fid/$tfile"
13745         touch $MOUNT/.lustre/fid/$tfile && \
13746                 error "touch $MOUNT/.lustre/fid/$tfile should fail."
13747
13748         echo "setxattr to $MOUNT/.lustre/fid"
13749         setfattr -n trusted.name1 -v value1 $MOUNT/.lustre/fid
13750
13751         echo "listxattr for $MOUNT/.lustre/fid"
13752         getfattr -d -m "^trusted" $MOUNT/.lustre/fid
13753
13754         echo "delxattr from $MOUNT/.lustre/fid"
13755         setfattr -x trusted.name1 $MOUNT/.lustre/fid
13756
13757         echo "touch invalid fid: $MOUNT/.lustre/fid/[0x200000400:0x2:0x3]"
13758         touch $MOUNT/.lustre/fid/[0x200000400:0x2:0x3] &&
13759                 error "touch invalid fid should fail."
13760
13761         echo "touch non-normal fid: $MOUNT/.lustre/fid/[0x1:0x2:0x0]"
13762         touch $MOUNT/.lustre/fid/[0x1:0x2:0x0] &&
13763                 error "touch non-normal fid should fail."
13764
13765         echo "rename $tdir to $MOUNT/.lustre/fid"
13766         mrename $test_dir/$tdir $MOUNT/.lustre/fid &&
13767                 error "rename to $MOUNT/.lustre/fid should fail."
13768
13769         if [ $MDS1_VERSION -ge $(version_code 2.3.51) ]
13770         then            # LU-3547
13771                 local old_obf_mode=$(stat --format="%a" $DIR/.lustre/fid)
13772                 local new_obf_mode=777
13773
13774                 echo "change mode of $DIR/.lustre/fid to $new_obf_mode"
13775                 chmod $new_obf_mode $DIR/.lustre/fid ||
13776                         error "chmod $new_obf_mode $DIR/.lustre/fid failed"
13777
13778                 local obf_mode=$(stat --format=%a $DIR/.lustre/fid)
13779                 [ $obf_mode -eq $new_obf_mode ] ||
13780                         error "stat $DIR/.lustre/fid returned wrong mode $obf_mode"
13781
13782                 echo "restore mode of $DIR/.lustre/fid to $old_obf_mode"
13783                 chmod $old_obf_mode $DIR/.lustre/fid ||
13784                         error "chmod $old_obf_mode $DIR/.lustre/fid failed"
13785         fi
13786
13787         $OPENFILE -f O_LOV_DELAY_CREATE:O_CREAT $test_dir/$tfile-2
13788         fid=$($LFS path2fid $test_dir/$tfile-2)
13789
13790         if [ $MDS1_VERSION -ge $(version_code 2.6.50) ]
13791         then # LU-5424
13792                 echo "cp /etc/passwd $MOUNT/.lustre/fid/$fid"
13793                 cp /etc/passwd $MOUNT/.lustre/fid/$fid ||
13794                         error "create lov data thru .lustre failed"
13795         fi
13796         echo "cp /etc/passwd $test_dir/$tfile-2"
13797         cp /etc/passwd $test_dir/$tfile-2 ||
13798                 error "copy to $test_dir/$tfile-2 failed."
13799         echo "diff /etc/passwd $MOUNT/.lustre/fid/$fid"
13800         diff /etc/passwd $MOUNT/.lustre/fid/$fid ||
13801                 error "diff /etc/passwd $MOUNT/.lustre/fid/$fid failed."
13802
13803         rm -rf $test_dir/tfile.lnk
13804         rm -rf $test_dir/$tfile-2
13805 }
13806
13807 test_154A() {
13808         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
13809                 skip "Need MDS version at least 2.4.1"
13810
13811         local tf=$DIR/$tfile
13812         touch $tf
13813
13814         local fid=$($LFS path2fid $tf)
13815         [ -z "$fid" ] && error "path2fid unable to get $tf FID"
13816
13817         # check that we get the same pathname back
13818         local rootpath
13819         local found
13820         for rootpath in "$MOUNT" "$MOUNT///" "$MOUNT/$tfile"; do
13821                 echo "$rootpath $fid"
13822                 found=$($LFS fid2path $rootpath "$fid")
13823                 [ -z "$found" ] && error "fid2path unable to get '$fid' path"
13824                 [ "$found" == "$tf" ] || error "fid2path $found != $tf"
13825         done
13826
13827         # check wrong root path format
13828         rootpath=$MOUNT"_wrong"
13829         found=$($LFS fid2path $rootpath "$fid")
13830         [ -z "$found" ] || error "should fail ($rootpath != $MOUNT)"
13831 }
13832 run_test 154A "lfs path2fid and fid2path basic checks"
13833
13834 test_154B() {
13835         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
13836                 skip "Need MDS version at least 2.4.1"
13837
13838         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
13839         touch $DIR/$tdir/$tfile || error "touch $DIR/$tdir/$tfile failed"
13840         local linkea=$($LL_DECODE_LINKEA $DIR/$tdir/$tfile | grep 'pfid')
13841         [ -z "$linkea" ] && error "decode linkea $DIR/$tdir/$tfile failed"
13842
13843         local name=$(echo $linkea | awk '/pfid/ {print $5}' | sed -e "s/'//g")
13844         local PFID=$(echo $linkea | awk '/pfid/ {print $3}' | sed -e "s/,//g")
13845
13846         # check that we get the same pathname
13847         echo "PFID: $PFID, name: $name"
13848         local FOUND=$($LFS fid2path $MOUNT "$PFID")
13849         [ -z "$FOUND" ] && error "fid2path unable to get $PFID path"
13850         [ "$FOUND/$name" != "$DIR/$tdir/$tfile" ] &&
13851                 error "ll_decode_linkea has $FOUND/$name != $DIR/$tdir/$tfile"
13852
13853         rm -rf $DIR/$tdir || error "Can not delete directory $DIR/$tdir"
13854 }
13855 run_test 154B "verify the ll_decode_linkea tool"
13856
13857 test_154a() {
13858         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13859         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
13860         [[ $MDS1_VERSION -ge $(version_code 2.2.51) ]] ||
13861                 skip "Need MDS version at least 2.2.51"
13862         [ -z "$(which setfacl)" ] && skip_env "must have setfacl tool"
13863
13864         cp /etc/hosts $DIR/$tfile
13865
13866         fid=$($LFS path2fid $DIR/$tfile)
13867         rc=$?
13868         [ $rc -ne 0 ] && error "error: could not get fid for $DIR/$tfile."
13869
13870         dot_lustre_fid_permission_check "$fid" $DIR ||
13871                 error "dot lustre permission check $fid failed"
13872
13873         ls -a $MOUNT | grep "\.lustre" && error ".lustre should not be listed"
13874
13875         rm -rf $MOUNT/.lustre && error ".lustre is not allowed to be unlinked"
13876
13877         touch $MOUNT/.lustre/file &&
13878                 error "creation is not allowed under .lustre"
13879
13880         mkdir $MOUNT/.lustre/dir &&
13881                 error "mkdir is not allowed under .lustre"
13882
13883         rm -rf $DIR/$tfile
13884 }
13885 run_test 154a "Open-by-FID"
13886
13887 test_154b() {
13888         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13889         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
13890         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
13891         [[ $MDS1_VERSION -ge $(version_code 2.2.51) ]] ||
13892                 skip "Need MDS version at least 2.2.51"
13893
13894         local remote_dir=$DIR/$tdir/remote_dir
13895         local MDTIDX=1
13896         local rc=0
13897
13898         mkdir -p $DIR/$tdir
13899         $LFS mkdir -i $MDTIDX $remote_dir ||
13900                 error "create remote directory failed"
13901
13902         cp /etc/hosts $remote_dir/$tfile
13903
13904         fid=$($LFS path2fid $remote_dir/$tfile)
13905         rc=$?
13906         [ $rc -ne 0 ] && error "error: could not get fid for $remote_dir/$tfile"
13907
13908         dot_lustre_fid_permission_check "$fid" $remote_dir ||
13909                 error "dot lustre permission check $fid failed"
13910         rm -rf $DIR/$tdir
13911 }
13912 run_test 154b "Open-by-FID for remote directory"
13913
13914 test_154c() {
13915         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
13916                 skip "Need MDS version at least 2.4.1"
13917
13918         touch $DIR/$tfile.1 $DIR/$tfile.2 $DIR/$tfile.3
13919         local FID1=$($LFS path2fid $DIR/$tfile.1)
13920         local FID2=$($LFS path2fid $DIR/$tfile.2)
13921         local FID3=$($LFS path2fid $DIR/$tfile.3)
13922
13923         local N=1
13924         $LFS path2fid $DIR/$tfile.[123] | while read PATHNAME FID; do
13925                 [ "$PATHNAME" = "$DIR/$tfile.$N:" ] ||
13926                         error "path2fid pathname $PATHNAME != $DIR/$tfile.$N:"
13927                 local want=FID$N
13928                 [ "$FID" = "${!want}" ] ||
13929                         error "path2fid $PATHNAME FID $FID != FID$N ${!want}"
13930                 N=$((N + 1))
13931         done
13932
13933         $LFS fid2path $MOUNT "$FID1" "$FID2" "$FID3" | while read PATHNAME;
13934         do
13935                 [ "$PATHNAME" = "$DIR/$tfile.$N" ] ||
13936                         error "fid2path pathname $PATHNAME != $DIR/$tfile.$N:"
13937                 N=$((N + 1))
13938         done
13939 }
13940 run_test 154c "lfs path2fid and fid2path multiple arguments"
13941
13942 test_154d() {
13943         remote_mds_nodsh && skip "remote MDS with nodsh"
13944         [[ $MDS1_VERSION -lt $(version_code 2.5.53) ]] &&
13945                 skip "Need MDS version at least 2.5.53"
13946
13947         if remote_mds; then
13948                 nid=$($LCTL list_nids | sed  "s/\./\\\./g")
13949         else
13950                 nid="0@lo"
13951         fi
13952         local proc_ofile="mdt.*.exports.'$nid'.open_files"
13953         local fd
13954         local cmd
13955
13956         rm -f $DIR/$tfile
13957         touch $DIR/$tfile
13958
13959         local fid=$($LFS path2fid $DIR/$tfile)
13960         # Open the file
13961         fd=$(free_fd)
13962         cmd="exec $fd<$DIR/$tfile"
13963         eval $cmd
13964         local fid_list=$(do_facet $SINGLEMDS $LCTL get_param $proc_ofile)
13965         echo "$fid_list" | grep "$fid"
13966         rc=$?
13967
13968         cmd="exec $fd>/dev/null"
13969         eval $cmd
13970         if [ $rc -ne 0 ]; then
13971                 error "FID $fid not found in open files list $fid_list"
13972         fi
13973 }
13974 run_test 154d "Verify open file fid"
13975
13976 test_154e()
13977 {
13978         [[ $MDS1_VERSION -lt $(version_code 2.6.50) ]] &&
13979                 skip "Need MDS version at least 2.6.50"
13980
13981         if ls -a $MOUNT | grep -q '^\.lustre$'; then
13982                 error ".lustre returned by readdir"
13983         fi
13984 }
13985 run_test 154e ".lustre is not returned by readdir"
13986
13987 test_154f() {
13988         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
13989
13990         # create parent directory on a single MDT to avoid cross-MDT hardlinks
13991         test_mkdir -p -c1 $DIR/$tdir/d
13992         # test dirs inherit from its stripe
13993         mkdir -p $DIR/$tdir/d/foo1 || error "mkdir error"
13994         mkdir -p $DIR/$tdir/d/foo2 || error "mkdir error"
13995         cp /etc/hosts $DIR/$tdir/d/foo1/$tfile
13996         ln $DIR/$tdir/d/foo1/$tfile $DIR/$tdir/d/foo2/link
13997         touch $DIR/f
13998
13999         # get fid of parents
14000         local FID0=$($LFS path2fid $DIR/$tdir/d)
14001         local FID1=$($LFS path2fid $DIR/$tdir/d/foo1)
14002         local FID2=$($LFS path2fid $DIR/$tdir/d/foo2)
14003         local FID3=$($LFS path2fid $DIR)
14004
14005         # check that path2fid --parents returns expected <parent_fid>/name
14006         # 1) test for a directory (single parent)
14007         local parent=$($LFS path2fid --parents $DIR/$tdir/d/foo1)
14008         [ "$parent" == "$FID0/foo1" ] ||
14009                 error "expected parent: $FID0/foo1, got: $parent"
14010
14011         # 2) test for a file with nlink > 1 (multiple parents)
14012         parent=$($LFS path2fid --parents $DIR/$tdir/d/foo1/$tfile)
14013         echo "$parent" | grep -F "$FID1/$tfile" ||
14014                 error "$FID1/$tfile not returned in parent list"
14015         echo "$parent" | grep -F "$FID2/link" ||
14016                 error "$FID2/link not returned in parent list"
14017
14018         # 3) get parent by fid
14019         local file_fid=$($LFS path2fid $DIR/$tdir/d/foo1/$tfile)
14020         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
14021         echo "$parent" | grep -F "$FID1/$tfile" ||
14022                 error "$FID1/$tfile not returned in parent list (by fid)"
14023         echo "$parent" | grep -F "$FID2/link" ||
14024                 error "$FID2/link not returned in parent list (by fid)"
14025
14026         # 4) test for entry in root directory
14027         parent=$($LFS path2fid --parents $DIR/f)
14028         echo "$parent" | grep -F "$FID3/f" ||
14029                 error "$FID3/f not returned in parent list"
14030
14031         # 5) test it on root directory
14032         [ -z "$($LFS path2fid --parents $MOUNT 2>/dev/null)" ] ||
14033                 error "$MOUNT should not have parents"
14034
14035         # enable xattr caching and check that linkea is correctly updated
14036         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
14037         save_lustre_params client "llite.*.xattr_cache" > $save
14038         lctl set_param llite.*.xattr_cache 1
14039
14040         # 6.1) linkea update on rename
14041         mv $DIR/$tdir/d/foo1/$tfile $DIR/$tdir/d/foo2/$tfile.moved
14042
14043         # get parents by fid
14044         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
14045         # foo1 should no longer be returned in parent list
14046         echo "$parent" | grep -F "$FID1" &&
14047                 error "$FID1 should no longer be in parent list"
14048         # the new path should appear
14049         echo "$parent" | grep -F "$FID2/$tfile.moved" ||
14050                 error "$FID2/$tfile.moved is not in parent list"
14051
14052         # 6.2) linkea update on unlink
14053         rm -f $DIR/$tdir/d/foo2/link
14054         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
14055         # foo2/link should no longer be returned in parent list
14056         echo "$parent" | grep -F "$FID2/link" &&
14057                 error "$FID2/link should no longer be in parent list"
14058         true
14059
14060         rm -f $DIR/f
14061         restore_lustre_params < $save
14062         rm -f $save
14063 }
14064 run_test 154f "get parent fids by reading link ea"
14065
14066 test_154g()
14067 {
14068         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
14069         [[ $MDS1_VERSION -ge $(version_code 2.6.92) &&
14070            $CLIENT_VERSION -gt $(version_code 2.6.99) ]] ||
14071                 skip "Need MDS version at least 2.6.92"
14072
14073         mkdir -p $DIR/$tdir
14074         llapi_fid_test -d $DIR/$tdir
14075 }
14076 run_test 154g "various llapi FID tests"
14077
14078 test_155_small_load() {
14079     local temp=$TMP/$tfile
14080     local file=$DIR/$tfile
14081
14082     dd if=/dev/urandom of=$temp bs=6096 count=1 || \
14083         error "dd of=$temp bs=6096 count=1 failed"
14084     cp $temp $file
14085     cancel_lru_locks $OSC
14086     cmp $temp $file || error "$temp $file differ"
14087
14088     $TRUNCATE $temp 6000
14089     $TRUNCATE $file 6000
14090     cmp $temp $file || error "$temp $file differ (truncate1)"
14091
14092     echo "12345" >>$temp
14093     echo "12345" >>$file
14094     cmp $temp $file || error "$temp $file differ (append1)"
14095
14096     echo "12345" >>$temp
14097     echo "12345" >>$file
14098     cmp $temp $file || error "$temp $file differ (append2)"
14099
14100     rm -f $temp $file
14101     true
14102 }
14103
14104 test_155_big_load() {
14105         remote_ost_nodsh && skip "remote OST with nodsh"
14106
14107         local temp=$TMP/$tfile
14108         local file=$DIR/$tfile
14109
14110         free_min_max
14111         local cache_size=$(do_facet ost$((MAXI+1)) \
14112                 "awk '/cache/ {sum+=\\\$4} END {print sum}' /proc/cpuinfo")
14113         local large_file_size=$((cache_size * 2))
14114
14115         echo "OSS cache size: $cache_size KB"
14116         echo "Large file size: $large_file_size KB"
14117
14118         [ $MAXV -le $large_file_size ] &&
14119                 skip_env "max available OST size needs > $large_file_size KB"
14120
14121         $LFS setstripe $file -c 1 -i $MAXI || error "$LFS setstripe $file failed"
14122
14123         dd if=/dev/urandom of=$temp bs=$large_file_size count=1k ||
14124                 error "dd of=$temp bs=$large_file_size count=1k failed"
14125         cp $temp $file
14126         ls -lh $temp $file
14127         cancel_lru_locks osc
14128         cmp $temp $file || error "$temp $file differ"
14129
14130         rm -f $temp $file
14131         true
14132 }
14133
14134 save_writethrough() {
14135         local facets=$(get_facets OST)
14136
14137         save_lustre_params $facets "osd-*.*.writethrough_cache_enable" > $1
14138 }
14139
14140 test_155a() {
14141         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14142
14143         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
14144
14145         save_writethrough $p
14146
14147         set_cache read on
14148         set_cache writethrough on
14149         test_155_small_load
14150         restore_lustre_params < $p
14151         rm -f $p
14152 }
14153 run_test 155a "Verify small file correctness: read cache:on write_cache:on"
14154
14155 test_155b() {
14156         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14157
14158         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
14159
14160         save_writethrough $p
14161
14162         set_cache read on
14163         set_cache writethrough off
14164         test_155_small_load
14165         restore_lustre_params < $p
14166         rm -f $p
14167 }
14168 run_test 155b "Verify small file correctness: read cache:on write_cache:off"
14169
14170 test_155c() {
14171         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14172
14173         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
14174
14175         save_writethrough $p
14176
14177         set_cache read off
14178         set_cache writethrough on
14179         test_155_small_load
14180         restore_lustre_params < $p
14181         rm -f $p
14182 }
14183 run_test 155c "Verify small file correctness: read cache:off write_cache:on"
14184
14185 test_155d() {
14186         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14187
14188         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
14189
14190         save_writethrough $p
14191
14192         set_cache read off
14193         set_cache writethrough off
14194         test_155_small_load
14195         restore_lustre_params < $p
14196         rm -f $p
14197 }
14198 run_test 155d "Verify small file correctness: read cache:off write_cache:off"
14199
14200 test_155e() {
14201         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14202
14203         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
14204
14205         save_writethrough $p
14206
14207         set_cache read on
14208         set_cache writethrough on
14209         test_155_big_load
14210         restore_lustre_params < $p
14211         rm -f $p
14212 }
14213 run_test 155e "Verify big file correctness: read cache:on write_cache:on"
14214
14215 test_155f() {
14216         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14217
14218         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
14219
14220         save_writethrough $p
14221
14222         set_cache read on
14223         set_cache writethrough off
14224         test_155_big_load
14225         restore_lustre_params < $p
14226         rm -f $p
14227 }
14228 run_test 155f "Verify big file correctness: read cache:on write_cache:off"
14229
14230 test_155g() {
14231         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14232
14233         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
14234
14235         save_writethrough $p
14236
14237         set_cache read off
14238         set_cache writethrough on
14239         test_155_big_load
14240         restore_lustre_params < $p
14241         rm -f $p
14242 }
14243 run_test 155g "Verify big file correctness: read cache:off write_cache:on"
14244
14245 test_155h() {
14246         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14247
14248         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
14249
14250         save_writethrough $p
14251
14252         set_cache read off
14253         set_cache writethrough off
14254         test_155_big_load
14255         restore_lustre_params < $p
14256         rm -f $p
14257 }
14258 run_test 155h "Verify big file correctness: read cache:off write_cache:off"
14259
14260 test_156() {
14261         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14262         remote_ost_nodsh && skip "remote OST with nodsh"
14263         [ $OST1_VERSION -lt $(version_code 2.6.93) ] &&
14264                 skip "stats not implemented on old servers"
14265         [ "$ost1_FSTYPE" = "zfs" ] &&
14266                 skip "LU-1956/LU-2261: stats not implemented on OSD ZFS"
14267
14268         local CPAGES=3
14269         local BEFORE
14270         local AFTER
14271         local file="$DIR/$tfile"
14272         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
14273
14274         save_writethrough $p
14275         roc_hit_init
14276
14277         log "Turn on read and write cache"
14278         set_cache read on
14279         set_cache writethrough on
14280
14281         log "Write data and read it back."
14282         log "Read should be satisfied from the cache."
14283         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
14284         BEFORE=$(roc_hit)
14285         cancel_lru_locks osc
14286         cat $file >/dev/null
14287         AFTER=$(roc_hit)
14288         if ! let "AFTER - BEFORE == CPAGES"; then
14289                 error "NOT IN CACHE (2): before: $BEFORE, after: $AFTER"
14290         else
14291                 log "cache hits: before: $BEFORE, after: $AFTER"
14292         fi
14293
14294         log "Read again; it should be satisfied from the cache."
14295         BEFORE=$AFTER
14296         cancel_lru_locks osc
14297         cat $file >/dev/null
14298         AFTER=$(roc_hit)
14299         if ! let "AFTER - BEFORE == CPAGES"; then
14300                 error "NOT IN CACHE (3): before: $BEFORE, after: $AFTER"
14301         else
14302                 log "cache hits:: before: $BEFORE, after: $AFTER"
14303         fi
14304
14305         log "Turn off the read cache and turn on the write cache"
14306         set_cache read off
14307         set_cache writethrough on
14308
14309         log "Read again; it should be satisfied from the cache."
14310         BEFORE=$(roc_hit)
14311         cancel_lru_locks osc
14312         cat $file >/dev/null
14313         AFTER=$(roc_hit)
14314         if ! let "AFTER - BEFORE == CPAGES"; then
14315                 error "NOT IN CACHE (4): before: $BEFORE, after: $AFTER"
14316         else
14317                 log "cache hits:: before: $BEFORE, after: $AFTER"
14318         fi
14319
14320         if [ $OST1_VERSION -lt $(version_code 2.12.55) ]; then
14321                 # > 2.12.56 uses pagecache if cached
14322                 log "Read again; it should not be satisfied from the cache."
14323                 BEFORE=$AFTER
14324                 cancel_lru_locks osc
14325                 cat $file >/dev/null
14326                 AFTER=$(roc_hit)
14327                 if ! let "AFTER - BEFORE == 0"; then
14328                         error "IN CACHE (5): before: $BEFORE, after: $AFTER"
14329                 else
14330                         log "cache hits:: before: $BEFORE, after: $AFTER"
14331                 fi
14332         fi
14333
14334         log "Write data and read it back."
14335         log "Read should be satisfied from the cache."
14336         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
14337         BEFORE=$(roc_hit)
14338         cancel_lru_locks osc
14339         cat $file >/dev/null
14340         AFTER=$(roc_hit)
14341         if ! let "AFTER - BEFORE == CPAGES"; then
14342                 error "NOT IN CACHE (6): before: $BEFORE, after: $AFTER"
14343         else
14344                 log "cache hits:: before: $BEFORE, after: $AFTER"
14345         fi
14346
14347         if [ $OST1_VERSION -lt $(version_code 2.12.55) ]; then
14348                 # > 2.12.56 uses pagecache if cached
14349                 log "Read again; it should not be satisfied from the cache."
14350                 BEFORE=$AFTER
14351                 cancel_lru_locks osc
14352                 cat $file >/dev/null
14353                 AFTER=$(roc_hit)
14354                 if ! let "AFTER - BEFORE == 0"; then
14355                         error "IN CACHE (7): before: $BEFORE, after: $AFTER"
14356                 else
14357                         log "cache hits:: before: $BEFORE, after: $AFTER"
14358                 fi
14359         fi
14360
14361         log "Turn off read and write cache"
14362         set_cache read off
14363         set_cache writethrough off
14364
14365         log "Write data and read it back"
14366         log "It should not be satisfied from the cache."
14367         rm -f $file
14368         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
14369         cancel_lru_locks osc
14370         BEFORE=$(roc_hit)
14371         cat $file >/dev/null
14372         AFTER=$(roc_hit)
14373         if ! let "AFTER - BEFORE == 0"; then
14374                 error_ignore bz20762 "IN CACHE (8):before:$BEFORE,after:$AFTER"
14375         else
14376                 log "cache hits:: before: $BEFORE, after: $AFTER"
14377         fi
14378
14379         log "Turn on the read cache and turn off the write cache"
14380         set_cache read on
14381         set_cache writethrough off
14382
14383         log "Write data and read it back"
14384         log "It should not be satisfied from the cache."
14385         rm -f $file
14386         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
14387         BEFORE=$(roc_hit)
14388         cancel_lru_locks osc
14389         cat $file >/dev/null
14390         AFTER=$(roc_hit)
14391         if ! let "AFTER - BEFORE == 0"; then
14392                 error_ignore bz20762 "IN CACHE (9):before:$BEFORE,after:$AFTER"
14393         else
14394                 log "cache hits:: before: $BEFORE, after: $AFTER"
14395         fi
14396
14397         log "Read again; it should be satisfied from the cache."
14398         BEFORE=$(roc_hit)
14399         cancel_lru_locks osc
14400         cat $file >/dev/null
14401         AFTER=$(roc_hit)
14402         if ! let "AFTER - BEFORE == CPAGES"; then
14403                 error "NOT IN CACHE (1): before: $BEFORE, after: $AFTER"
14404         else
14405                 log "cache hits:: before: $BEFORE, after: $AFTER"
14406         fi
14407
14408         restore_lustre_params < $p
14409         rm -f $p $file
14410 }
14411 run_test 156 "Verification of tunables"
14412
14413 test_160a() {
14414         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14415         remote_mds_nodsh && skip "remote MDS with nodsh"
14416         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] ||
14417                 skip "Need MDS version at least 2.2.0"
14418
14419         changelog_register || error "changelog_register failed"
14420         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
14421         changelog_users $SINGLEMDS | grep -q $cl_user ||
14422                 error "User $cl_user not found in changelog_users"
14423
14424         # change something
14425         test_mkdir -p $DIR/$tdir/pics/2008/zachy
14426         changelog_clear 0 || error "changelog_clear failed"
14427         touch $DIR/$tdir/pics/2008/zachy/$tfile                 # open 1
14428         cp /etc/hosts $DIR/$tdir/pics/2008/zachy/pic1.jpg       # open 2
14429         mv $DIR/$tdir/pics/2008/zachy $DIR/$tdir/pics/zach
14430         ln $DIR/$tdir/pics/zach/pic1.jpg $DIR/$tdir/pics/2008/portland.jpg
14431         ln -s $DIR/$tdir/pics/2008/portland.jpg $DIR/$tdir/pics/desktop.jpg
14432         rm $DIR/$tdir/pics/desktop.jpg
14433
14434         changelog_dump | tail -10
14435
14436         echo "verifying changelog mask"
14437         changelog_chmask "-MKDIR"
14438         changelog_chmask "-CLOSE"
14439
14440         test_mkdir -p $DIR/$tdir/pics/zach/sofia                # not logged
14441         echo "zzzzzz" > $DIR/$tdir/pics/zach/file               # not logged
14442
14443         changelog_chmask "+MKDIR"
14444         changelog_chmask "+CLOSE"
14445
14446         test_mkdir -p $DIR/$tdir/pics/2008/sofia                # mkdir 1
14447         echo "zzzzzz" > $DIR/$tdir/pics/zach/file               # open 3
14448
14449         changelog_dump | tail -10
14450         MKDIRS=$(changelog_dump | grep -c "MKDIR")
14451         CLOSES=$(changelog_dump | grep -c "CLOSE")
14452         [ $MKDIRS -eq 1 ] || error "MKDIR changelog mask count $MKDIRS != 1"
14453         [ $CLOSES -eq 3 ] || error "CLOSE changelog mask count $CLOSES != 3"
14454
14455         # verify contents
14456         echo "verifying target fid"
14457         local fidc=$(changelog_extract_field "CREAT" "$tfile" "t=")
14458         local fidf=$($LFS path2fid $DIR/$tdir/pics/zach/$tfile)
14459         [ "$fidc" == "$fidf" ] ||
14460                 error "changelog '$tfile' fid $fidc != file fid $fidf"
14461         echo "verifying parent fid"
14462         # The FID returned from the Changelog may be the directory shard on
14463         # a different MDT, and not the FID returned by path2fid on the parent.
14464         # Instead of comparing FIDs, verify that fid2path(fidp) is correct,
14465         # since this is what will matter when recreating this file in the tree.
14466         local fidp=$(changelog_extract_field "CREAT" "$tfile" "p=")
14467         local pathp=$($LFS fid2path $MOUNT "$fidp")
14468         [ "${pathp%/}" == "$DIR/$tdir/pics/zach" ] ||
14469                 error "changelog fid2path($fidc) $pathp != $DIR/$tdir/pics/zach"
14470
14471         echo "getting records for $cl_user"
14472         changelog_users $SINGLEMDS
14473         local user_rec1=$(changelog_user_rec $SINGLEMDS $cl_user)
14474         local nclr=3
14475         __changelog_clear $SINGLEMDS $cl_user +$nclr ||
14476                 error "changelog_clear failed"
14477         local user_rec2=$(changelog_user_rec $SINGLEMDS $cl_user)
14478         echo "verifying user clear: $user_rec1 + $nclr == $user_rec2"
14479         [ $user_rec2 == $((user_rec1 + nclr)) ] ||
14480                 error "user index expect $user_rec1 + $nclr != $user_rec2"
14481
14482         local min0_rec=$(changelog_users $SINGLEMDS |
14483                 awk 'min == "" || $2 < min { min = $2 }; END { print min }')
14484         local first_rec=$($LFS changelog $(facet_svc $SINGLEMDS) |
14485                           awk '{ print $1; exit; }')
14486
14487         changelog_dump | tail -n 5
14488         echo "verifying user min purge: $min0_rec + 1 == $first_rec"
14489         [ $first_rec == $((min0_rec + 1)) ] ||
14490                 error "first index should be $min0_rec + 1 not $first_rec"
14491
14492         # LU-3446 changelog index reset on MDT restart
14493         local cur_rec1=$(changelog_users $SINGLEMDS |
14494                          awk '/^current.index:/ { print $NF }')
14495         changelog_clear 0 ||
14496                 error "clear all changelog records for $cl_user failed"
14497         stop $SINGLEMDS || error "Fail to stop $SINGLEMDS"
14498         start $SINGLEMDS $(mdsdevname ${SINGLEMDS//mds/}) $MDS_MOUNT_OPTS ||
14499                 error "Fail to start $SINGLEMDS"
14500         local cur_rec2=$(changelog_users $SINGLEMDS |
14501                          awk '/^current.index:/ { print $NF }')
14502         echo "verifying index survives MDT restart: $cur_rec1 == $cur_rec2"
14503         [ $cur_rec1 == $cur_rec2 ] ||
14504                 error "current index should be $cur_rec1 not $cur_rec2"
14505
14506         echo "verifying users from this test are deregistered"
14507         changelog_deregister || error "changelog_deregister failed"
14508         changelog_users $SINGLEMDS | grep -q $cl_user &&
14509                 error "User '$cl_user' still in changelog_users"
14510
14511         # lctl get_param -n mdd.*.changelog_users
14512         # current index: 144
14513         # ID    index (idle seconds)
14514         # cl3   144 (2)
14515         if ! changelog_users $SINGLEMDS | grep "^cl"; then
14516                 # this is the normal case where all users were deregistered
14517                 # make sure no new records are added when no users are present
14518                 local last_rec1=$(changelog_users $SINGLEMDS |
14519                                   awk '/^current.index:/ { print $NF }')
14520                 touch $DIR/$tdir/chloe
14521                 local last_rec2=$(changelog_users $SINGLEMDS |
14522                                   awk '/^current.index:/ { print $NF }')
14523                 echo "verify changelogs are off: $last_rec1 == $last_rec2"
14524                 [ $last_rec1 == $last_rec2 ] || error "changelogs not off"
14525         else
14526                 # any changelog users must be leftovers from a previous test
14527                 changelog_users $SINGLEMDS
14528                 echo "other changelog users; can't verify off"
14529         fi
14530 }
14531 run_test 160a "changelog sanity"
14532
14533 test_160b() { # LU-3587
14534         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14535         remote_mds_nodsh && skip "remote MDS with nodsh"
14536         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] ||
14537                 skip "Need MDS version at least 2.2.0"
14538
14539         changelog_register || error "changelog_register failed"
14540         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
14541         changelog_users $SINGLEMDS | grep -q $cl_user ||
14542                 error "User '$cl_user' not found in changelog_users"
14543
14544         local longname1=$(str_repeat a 255)
14545         local longname2=$(str_repeat b 255)
14546
14547         cd $DIR
14548         echo "creating very long named file"
14549         touch $longname1 || error "create of '$longname1' failed"
14550         echo "renaming very long named file"
14551         mv $longname1 $longname2
14552
14553         changelog_dump | grep RENME | tail -n 5
14554         rm -f $longname2
14555 }
14556 run_test 160b "Verify that very long rename doesn't crash in changelog"
14557
14558 test_160c() {
14559         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14560         remote_mds_nodsh && skip "remote MDS with nodsh"
14561
14562         [[ $MDS1_VERSION -gt $(version_code 2.5.57) ]] ||
14563                 [[ $MDS1_VERSION -gt $(version_code 2.5.1) &&
14564                    $MDS1_VERSION -lt $(version_code 2.5.50) ]] ||
14565                 skip "Need MDS version at least 2.5.58 or 2.5.2+"
14566
14567         local rc=0
14568
14569         # Registration step
14570         changelog_register || error "changelog_register failed"
14571
14572         rm -rf $DIR/$tdir
14573         mkdir -p $DIR/$tdir
14574         $MCREATE $DIR/$tdir/foo_160c
14575         changelog_chmask "-TRUNC"
14576         $TRUNCATE $DIR/$tdir/foo_160c 200
14577         changelog_chmask "+TRUNC"
14578         $TRUNCATE $DIR/$tdir/foo_160c 199
14579         changelog_dump | tail -n 5
14580         local truncs=$(changelog_dump | tail -n 5 | grep -c TRUNC)
14581         [ $truncs -eq 1 ] || error "TRUNC changelog mask count $truncs != 1"
14582 }
14583 run_test 160c "verify that changelog log catch the truncate event"
14584
14585 test_160d() {
14586         remote_mds_nodsh && skip "remote MDS with nodsh"
14587         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
14588         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14589         [[ $MDS1_VERSION -ge $(version_code 2.7.60) ]] ||
14590                 skip "Need MDS version at least 2.7.60"
14591
14592         # Registration step
14593         changelog_register || error "changelog_register failed"
14594
14595         mkdir -p $DIR/$tdir/migrate_dir
14596         changelog_clear 0 || error "changelog_clear failed"
14597
14598         $LFS migrate -m 1 $DIR/$tdir/migrate_dir || error "migrate fails"
14599         changelog_dump | tail -n 5
14600         local migrates=$(changelog_dump | grep -c "MIGRT")
14601         [ $migrates -eq 1 ] || error "MIGRATE changelog count $migrates != 1"
14602 }
14603 run_test 160d "verify that changelog log catch the migrate event"
14604
14605 test_160e() {
14606         remote_mds_nodsh && skip "remote MDS with nodsh"
14607
14608         # Create a user
14609         changelog_register || error "changelog_register failed"
14610
14611         # Delete a future user (expect fail)
14612         local MDT0=$(facet_svc $SINGLEMDS)
14613         do_facet $SINGLEMDS $LCTL --device $MDT0 changelog_deregister "cl77"
14614         local rc=$?
14615
14616         if [ $rc -eq 0 ]; then
14617                 error "Deleted non-existant user cl77"
14618         elif [ $rc -ne 2 ]; then
14619                 error "changelog_deregister failed with $rc, expect 2 (ENOENT)"
14620         fi
14621
14622         # Clear to a bad index (1 billion should be safe)
14623         $LFS changelog_clear $MDT0 "${CL_USERS[$SINGLEMDS]%% *}" 1000000000
14624         rc=$?
14625
14626         if [ $rc -eq 0 ]; then
14627                 error "Successfully cleared to invalid CL index"
14628         elif [ $rc -ne 22 ]; then
14629                 error "changelog_clear failed with $rc, expected 22 (EINVAL)"
14630         fi
14631 }
14632 run_test 160e "changelog negative testing (should return errors)"
14633
14634 test_160f() {
14635         remote_mds_nodsh && skip "remote MDS with nodsh" && return
14636         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
14637                 skip "Need MDS version at least 2.10.56"
14638
14639         local mdts=$(comma_list $(mdts_nodes))
14640
14641         # Create a user
14642         changelog_register || error "first changelog_register failed"
14643         changelog_register || error "second changelog_register failed"
14644         local cl_users
14645         declare -A cl_user1
14646         declare -A cl_user2
14647         local user_rec1
14648         local user_rec2
14649         local i
14650
14651         # generate some changelog records to accumulate on each MDT
14652         # use fnv1a because created files should be evenly distributed
14653         test_mkdir -c $MDSCOUNT -H fnv_1a_64 $DIR/$tdir ||
14654                 error "test_mkdir $tdir failed"
14655         log "$(date +%s): creating first files"
14656         createmany -m $DIR/$tdir/$tfile $((MDSCOUNT * 2)) ||
14657                 error "create $DIR/$tdir/$tfile failed"
14658
14659         # check changelogs have been generated
14660         local start=$SECONDS
14661         local idle_time=$((MDSCOUNT * 5 + 5))
14662         local nbcl=$(changelog_dump | wc -l)
14663         [[ $nbcl -eq 0 ]] && error "no changelogs found"
14664
14665         for param in "changelog_max_idle_time=$idle_time" \
14666                      "changelog_gc=1" \
14667                      "changelog_min_gc_interval=2" \
14668                      "changelog_min_free_cat_entries=3"; do
14669                 local MDT0=$(facet_svc $SINGLEMDS)
14670                 local var="${param%=*}"
14671                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
14672
14673                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
14674                 do_nodes $mdts $LCTL set_param mdd.*.$param
14675         done
14676
14677         # force cl_user2 to be idle (1st part), but also cancel the
14678         # cl_user1 records so that it is not evicted later in the test.
14679         local sleep1=$((idle_time / 2))
14680         echo "$(date +%s): sleep1 $sleep1/${idle_time}s"
14681         sleep $sleep1
14682
14683         # simulate changelog catalog almost full
14684         #define OBD_FAIL_CAT_FREE_RECORDS       0x1313
14685         do_nodes $mdts $LCTL set_param fail_loc=0x1313 fail_val=3
14686
14687         for i in $(seq $MDSCOUNT); do
14688                 cl_users=(${CL_USERS[mds$i]})
14689                 cl_user1[mds$i]="${cl_users[0]}"
14690                 cl_user2[mds$i]="${cl_users[1]}"
14691
14692                 [ -n "${cl_user1[mds$i]}" ] ||
14693                         error "mds$i: no user registered"
14694                 [ -n "${cl_user2[mds$i]}" ] ||
14695                         error "mds$i: only ${cl_user2[mds$i]} is registered"
14696
14697                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
14698                 [ -n "$user_rec1" ] ||
14699                         error "mds$i: User ${cl_user1[mds$i]} not registered"
14700                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
14701                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
14702                 [ -n "$user_rec2" ] ||
14703                         error "mds$i: User ${cl_user1[mds$i]} not registered"
14704                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
14705                      "$user_rec1 + 2 == $user_rec2"
14706                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
14707                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
14708                               "$user_rec1 + 2, but is $user_rec2"
14709                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
14710                 [ -n "$user_rec2" ] ||
14711                         error "mds$i: User ${cl_user2[mds$i]} not registered"
14712                 [ $user_rec1 == $user_rec2 ] ||
14713                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
14714                               "$user_rec1, but is $user_rec2"
14715         done
14716
14717         # force cl_user2 idle (2nd part) to just exceed changelog_max_idle_time
14718         local sleep2=$((idle_time - (SECONDS - start) + 1))
14719         echo "$(date +%s): sleep2 $sleep2/${idle_time}s"
14720         sleep $sleep2
14721
14722         # Generate one more changelog to trigger GC at fail_loc for cl_user2.
14723         # cl_user1 should be OK because it recently processed records.
14724         echo "$(date +%s): creating $((MDSCOUNT * 2)) files"
14725         createmany -m $DIR/$tdir/${tfile}b $((MDSCOUNT * 2)) ||
14726                 error "create $DIR/$tdir/${tfile}b failed"
14727
14728         # ensure gc thread is done
14729         for i in $(mdts_nodes); do
14730                 wait_update $i \
14731                         "ps -e -o comm= | grep chlg_gc_thread" "" 20 ||
14732                         error "$i: GC-thread not done"
14733         done
14734
14735         local first_rec
14736         for i in $(seq $MDSCOUNT); do
14737                 # check cl_user1 still registered
14738                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
14739                         error "mds$i: User ${cl_user1[mds$i]} not registered"
14740                 # check cl_user2 unregistered
14741                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
14742                         error "mds$i: User ${cl_user2[mds$i]} still registered"
14743
14744                 # check changelogs are present and starting at $user_rec1 + 1
14745                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
14746                 [ -n "$user_rec1" ] ||
14747                         error "mds$i: User ${cl_user1[mds$i]} not registered"
14748                 first_rec=$($LFS changelog $(facet_svc mds$i) |
14749                             awk '{ print $1; exit; }')
14750
14751                 echo "mds$i: verifying first index $user_rec1 + 1 == $first_rec"
14752                 [ $((user_rec1 + 1)) == $first_rec ] ||
14753                         error "mds$i: first index should be $user_rec1 + 1, " \
14754                               "but is $first_rec"
14755         done
14756 }
14757 run_test 160f "changelog garbage collect (timestamped users)"
14758
14759 test_160g() {
14760         remote_mds_nodsh && skip "remote MDS with nodsh"
14761         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
14762                 skip "Need MDS version at least 2.10.56"
14763
14764         local mdts=$(comma_list $(mdts_nodes))
14765
14766         #define OBD_FAIL_TIME_IN_CHLOG_USER     0x1314
14767         do_nodes $mdts $LCTL set_param fail_loc=0x1314
14768
14769         # Create a user
14770         changelog_register || error "first changelog_register failed"
14771         changelog_register || error "second changelog_register failed"
14772         local cl_users
14773         declare -A cl_user1
14774         declare -A cl_user2
14775         local user_rec1
14776         local user_rec2
14777         local i
14778
14779         # generate some changelog records to accumulate on each MDT
14780         # use fnv1a because created files should be evenly distributed
14781         test_mkdir -c $MDSCOUNT -H fnv_1a_64 $DIR/$tdir ||
14782                 error "mkdir $tdir failed"
14783         createmany -m $DIR/$tdir/$tfile $((MDSCOUNT * 2)) ||
14784                 error "create $DIR/$tdir/$tfile failed"
14785
14786         # check changelogs have been generated
14787         local nbcl=$(changelog_dump | wc -l)
14788         [[ $nbcl -eq 0 ]] && error "no changelogs found"
14789
14790         # reduce the max_idle_indexes value to make sure we exceed it
14791         max_ndx=$((nbcl / 2 - 1))
14792
14793         for param in "changelog_max_idle_indexes=$max_ndx" \
14794                      "changelog_gc=1" \
14795                      "changelog_min_gc_interval=2" \
14796                      "changelog_min_free_cat_entries=3"; do
14797                 local MDT0=$(facet_svc $SINGLEMDS)
14798                 local var="${param%=*}"
14799                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
14800
14801                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
14802                 do_nodes $mdts $LCTL set_param mdd.*.$param ||
14803                         error "unable to set mdd.*.$param"
14804         done
14805
14806         # simulate changelog catalog almost full
14807         #define OBD_FAIL_CAT_FREE_RECORDS       0x1313
14808         do_nodes $mdts $LCTL set_param fail_loc=0x1313 fail_val=3
14809
14810         for i in $(seq $MDSCOUNT); do
14811                 cl_users=(${CL_USERS[mds$i]})
14812                 cl_user1[mds$i]="${cl_users[0]}"
14813                 cl_user2[mds$i]="${cl_users[1]}"
14814
14815                 [ -n "${cl_user1[mds$i]}" ] ||
14816                         error "mds$i: no user registered"
14817                 [ -n "${cl_user2[mds$i]}" ] ||
14818                         error "mds$i: only ${cl_user1[mds$i]} is registered"
14819
14820                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
14821                 [ -n "$user_rec1" ] ||
14822                         error "mds$i: User ${cl_user1[mds$i]} not registered"
14823                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
14824                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
14825                 [ -n "$user_rec2" ] ||
14826                         error "mds$i: User ${cl_user1[mds$i]} not registered"
14827                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
14828                      "$user_rec1 + 2 == $user_rec2"
14829                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
14830                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
14831                               "$user_rec1 + 2, but is $user_rec2"
14832                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
14833                 [ -n "$user_rec2" ] ||
14834                         error "mds$i: User ${cl_user2[mds$i]} not registered"
14835                 [ $user_rec1 == $user_rec2 ] ||
14836                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
14837                               "$user_rec1, but is $user_rec2"
14838         done
14839
14840         # ensure we are past the previous changelog_min_gc_interval set above
14841         sleep 2
14842
14843         # generate one more changelog to trigger fail_loc
14844         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
14845                 error "create $DIR/$tdir/${tfile}bis failed"
14846
14847         # ensure gc thread is done
14848         for i in $(mdts_nodes); do
14849                 wait_update $i \
14850                         "ps -e -o comm= | grep chlg_gc_thread" "" 20 ||
14851                         error "$i: GC-thread not done"
14852         done
14853
14854         local first_rec
14855         for i in $(seq $MDSCOUNT); do
14856                 # check cl_user1 still registered
14857                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
14858                         error "mds$i: User ${cl_user1[mds$i]} not registered"
14859                 # check cl_user2 unregistered
14860                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
14861                         error "mds$i: User ${cl_user2[mds$i]} still registered"
14862
14863                 # check changelogs are present and starting at $user_rec1 + 1
14864                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
14865                 [ -n "$user_rec1" ] ||
14866                         error "mds$i: User ${cl_user1[mds$i]} not registered"
14867                 first_rec=$($LFS changelog $(facet_svc mds$i) |
14868                             awk '{ print $1; exit; }')
14869
14870                 echo "mds$i: verifying first index $user_rec1 + 1 == $first_rec"
14871                 [ $((user_rec1 + 1)) == $first_rec ] ||
14872                         error "mds$i: first index should be $user_rec1 + 1, " \
14873                               "but is $first_rec"
14874         done
14875 }
14876 run_test 160g "changelog garbage collect (old users)"
14877
14878 test_160h() {
14879         remote_mds_nodsh && skip "remote MDS with nodsh" && return
14880         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
14881                 skip "Need MDS version at least 2.10.56"
14882
14883         local mdts=$(comma_list $(mdts_nodes))
14884
14885         # Create a user
14886         changelog_register || error "first changelog_register failed"
14887         changelog_register || error "second changelog_register failed"
14888         local cl_users
14889         declare -A cl_user1
14890         declare -A cl_user2
14891         local user_rec1
14892         local user_rec2
14893         local i
14894
14895         # generate some changelog records to accumulate on each MDT
14896         # use fnv1a because created files should be evenly distributed
14897         test_mkdir -c $MDSCOUNT -H fnv_1a_64 $DIR/$tdir ||
14898                 error "test_mkdir $tdir failed"
14899         createmany -m $DIR/$tdir/$tfile $((MDSCOUNT * 2)) ||
14900                 error "create $DIR/$tdir/$tfile failed"
14901
14902         # check changelogs have been generated
14903         local nbcl=$(changelog_dump | wc -l)
14904         [[ $nbcl -eq 0 ]] && error "no changelogs found"
14905
14906         for param in "changelog_max_idle_time=10" \
14907                      "changelog_gc=1" \
14908                      "changelog_min_gc_interval=2"; do
14909                 local MDT0=$(facet_svc $SINGLEMDS)
14910                 local var="${param%=*}"
14911                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
14912
14913                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
14914                 do_nodes $mdts $LCTL set_param mdd.*.$param
14915         done
14916
14917         # force cl_user2 to be idle (1st part)
14918         sleep 9
14919
14920         for i in $(seq $MDSCOUNT); do
14921                 cl_users=(${CL_USERS[mds$i]})
14922                 cl_user1[mds$i]="${cl_users[0]}"
14923                 cl_user2[mds$i]="${cl_users[1]}"
14924
14925                 [ -n "${cl_user1[mds$i]}" ] ||
14926                         error "mds$i: no user registered"
14927                 [ -n "${cl_user2[mds$i]}" ] ||
14928                         error "mds$i: only ${cl_user2[mds$i]} is registered"
14929
14930                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
14931                 [ -n "$user_rec1" ] ||
14932                         error "mds$i: User ${cl_user1[mds$i]} not registered"
14933                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
14934                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
14935                 [ -n "$user_rec2" ] ||
14936                         error "mds$i: User ${cl_user1[mds$i]} not registered"
14937                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
14938                      "$user_rec1 + 2 == $user_rec2"
14939                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
14940                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
14941                               "$user_rec1 + 2, but is $user_rec2"
14942                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
14943                 [ -n "$user_rec2" ] ||
14944                         error "mds$i: User ${cl_user2[mds$i]} not registered"
14945                 [ $user_rec1 == $user_rec2 ] ||
14946                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
14947                               "$user_rec1, but is $user_rec2"
14948         done
14949
14950         # force cl_user2 to be idle (2nd part) and to reach
14951         # changelog_max_idle_time
14952         sleep 2
14953
14954         # force each GC-thread start and block then
14955         # one per MDT/MDD, set fail_val accordingly
14956         #define OBD_FAIL_FORCE_GC_THREAD 0x1316
14957         do_nodes $mdts $LCTL set_param fail_loc=0x1316
14958
14959         # generate more changelogs to trigger fail_loc
14960         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
14961                 error "create $DIR/$tdir/${tfile}bis failed"
14962
14963         # stop MDT to stop GC-thread, should be done in back-ground as it will
14964         # block waiting for the thread to be released and exit
14965         declare -A stop_pids
14966         for i in $(seq $MDSCOUNT); do
14967                 stop mds$i &
14968                 stop_pids[mds$i]=$!
14969         done
14970
14971         for i in $(mdts_nodes); do
14972                 local facet
14973                 local nb=0
14974                 local facets=$(facets_up_on_host $i)
14975
14976                 for facet in ${facets//,/ }; do
14977                         if [[ $facet == mds* ]]; then
14978                                 nb=$((nb + 1))
14979                         fi
14980                 done
14981                 # ensure each MDS's gc threads are still present and all in "R"
14982                 # state (OBD_FAIL_FORCE_GC_THREAD effect!)
14983                 [[ $(do_node $i pgrep chlg_gc_thread | wc -l) -eq $nb ]] ||
14984                         error "$i: expected $nb GC-thread"
14985                 wait_update $i \
14986                         "ps -C chlg_gc_thread -o state --no-headers | uniq" \
14987                         "R" 20 ||
14988                         error "$i: GC-thread not found in R-state"
14989                 # check umounts of each MDT on MDS have reached kthread_stop()
14990                 [[ $(do_node $i pgrep umount | wc -l) -eq $nb ]] ||
14991                         error "$i: expected $nb umount"
14992                 wait_update $i \
14993                         "ps -C umount -o state --no-headers | uniq" "D" 20 ||
14994                         error "$i: umount not found in D-state"
14995         done
14996
14997         # release all GC-threads
14998         do_nodes $mdts $LCTL set_param fail_loc=0
14999
15000         # wait for MDT stop to complete
15001         for i in $(seq $MDSCOUNT); do
15002                 wait ${stop_pids[mds$i]} || error "mds$i: stop failed"
15003         done
15004
15005         # XXX
15006         # may try to check if any orphan changelog records are present
15007         # via ldiskfs/zfs and llog_reader...
15008
15009         # re-start/mount MDTs
15010         for i in $(seq $MDSCOUNT); do
15011                 start mds$i $(mdsdevname $i) $MDS_MOUNT_OPTS ||
15012                         error "Fail to start mds$i"
15013         done
15014
15015         local first_rec
15016         for i in $(seq $MDSCOUNT); do
15017                 # check cl_user1 still registered
15018                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
15019                         error "mds$i: User ${cl_user1[mds$i]} not registered"
15020                 # check cl_user2 unregistered
15021                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
15022                         error "mds$i: User ${cl_user2[mds$i]} still registered"
15023
15024                 # check changelogs are present and starting at $user_rec1 + 1
15025                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
15026                 [ -n "$user_rec1" ] ||
15027                         error "mds$i: User ${cl_user1[mds$i]} not registered"
15028                 first_rec=$($LFS changelog $(facet_svc mds$i) |
15029                             awk '{ print $1; exit; }')
15030
15031                 echo "mds$i: verifying first index $user_rec1 + 1 == $first_rec"
15032                 [ $((user_rec1 + 1)) == $first_rec ] ||
15033                         error "mds$i: first index should be $user_rec1 + 1, " \
15034                               "but is $first_rec"
15035         done
15036 }
15037 run_test 160h "changelog gc thread stop upon umount, orphan records delete " \
15038               "during mount"
15039
15040 test_160i() {
15041
15042         local mdts=$(comma_list $(mdts_nodes))
15043
15044         changelog_register || error "first changelog_register failed"
15045
15046         # generate some changelog records to accumulate on each MDT
15047         # use fnv1a because created files should be evenly distributed
15048         test_mkdir -c $MDSCOUNT -H fnv_1a_64 $DIR/$tdir ||
15049                 error "mkdir $tdir failed"
15050         createmany -m $DIR/$tdir/$tfile $((MDSCOUNT * 2)) ||
15051                 error "create $DIR/$tdir/$tfile failed"
15052
15053         # check changelogs have been generated
15054         local nbcl=$(changelog_dump | wc -l)
15055         [[ $nbcl -eq 0 ]] && error "no changelogs found"
15056
15057         # simulate race between register and unregister
15058         # XXX as fail_loc is set per-MDS, with DNE configs the race
15059         # simulation will only occur for one MDT per MDS and for the
15060         # others the normal race scenario will take place
15061         #define CFS_FAIL_CHLOG_USER_REG_UNREG_RACE          0x1315
15062         do_nodes $mdts $LCTL set_param fail_loc=0x10001315
15063         do_nodes $mdts $LCTL set_param fail_val=1
15064
15065         # unregister 1st user
15066         changelog_deregister &
15067         local pid1=$!
15068         # wait some time for deregister work to reach race rdv
15069         sleep 2
15070         # register 2nd user
15071         changelog_register || error "2nd user register failed"
15072
15073         wait $pid1 || error "1st user deregister failed"
15074
15075         local i
15076         local last_rec
15077         declare -A LAST_REC
15078         for i in $(seq $MDSCOUNT); do
15079                 if changelog_users mds$i | grep "^cl"; then
15080                         # make sure new records are added with one user present
15081                         LAST_REC[mds$i]=$(changelog_users $SINGLEMDS |
15082                                           awk '/^current.index:/ { print $NF }')
15083                 else
15084                         error "mds$i has no user registered"
15085                 fi
15086         done
15087
15088         # generate more changelog records to accumulate on each MDT
15089         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
15090                 error "create $DIR/$tdir/${tfile}bis failed"
15091
15092         for i in $(seq $MDSCOUNT); do
15093                 last_rec=$(changelog_users $SINGLEMDS |
15094                            awk '/^current.index:/ { print $NF }')
15095                 echo "verify changelogs are on: $last_rec != ${LAST_REC[mds$i]}"
15096                 [ $last_rec != ${LAST_REC[mds$i]} ] ||
15097                         error "changelogs are off on mds$i"
15098         done
15099 }
15100 run_test 160i "changelog user register/unregister race"
15101
15102 test_160j() {
15103         remote_mds_nodsh && skip "remote MDS with nodsh"
15104         [[ $MDS1_VERSION -lt $(version_code 2.12.56) ]] &&
15105                 skip "Need MDS version at least 2.12.56"
15106
15107         mount_client $MOUNT2 || error "mount_client on $MOUNT2 failed"
15108         stack_trap "umount $MOUNT2" EXIT
15109
15110         changelog_register || error "first changelog_register failed"
15111         stack_trap "changelog_deregister" EXIT
15112
15113         # generate some changelog
15114         # use fnv1a because created files should be evenly distributed
15115         test_mkdir -c $MDSCOUNT -H fnv_1a_64 $DIR/$tdir ||
15116                 error "mkdir $tdir failed"
15117         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
15118                 error "create $DIR/$tdir/${tfile}bis failed"
15119
15120         # open the changelog device
15121         exec 3>/dev/changelog-$FSNAME-MDT0000
15122         stack_trap "exec 3>&-" EXIT
15123         exec 4</dev/changelog-$FSNAME-MDT0000
15124         stack_trap "exec 4<&-" EXIT
15125
15126         # umount the first lustre mount
15127         umount $MOUNT
15128         stack_trap "mount_client $MOUNT" EXIT
15129
15130         # read changelog
15131         cat <&4 >/dev/null || error "read changelog failed"
15132
15133         # clear changelog
15134         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
15135         changelog_users $SINGLEMDS | grep -q $cl_user ||
15136                 error "User $cl_user not found in changelog_users"
15137
15138         printf 'clear:'$cl_user':0' >&3
15139 }
15140 run_test 160j "client can be umounted  while its chanangelog is being used"
15141
15142 test_160k() {
15143         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15144         remote_mds_nodsh && skip "remote MDS with nodsh"
15145
15146         mkdir -p $DIR/$tdir/1/1
15147
15148         changelog_register || error "changelog_register failed"
15149         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
15150
15151         changelog_users $SINGLEMDS | grep -q $cl_user ||
15152                 error "User '$cl_user' not found in changelog_users"
15153 #define OBD_FAIL_MDS_CHANGELOG_REORDER 0x15d
15154         do_facet mds1 $LCTL set_param fail_loc=0x8000015d fail_val=3
15155         rmdir $DIR/$tdir/1/1 & sleep 1
15156         mkdir $DIR/$tdir/2
15157         touch $DIR/$tdir/2/2
15158         rm -rf $DIR/$tdir/2
15159
15160         wait
15161         sleep 4
15162
15163         changelog_dump | grep rmdir || error "rmdir not recorded"
15164
15165         rm -rf $DIR/$tdir
15166         changelog_deregister
15167 }
15168 run_test 160k "Verify that changelog records are not lost"
15169
15170 # Verifies that a file passed as a parameter has recently had an operation
15171 # performed on it that has generated an MTIME changelog which contains the
15172 # correct parent FID. As files might reside on a different MDT from the
15173 # parent directory in DNE configurations, the FIDs are translated to paths
15174 # before being compared, which should be identical
15175 compare_mtime_changelog() {
15176         local file="${1}"
15177         local mdtidx
15178         local mtime
15179         local cl_fid
15180         local pdir
15181         local dir
15182
15183         mdtidx=$($LFS getstripe --mdt-index $file)
15184         mdtidx=$(printf "%04x" $mdtidx)
15185
15186         # Obtain the parent FID from the MTIME changelog
15187         mtime=$($LFS changelog $FSNAME-MDT$mdtidx | tail -n 1 | grep MTIME)
15188         [ -z "$mtime" ] && error "MTIME changelog not recorded"
15189
15190         cl_fid=$(sed -e 's/.* p=//' -e 's/ .*//' <<<$mtime)
15191         [ -z "$cl_fid" ] && error "parent FID not present"
15192
15193         # Verify that the path for the parent FID is the same as the path for
15194         # the test directory
15195         pdir=$($LFS fid2path $MOUNT "$cl_fid")
15196
15197         dir=$(dirname $1)
15198
15199         [[ "${pdir%/}" == "$dir" ]] ||
15200                 error "MTIME changelog parent FID is wrong, expected $dir, got $pdir"
15201 }
15202
15203 test_160l() {
15204         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15205
15206         remote_mds_nodsh && skip "remote MDS with nodsh"
15207         [[ $MDS1_VERSION -ge $(version_code 2.13.55) ]] ||
15208                 skip "Need MDS version at least 2.13.55"
15209
15210         local cl_user
15211
15212         changelog_register || error "changelog_register failed"
15213         cl_user="${CL_USERS[$SINGLEMDS]%% *}"
15214
15215         changelog_users $SINGLEMDS | grep -q $cl_user ||
15216                 error "User '$cl_user' not found in changelog_users"
15217
15218         # Clear some types so that MTIME changelogs are generated
15219         changelog_chmask "-CREAT"
15220         changelog_chmask "-CLOSE"
15221
15222         test_mkdir $DIR/$tdir || error "failed to mkdir $DIR/$tdir"
15223
15224         # Test CL_MTIME during setattr
15225         touch $DIR/$tdir/$tfile
15226         compare_mtime_changelog $DIR/$tdir/$tfile
15227
15228         # Test CL_MTIME during close
15229         $MULTIOP $DIR/$tdir/${tfile}_2 O_2w4096c || error "multiop failed"
15230         compare_mtime_changelog $DIR/$tdir/${tfile}_2
15231 }
15232 run_test 160l "Verify that MTIME changelog records contain the parent FID"
15233
15234 test_161a() {
15235         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15236
15237         test_mkdir -c1 $DIR/$tdir
15238         cp /etc/hosts $DIR/$tdir/$tfile
15239         test_mkdir -c1 $DIR/$tdir/foo1
15240         test_mkdir -c1 $DIR/$tdir/foo2
15241         ln $DIR/$tdir/$tfile $DIR/$tdir/foo1/sofia
15242         ln $DIR/$tdir/$tfile $DIR/$tdir/foo2/zachary
15243         ln $DIR/$tdir/$tfile $DIR/$tdir/foo1/luna
15244         ln $DIR/$tdir/$tfile $DIR/$tdir/foo2/thor
15245         local FID=$($LFS path2fid $DIR/$tdir/$tfile | tr -d '[]')
15246         if [ "$($LFS fid2path $DIR $FID | wc -l)" != "5" ]; then
15247                 $LFS fid2path $DIR $FID
15248                 error "bad link ea"
15249         fi
15250         # middle
15251         rm $DIR/$tdir/foo2/zachary
15252         # last
15253         rm $DIR/$tdir/foo2/thor
15254         # first
15255         rm $DIR/$tdir/$tfile
15256         # rename
15257         mv $DIR/$tdir/foo1/sofia $DIR/$tdir/foo2/maggie
15258         [ "$($LFS fid2path $FSNAME --link 1 $FID)" != "$tdir/foo2/maggie" ] &&
15259                 { $LFS fid2path $DIR $FID; error "bad link rename"; }
15260         rm $DIR/$tdir/foo2/maggie
15261
15262         # overflow the EA
15263         local longname=$tfile.avg_len_is_thirty_two_
15264         stack_trap "unlinkmany $DIR/$tdir/foo2/$longname 1000 || \
15265                 error_noexit 'failed to unlink many hardlinks'" EXIT
15266         createmany -l$DIR/$tdir/foo1/luna $DIR/$tdir/foo2/$longname 1000 ||
15267                 error "failed to hardlink many files"
15268         links=$($LFS fid2path $DIR $FID | wc -l)
15269         echo -n "${links}/1000 links in link EA"
15270         [[ $links -gt 60 ]] || error "expected at least 60 links in link EA"
15271 }
15272 run_test 161a "link ea sanity"
15273
15274 test_161b() {
15275         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15276         [ $MDSCOUNT -lt 2 ] && skip_env "skipping remote directory test"
15277
15278         local MDTIDX=1
15279         local remote_dir=$DIR/$tdir/remote_dir
15280
15281         mkdir -p $DIR/$tdir
15282         $LFS mkdir -i $MDTIDX $remote_dir ||
15283                 error "create remote directory failed"
15284
15285         cp /etc/hosts $remote_dir/$tfile
15286         mkdir -p $remote_dir/foo1
15287         mkdir -p $remote_dir/foo2
15288         ln $remote_dir/$tfile $remote_dir/foo1/sofia
15289         ln $remote_dir/$tfile $remote_dir/foo2/zachary
15290         ln $remote_dir/$tfile $remote_dir/foo1/luna
15291         ln $remote_dir/$tfile $remote_dir/foo2/thor
15292
15293         local FID=$($LFS path2fid $remote_dir/$tfile | tr -d '[' |
15294                      tr -d ']')
15295         if [ "$($LFS fid2path $DIR $FID | wc -l)" != "5" ]; then
15296                 $LFS fid2path $DIR $FID
15297                 error "bad link ea"
15298         fi
15299         # middle
15300         rm $remote_dir/foo2/zachary
15301         # last
15302         rm $remote_dir/foo2/thor
15303         # first
15304         rm $remote_dir/$tfile
15305         # rename
15306         mv $remote_dir/foo1/sofia $remote_dir/foo2/maggie
15307         local link_path=$($LFS fid2path $FSNAME --link 1 $FID)
15308         if [ "$DIR/$link_path" != "$remote_dir/foo2/maggie" ]; then
15309                 $LFS fid2path $DIR $FID
15310                 error "bad link rename"
15311         fi
15312         rm $remote_dir/foo2/maggie
15313
15314         # overflow the EA
15315         local longname=filename_avg_len_is_thirty_two_
15316         createmany -l$remote_dir/foo1/luna $remote_dir/foo2/$longname 1000 ||
15317                 error "failed to hardlink many files"
15318         links=$($LFS fid2path $DIR $FID | wc -l)
15319         echo -n "${links}/1000 links in link EA"
15320         [[ ${links} -gt 60 ]] ||
15321                 error "expected at least 60 links in link EA"
15322         unlinkmany $remote_dir/foo2/$longname 1000 ||
15323         error "failed to unlink many hardlinks"
15324 }
15325 run_test 161b "link ea sanity under remote directory"
15326
15327 test_161c() {
15328         remote_mds_nodsh && skip "remote MDS with nodsh"
15329         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15330         [[ $MDS1_VERSION -lt $(version_code 2.1.5) ]] &&
15331                 skip "Need MDS version at least 2.1.5"
15332
15333         # define CLF_RENAME_LAST 0x0001
15334         # rename overwrite a target having nlink = 1 (changelog flag 0x1)
15335         changelog_register || error "changelog_register failed"
15336
15337         rm -rf $DIR/$tdir
15338         test_mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir
15339         touch $DIR/$tdir/foo_161c
15340         touch $DIR/$tdir/bar_161c
15341         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/bar_161c
15342         changelog_dump | grep RENME | tail -n 5
15343         local flags=$(changelog_dump | grep "RENME.*bar_161c" | cut -f5 -d' ')
15344         changelog_clear 0 || error "changelog_clear failed"
15345         if [ x$flags != "x0x1" ]; then
15346                 error "flag $flags is not 0x1"
15347         fi
15348
15349         echo "rename overwrite target with nlink = 1, changelog flags=$flags"
15350         # rename overwrite a target having nlink > 1 (changelog flag 0x0)
15351         touch $DIR/$tdir/foo_161c
15352         touch $DIR/$tdir/bar_161c
15353         ln $DIR/$tdir/bar_161c $DIR/$tdir/foobar_161c
15354         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/bar_161c
15355         changelog_dump | grep RENME | tail -n 5
15356         flags=$(changelog_dump | grep "RENME.*bar_161c" | cut -f5 -d' ')
15357         changelog_clear 0 || error "changelog_clear failed"
15358         if [ x$flags != "x0x0" ]; then
15359                 error "flag $flags is not 0x0"
15360         fi
15361         echo "rename overwrite a target having nlink > 1," \
15362                 "changelog record has flags of $flags"
15363
15364         # rename doesn't overwrite a target (changelog flag 0x0)
15365         touch $DIR/$tdir/foo_161c
15366         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/foo2_161c
15367         changelog_dump | grep RENME | tail -n 5
15368         flags=$(changelog_dump | grep RENME | tail -1 | cut -f5 -d' ')
15369         changelog_clear 0 || error "changelog_clear failed"
15370         if [ x$flags != "x0x0" ]; then
15371                 error "flag $flags is not 0x0"
15372         fi
15373         echo "rename doesn't overwrite a target," \
15374                 "changelog record has flags of $flags"
15375
15376         # define CLF_UNLINK_LAST 0x0001
15377         # unlink a file having nlink = 1 (changelog flag 0x1)
15378         rm -f $DIR/$tdir/foo2_161c
15379         changelog_dump | grep UNLNK | tail -n 5
15380         flags=$(changelog_dump | grep UNLNK | tail -1 | cut -f5 -d' ')
15381         changelog_clear 0 || error "changelog_clear failed"
15382         if [ x$flags != "x0x1" ]; then
15383                 error "flag $flags is not 0x1"
15384         fi
15385         echo "unlink a file having nlink = 1," \
15386                 "changelog record has flags of $flags"
15387
15388         # unlink a file having nlink > 1 (changelog flag 0x0)
15389         ln -f $DIR/$tdir/bar_161c $DIR/$tdir/foobar_161c
15390         rm -f $DIR/$tdir/foobar_161c
15391         changelog_dump | grep UNLNK | tail -n 5
15392         flags=$(changelog_dump | grep UNLNK | tail -1 | cut -f5 -d' ')
15393         changelog_clear 0 || error "changelog_clear failed"
15394         if [ x$flags != "x0x0" ]; then
15395                 error "flag $flags is not 0x0"
15396         fi
15397         echo "unlink a file having nlink > 1, changelog record flags '$flags'"
15398 }
15399 run_test 161c "check CL_RENME[UNLINK] changelog record flags"
15400
15401 test_161d() {
15402         remote_mds_nodsh && skip "remote MDS with nodsh"
15403         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
15404
15405         local pid
15406         local fid
15407
15408         changelog_register || error "changelog_register failed"
15409
15410         # work in a standalone dir to avoid locking on $DIR/$MOUNT to
15411         # interfer with $MOUNT/.lustre/fid/ access
15412         mkdir $DIR/$tdir
15413         [[ $? -eq 0 ]] || error "mkdir failed"
15414
15415         #define OBD_FAIL_LLITE_CREATE_NODE_PAUSE 0x140c | OBD_FAIL_ONCE
15416         $LCTL set_param fail_loc=0x8000140c
15417         # 5s pause
15418         $LCTL set_param fail_val=5
15419
15420         # create file
15421         echo foofoo > $DIR/$tdir/$tfile &
15422         pid=$!
15423
15424         # wait for create to be delayed
15425         sleep 2
15426
15427         ps -p $pid
15428         [[ $? -eq 0 ]] || error "create should be blocked"
15429
15430         local tempfile="$(mktemp --tmpdir $tfile.XXXXXX)"
15431         stack_trap "rm -f $tempfile"
15432         fid=$(changelog_extract_field "CREAT" "$tfile" "t=")
15433         cat $MOUNT/.lustre/fid/$fid 2>/dev/null >$tempfile || error "cat failed"
15434         # some delay may occur during ChangeLog publishing and file read just
15435         # above, that could allow file write to happen finally
15436         [[ -s $tempfile ]] && echo "file should be empty"
15437
15438         $LCTL set_param fail_loc=0
15439
15440         wait $pid
15441         [[ $? -eq 0 ]] || error "create failed"
15442 }
15443 run_test 161d "create with concurrent .lustre/fid access"
15444
15445 check_path() {
15446         local expected="$1"
15447         shift
15448         local fid="$2"
15449
15450         local path
15451         path=$($LFS fid2path "$@")
15452         local rc=$?
15453
15454         if [ $rc -ne 0 ]; then
15455                 error "path looked up of '$expected' failed: rc=$rc"
15456         elif [ "$path" != "$expected" ]; then
15457                 error "path looked up '$path' instead of '$expected'"
15458         else
15459                 echo "FID '$fid' resolves to path '$path' as expected"
15460         fi
15461 }
15462
15463 test_162a() { # was test_162
15464         test_mkdir -p -c1 $DIR/$tdir/d2
15465         touch $DIR/$tdir/d2/$tfile
15466         touch $DIR/$tdir/d2/x1
15467         touch $DIR/$tdir/d2/x2
15468         test_mkdir -p -c1 $DIR/$tdir/d2/a/b/c
15469         test_mkdir -p -c1 $DIR/$tdir/d2/p/q/r
15470         # regular file
15471         local fid=$($LFS path2fid $DIR/$tdir/d2/$tfile | tr -d '[]')
15472         check_path "$tdir/d2/$tfile" $FSNAME "$fid" --link 0
15473
15474         # softlink
15475         ln -s $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/p/q/r/slink
15476         fid=$($LFS path2fid $DIR/$tdir/d2/p/q/r/slink | tr -d '[]')
15477         check_path "$tdir/d2/p/q/r/slink" $FSNAME "$fid" --link 0
15478
15479         # softlink to wrong file
15480         ln -s /this/is/garbage $DIR/$tdir/d2/p/q/r/slink.wrong
15481         fid=$($LFS path2fid $DIR/$tdir/d2/p/q/r/slink.wrong | tr -d '[]')
15482         check_path "$tdir/d2/p/q/r/slink.wrong" $FSNAME "$fid" --link 0
15483
15484         # hardlink
15485         ln $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/p/q/r/hlink
15486         mv $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/a/b/c/new_file
15487         fid=$($LFS path2fid $DIR/$tdir/d2/a/b/c/new_file | tr -d '[]')
15488         # fid2path dir/fsname should both work
15489         check_path "$tdir/d2/a/b/c/new_file" $FSNAME "$fid" --link 1
15490         check_path "$DIR/$tdir/d2/p/q/r/hlink" $DIR "$fid" --link 0
15491
15492         # hardlink count: check that there are 2 links
15493         local nlinks=$($LFS fid2path $DIR "$fid" | wc -l)
15494         [ $nlinks -eq 2 ] || error "expect 2 links, found $nlinks"
15495
15496         # hardlink indexing: remove the first link
15497         rm $DIR/$tdir/d2/p/q/r/hlink
15498         check_path "$tdir/d2/a/b/c/new_file" $FSNAME $fid --link 0
15499 }
15500 run_test 162a "path lookup sanity"
15501
15502 test_162b() {
15503         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15504         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
15505
15506         mkdir $DIR/$tdir
15507         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
15508                                 error "create striped dir failed"
15509
15510         local FID=$($LFS getdirstripe $DIR/$tdir/striped_dir |
15511                                         tail -n 1 | awk '{print $2}')
15512         stat $MOUNT/.lustre/fid/$FID && error "sub_stripe can be accessed"
15513
15514         touch $DIR/$tdir/striped_dir/f{0..4} || error "touch f0..4 failed"
15515         mkdir $DIR/$tdir/striped_dir/d{0..4} || error "mkdir d0..4 failed"
15516
15517         # regular file
15518         for ((i=0;i<5;i++)); do
15519                 FID=$($LFS path2fid $DIR/$tdir/striped_dir/f$i | tr -d '[]') ||
15520                         error "get fid for f$i failed"
15521                 check_path "$tdir/striped_dir/f$i" $FSNAME $FID --link 0
15522
15523                 FID=$($LFS path2fid $DIR/$tdir/striped_dir/d$i | tr -d '[]') ||
15524                         error "get fid for d$i failed"
15525                 check_path "$tdir/striped_dir/d$i" $FSNAME $FID --link 0
15526         done
15527
15528         return 0
15529 }
15530 run_test 162b "striped directory path lookup sanity"
15531
15532 # LU-4239: Verify fid2path works with paths 100 or more directories deep
15533 test_162c() {
15534         [[ $MDS1_VERSION -lt $(version_code 2.7.51) ]] &&
15535                 skip "Need MDS version at least 2.7.51"
15536
15537         local lpath=$tdir.local
15538         local rpath=$tdir.remote
15539
15540         test_mkdir $DIR/$lpath
15541         test_mkdir $DIR/$rpath
15542
15543         for ((i = 0; i <= 101; i++)); do
15544                 lpath="$lpath/$i"
15545                 mkdir $DIR/$lpath
15546                 FID=$($LFS path2fid $DIR/$lpath | tr -d '[]') ||
15547                         error "get fid for local directory $DIR/$lpath failed"
15548                 check_path "$DIR/$lpath" $MOUNT $FID --link 0
15549
15550                 rpath="$rpath/$i"
15551                 test_mkdir $DIR/$rpath
15552                 FID=$($LFS path2fid $DIR/$rpath | tr -d '[]') ||
15553                         error "get fid for remote directory $DIR/$rpath failed"
15554                 check_path "$DIR/$rpath" $MOUNT $FID --link 0
15555         done
15556
15557         return 0
15558 }
15559 run_test 162c "fid2path works with paths 100 or more directories deep"
15560
15561 oalr_event_count() {
15562         local event="${1}"
15563         local trace="${2}"
15564
15565         awk -v name="${FSNAME}-OST0000" \
15566             -v event="${event}" \
15567             '$1 == "TRACE" && $2 == event && $3 == name' \
15568             "${trace}" |
15569         wc -l
15570 }
15571
15572 oalr_expect_event_count() {
15573         local event="${1}"
15574         local trace="${2}"
15575         local expect="${3}"
15576         local count
15577
15578         count=$(oalr_event_count "${event}" "${trace}")
15579         if ((count == expect)); then
15580                 return 0
15581         fi
15582
15583         error_noexit "${event} event count was '${count}', expected ${expect}"
15584         cat "${trace}" >&2
15585         exit 1
15586 }
15587
15588 cleanup_165() {
15589         do_facet ost1 killall --quiet -KILL ofd_access_log_reader || true
15590         stop ost1
15591         start ost1 "$(ostdevname 1)" $OST_MOUNT_OPTS
15592 }
15593
15594 setup_165() {
15595         sync # Flush previous IOs so we can count log entries.
15596         do_facet ost1 $LCTL set_param "obdfilter.${FSNAME}-OST0000.access_log_size=4096"
15597         stack_trap cleanup_165 EXIT
15598 }
15599
15600 test_165a() {
15601         local trace="/tmp/${tfile}.trace"
15602         local rc
15603         local count
15604
15605         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
15606                 skip "OFD access log unsupported"
15607
15608         setup_165
15609         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
15610         sleep 5
15611
15612         do_facet ost1 ofd_access_log_reader --list
15613         stop ost1
15614
15615         do_facet ost1 killall -TERM ofd_access_log_reader
15616         wait
15617         rc=$?
15618
15619         if ((rc != 0)); then
15620                 error "ofd_access_log_reader exited with rc = '${rc}'"
15621         fi
15622
15623         # Parse trace file for discovery events:
15624         oalr_expect_event_count alr_log_add "${trace}" 1
15625         oalr_expect_event_count alr_log_eof "${trace}" 1
15626         oalr_expect_event_count alr_log_free "${trace}" 1
15627 }
15628 run_test 165a "ofd access log discovery"
15629
15630 test_165b() {
15631         local trace="/tmp/${tfile}.trace"
15632         local file="${DIR}/${tfile}"
15633         local pfid1
15634         local pfid2
15635         local -a entry
15636         local rc
15637         local count
15638         local size
15639         local flags
15640
15641         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
15642                 skip "OFD access log unsupported"
15643
15644         setup_165
15645         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
15646         sleep 5
15647
15648         do_facet ost1 ofd_access_log_reader --list
15649
15650         lfs setstripe -c 1 -i 0 "${file}"
15651         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
15652                 error "cannot create '${file}'"
15653
15654         sleep 5
15655         do_facet ost1 killall -TERM ofd_access_log_reader
15656         wait
15657         rc=$?
15658
15659         if ((rc != 0)); then
15660                 error "ofd_access_log_reader exited with rc = '${rc}'"
15661         fi
15662
15663         oalr_expect_event_count alr_log_entry "${trace}" 1
15664
15665         pfid1=$($LFS path2fid "${file}")
15666
15667         # 1     2             3   4    5     6   7    8    9     10
15668         # TRACE alr_log_entry OST PFID BEGIN END TIME SIZE COUNT FLAGS
15669         entry=( - $(awk -v pfid="${pfid}" '$1 == "TRACE" && $2 == "alr_log_entry"' "${trace}" ) )
15670
15671         echo "entry = '${entry[*]}'" >&2
15672
15673         pfid2=${entry[4]}
15674         if [[ "${pfid1}" != "${pfid2}" ]]; then
15675                 error "entry '${entry[*]}' has invalid PFID '${pfid2}', expected ${pfid1}"
15676         fi
15677
15678         size=${entry[8]}
15679         if ((size != 1048576)); then
15680                 error "entry '${entry[*]}' has invalid io size '${size}', expected 1048576"
15681         fi
15682
15683         flags=${entry[10]}
15684         if [[ "${flags}" != "w" ]]; then
15685                 error "entry '${entry[*]}' has invalid io flags '${flags}', expected 'w'"
15686         fi
15687
15688         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
15689         sleep 5
15690
15691         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r524288c ||
15692                 error "cannot read '${file}'"
15693         sleep 5
15694
15695         do_facet ost1 killall -TERM ofd_access_log_reader
15696         wait
15697         rc=$?
15698
15699         if ((rc != 0)); then
15700                 error "ofd_access_log_reader exited with rc = '${rc}'"
15701         fi
15702
15703         oalr_expect_event_count alr_log_entry "${trace}" 1
15704
15705         entry=( - $(awk -v pfid="${pfid}" '$1 == "TRACE" && $2 == "alr_log_entry"' "${trace}" ) )
15706         echo "entry = '${entry[*]}'" >&2
15707
15708         pfid2=${entry[4]}
15709         if [[ "${pfid1}" != "${pfid2}" ]]; then
15710                 error "entry '${entry[*]}' has invalid PFID '${pfid2}', expected ${pfid1}"
15711         fi
15712
15713         size=${entry[8]}
15714         if ((size != 524288)); then
15715                 error "entry '${entry[*]}' has invalid io size '${size}', 524288"
15716         fi
15717
15718         flags=${entry[10]}
15719         if [[ "${flags}" != "r" ]]; then
15720                 error "entry '${entry[*]}' has invalid io flags '${flags}', expected 'r'"
15721         fi
15722 }
15723 run_test 165b "ofd access log entries are produced and consumed"
15724
15725 test_165c() {
15726         local trace="/tmp/${tfile}.trace"
15727         local file="${DIR}/${tdir}/${tfile}"
15728
15729         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
15730                 skip "OFD access log unsupported"
15731
15732         test_mkdir "${DIR}/${tdir}"
15733
15734         setup_165
15735         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
15736         sleep 5
15737
15738         lfs setstripe -c 1 -i 0 "${DIR}/${tdir}"
15739
15740         # 4096 / 64 = 64. Create twice as many entries.
15741         for ((i = 0; i < 128; i++)); do
15742                 $MULTIOP "${file}-${i}" oO_CREAT:O_WRONLY:w512c ||
15743                         error "cannot create file"
15744         done
15745
15746         sync
15747
15748         do_facet ost1 killall -TERM ofd_access_log_reader
15749         wait
15750         rc=$?
15751         if ((rc != 0)); then
15752                 error "ofd_access_log_reader exited with rc = '${rc}'"
15753         fi
15754
15755         unlinkmany  "${file}-%d" 128
15756 }
15757 run_test 165c "full ofd access logs do not block IOs"
15758
15759 oal_get_read_count() {
15760         local stats="$1"
15761
15762         # STATS lustre-OST0001 alr_read_count 1
15763
15764         do_facet ost1 cat "${stats}" |
15765         awk '$1 == "STATS" && $3 == "alr_read_count" { count = $4; }
15766              END { print count; }'
15767 }
15768
15769 oal_expect_read_count() {
15770         local stats="$1"
15771         local count
15772         local expect="$2"
15773
15774         # Ask ofd_access_log_reader to write stats.
15775         do_facet ost1 killall -USR1 ofd_access_log_reader
15776
15777         # Allow some time for things to happen.
15778         sleep 1
15779
15780         count=$(oal_get_read_count "${stats}")
15781         if ((count == expect)); then
15782                 return 0
15783         fi
15784
15785         error_noexit "bad read count, got ${count}, expected ${expect}"
15786         do_facet ost1 cat "${stats}" >&2
15787         exit 1
15788 }
15789
15790 test_165d() {
15791         local stats="/tmp/${tfile}.stats"
15792         local file="${DIR}/${tdir}/${tfile}"
15793         local param="obdfilter.${FSNAME}-OST0000.access_log_mask"
15794
15795         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
15796                 skip "OFD access log unsupported"
15797
15798         test_mkdir "${DIR}/${tdir}"
15799
15800         setup_165
15801         do_facet ost1 ofd_access_log_reader --stats="${stats}" &
15802         sleep 5
15803
15804         lfs setstripe -c 1 -i 0 "${file}"
15805
15806         do_facet ost1 lctl set_param "${param}=rw"
15807         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
15808                 error "cannot create '${file}'"
15809         oal_expect_read_count "${stats}" 1
15810
15811         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
15812                 error "cannot read '${file}'"
15813         oal_expect_read_count "${stats}" 2
15814
15815         do_facet ost1 lctl set_param "${param}=r"
15816         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
15817                 error "cannot create '${file}'"
15818         oal_expect_read_count "${stats}" 2
15819
15820         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
15821                 error "cannot read '${file}'"
15822         oal_expect_read_count "${stats}" 3
15823
15824         do_facet ost1 lctl set_param "${param}=w"
15825         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
15826                 error "cannot create '${file}'"
15827         oal_expect_read_count "${stats}" 4
15828
15829         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
15830                 error "cannot read '${file}'"
15831         oal_expect_read_count "${stats}" 4
15832
15833         do_facet ost1 lctl set_param "${param}=0"
15834         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
15835                 error "cannot create '${file}'"
15836         oal_expect_read_count "${stats}" 4
15837
15838         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
15839                 error "cannot read '${file}'"
15840         oal_expect_read_count "${stats}" 4
15841
15842         do_facet ost1 killall -TERM ofd_access_log_reader
15843         wait
15844         rc=$?
15845         if ((rc != 0)); then
15846                 error "ofd_access_log_reader exited with rc = '${rc}'"
15847         fi
15848 }
15849 run_test 165d "ofd_access_log mask works"
15850
15851 test_165e() {
15852         local stats="/tmp/${tfile}.stats"
15853         local file0="${DIR}/${tdir}-0/${tfile}"
15854         local file1="${DIR}/${tdir}-1/${tfile}"
15855
15856         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
15857                 skip "OFD access log unsupported"
15858
15859         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
15860
15861         test_mkdir -c 1 -i 0 "${DIR}/${tdir}-0"
15862         test_mkdir -c 1 -i 1 "${DIR}/${tdir}-1"
15863
15864         lfs setstripe -c 1 -i 0 "${file0}"
15865         lfs setstripe -c 1 -i 0 "${file1}"
15866
15867         setup_165
15868         do_facet ost1 ofd_access_log_reader -I 1 --stats="${stats}" &
15869         sleep 5
15870
15871         $MULTIOP "${file0}" oO_CREAT:O_WRONLY:w512c ||
15872                 error "cannot create '${file0}'"
15873         sync
15874         oal_expect_read_count "${stats}" 0
15875
15876         $MULTIOP "${file1}" oO_CREAT:O_WRONLY:w512c ||
15877                 error "cannot create '${file1}'"
15878         sync
15879         oal_expect_read_count "${stats}" 1
15880
15881         do_facet ost1 killall -TERM ofd_access_log_reader
15882         wait
15883         rc=$?
15884         if ((rc != 0)); then
15885                 error "ofd_access_log_reader exited with rc = '${rc}'"
15886         fi
15887 }
15888 run_test 165e "ofd_access_log MDT index filter works"
15889
15890 test_165f() {
15891         local trace="/tmp/${tfile}.trace"
15892         local rc
15893         local count
15894
15895         setup_165
15896         do_facet ost1 timeout 60 ofd_access_log_reader \
15897                 --exit-on-close --debug=- --trace=- > "${trace}" &
15898         sleep 5
15899         stop ost1
15900
15901         wait
15902         rc=$?
15903
15904         if ((rc != 0)); then
15905                 error_noexit "ofd_access_log_reader exited with rc = '${rc}'"
15906                 cat "${trace}"
15907                 exit 1
15908         fi
15909 }
15910 run_test 165f "ofd_access_log_reader --exit-on-close works"
15911
15912 test_169() {
15913         # do directio so as not to populate the page cache
15914         log "creating a 10 Mb file"
15915         $MULTIOP $DIR/$tfile oO_CREAT:O_DIRECT:O_RDWR:w$((10*1048576))c ||
15916                 error "multiop failed while creating a file"
15917         log "starting reads"
15918         dd if=$DIR/$tfile of=/dev/null bs=4096 &
15919         log "truncating the file"
15920         $MULTIOP $DIR/$tfile oO_TRUNC:c ||
15921                 error "multiop failed while truncating the file"
15922         log "killing dd"
15923         kill %+ || true # reads might have finished
15924         echo "wait until dd is finished"
15925         wait
15926         log "removing the temporary file"
15927         rm -rf $DIR/$tfile || error "tmp file removal failed"
15928 }
15929 run_test 169 "parallel read and truncate should not deadlock"
15930
15931 test_170() {
15932         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15933
15934         $LCTL clear     # bug 18514
15935         $LCTL debug_daemon start $TMP/${tfile}_log_good
15936         touch $DIR/$tfile
15937         $LCTL debug_daemon stop
15938         sed -e "s/^...../a/g" $TMP/${tfile}_log_good > $TMP/${tfile}_log_bad ||
15939                 error "sed failed to read log_good"
15940
15941         $LCTL debug_daemon start $TMP/${tfile}_log_good
15942         rm -rf $DIR/$tfile
15943         $LCTL debug_daemon stop
15944
15945         $LCTL df $TMP/${tfile}_log_bad > $TMP/${tfile}_log_bad.out 2>&1 ||
15946                error "lctl df log_bad failed"
15947
15948         local bad_line=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $9}')
15949         local good_line1=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $5}')
15950
15951         $LCTL df $TMP/${tfile}_log_good > $TMP/${tfile}_log_good.out 2>&1
15952         local good_line2=$(tail -n 1 $TMP/${tfile}_log_good.out | awk '{print $5}')
15953
15954         [ "$bad_line" ] && [ "$good_line1" ] && [ "$good_line2" ] ||
15955                 error "bad_line good_line1 good_line2 are empty"
15956
15957         cat $TMP/${tfile}_log_good >> $TMP/${tfile}_logs_corrupt
15958         cat $TMP/${tfile}_log_bad >> $TMP/${tfile}_logs_corrupt
15959         cat $TMP/${tfile}_log_good >> $TMP/${tfile}_logs_corrupt
15960
15961         $LCTL df $TMP/${tfile}_logs_corrupt > $TMP/${tfile}_log_bad.out 2>&1
15962         local bad_line_new=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $9}')
15963         local good_line_new=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $5}')
15964
15965         [ "$bad_line_new" ] && [ "$good_line_new" ] ||
15966                 error "bad_line_new good_line_new are empty"
15967
15968         local expected_good=$((good_line1 + good_line2*2))
15969
15970         rm -f $TMP/${tfile}*
15971         # LU-231, short malformed line may not be counted into bad lines
15972         if [ $bad_line -ne $bad_line_new ] &&
15973                    [ $bad_line -ne $((bad_line_new - 1)) ]; then
15974                 error "expected $bad_line bad lines, but got $bad_line_new"
15975                 return 1
15976         fi
15977
15978         if [ $expected_good -ne $good_line_new ]; then
15979                 error "expected $expected_good good lines, but got $good_line_new"
15980                 return 2
15981         fi
15982         true
15983 }
15984 run_test 170 "test lctl df to handle corrupted log ====================="
15985
15986 test_171() { # bug20592
15987         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15988
15989         #define OBD_FAIL_PTLRPC_DUMP_LOG         0x50e
15990         $LCTL set_param fail_loc=0x50e
15991         $LCTL set_param fail_val=3000
15992         multiop_bg_pause $DIR/$tfile O_s || true
15993         local MULTIPID=$!
15994         kill -USR1 $MULTIPID
15995         # cause log dump
15996         sleep 3
15997         wait $MULTIPID
15998         if dmesg | grep "recursive fault"; then
15999                 error "caught a recursive fault"
16000         fi
16001         $LCTL set_param fail_loc=0
16002         true
16003 }
16004 run_test 171 "test libcfs_debug_dumplog_thread stuck in do_exit() ======"
16005
16006 # it would be good to share it with obdfilter-survey/iokit-libecho code
16007 setup_obdecho_osc () {
16008         local rc=0
16009         local ost_nid=$1
16010         local obdfilter_name=$2
16011         echo "Creating new osc for $obdfilter_name on $ost_nid"
16012         # make sure we can find loopback nid
16013         $LCTL add_uuid $ost_nid $ost_nid >/dev/null 2>&1
16014
16015         [ $rc -eq 0 ] && { $LCTL attach osc ${obdfilter_name}_osc     \
16016                            ${obdfilter_name}_osc_UUID || rc=2; }
16017         [ $rc -eq 0 ] && { $LCTL --device ${obdfilter_name}_osc setup \
16018                            ${obdfilter_name}_UUID  $ost_nid || rc=3; }
16019         return $rc
16020 }
16021
16022 cleanup_obdecho_osc () {
16023         local obdfilter_name=$1
16024         $LCTL --device ${obdfilter_name}_osc cleanup >/dev/null
16025         $LCTL --device ${obdfilter_name}_osc detach  >/dev/null
16026         return 0
16027 }
16028
16029 obdecho_test() {
16030         local OBD=$1
16031         local node=$2
16032         local pages=${3:-64}
16033         local rc=0
16034         local id
16035
16036         local count=10
16037         local obd_size=$(get_obd_size $node $OBD)
16038         local page_size=$(get_page_size $node)
16039         if [[ -n "$obd_size" ]]; then
16040                 local new_count=$((obd_size / (pages * page_size / 1024)))
16041                 [[ $new_count -ge $count ]] || count=$new_count
16042         fi
16043
16044         do_facet $node "$LCTL attach echo_client ec ec_uuid" || rc=1
16045         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec setup $OBD" ||
16046                            rc=2; }
16047         if [ $rc -eq 0 ]; then
16048             id=$(do_facet $node "$LCTL --device ec create 1"  | awk '/object id/ {print $6}')
16049             [ ${PIPESTATUS[0]} -eq 0 -a -n "$id" ] || rc=3
16050         fi
16051         echo "New object id is $id"
16052         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec getattr $id" ||
16053                            rc=4; }
16054         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec "                 \
16055                            "test_brw $count w v $pages $id" || rc=4; }
16056         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec destroy $id 1" ||
16057                            rc=4; }
16058         [ $rc -eq 0 ] || [ $rc -gt 2 ] &&
16059                 { do_facet $node "$LCTL --device ec cleanup" || rc=5; }
16060         [ $rc -eq 0 ] || [ $rc -gt 1 ] &&
16061                 { do_facet $node "$LCTL --device ec detach" || rc=6; }
16062         [ $rc -ne 0 ] && echo "obecho_create_test failed: $rc"
16063         return $rc
16064 }
16065
16066 test_180a() {
16067         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16068
16069         if ! [ -d /sys/fs/lustre/echo_client ] &&
16070            ! module_loaded obdecho; then
16071                 load_module obdecho/obdecho &&
16072                         stack_trap "rmmod obdecho" EXIT ||
16073                         error "unable to load obdecho on client"
16074         fi
16075
16076         local osc=$($LCTL dl | grep -v mdt | awk '$3 == "osc" {print $4; exit}')
16077         local host=$($LCTL get_param -n osc.$osc.import |
16078                      awk '/current_connection:/ { print $2 }' )
16079         local target=$($LCTL get_param -n osc.$osc.import |
16080                        awk '/target:/ { print $2 }' )
16081         target=${target%_UUID}
16082
16083         if [ -n "$target" ]; then
16084                 setup_obdecho_osc $host $target &&
16085                         stack_trap "cleanup_obdecho_osc $target" EXIT ||
16086                         { error "obdecho setup failed with $?"; return; }
16087
16088                 obdecho_test ${target}_osc client ||
16089                         error "obdecho_test failed on ${target}_osc"
16090         else
16091                 $LCTL get_param osc.$osc.import
16092                 error "there is no osc.$osc.import target"
16093         fi
16094 }
16095 run_test 180a "test obdecho on osc"
16096
16097 test_180b() {
16098         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16099         remote_ost_nodsh && skip "remote OST with nodsh"
16100
16101         do_rpc_nodes $(facet_active_host ost1) load_module obdecho/obdecho &&
16102                 stack_trap "do_facet ost1 rmmod obdecho" EXIT ||
16103                 error "failed to load module obdecho"
16104
16105         local target=$(do_facet ost1 $LCTL dl |
16106                        awk '/obdfilter/ { print $4; exit; }')
16107
16108         if [ -n "$target" ]; then
16109                 obdecho_test $target ost1 || error "obdecho_test failed with $?"
16110         else
16111                 do_facet ost1 $LCTL dl
16112                 error "there is no obdfilter target on ost1"
16113         fi
16114 }
16115 run_test 180b "test obdecho directly on obdfilter"
16116
16117 test_180c() { # LU-2598
16118         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16119         remote_ost_nodsh && skip "remote OST with nodsh"
16120         [[ $MDS1_VERSION -lt $(version_code 2.4.0) ]] &&
16121                 skip "Need MDS version at least 2.4.0"
16122
16123         do_rpc_nodes $(facet_active_host ost1) load_module obdecho/obdecho &&
16124                 stack_trap "do_facet ost1 rmmod obdecho" EXIT ||
16125                 error "failed to load module obdecho"
16126
16127         local target=$(do_facet ost1 $LCTL dl |
16128                        awk '/obdfilter/ { print $4; exit; }')
16129
16130         if [ -n "$target" ]; then
16131                 local pages=16384 # 64MB bulk I/O RPC size
16132
16133                 obdecho_test "$target" ost1 "$pages" ||
16134                         error "obdecho_test with pages=$pages failed with $?"
16135         else
16136                 do_facet ost1 $LCTL dl
16137                 error "there is no obdfilter target on ost1"
16138         fi
16139 }
16140 run_test 180c "test huge bulk I/O size on obdfilter, don't LASSERT"
16141
16142 test_181() { # bug 22177
16143         test_mkdir $DIR/$tdir
16144         # create enough files to index the directory
16145         createmany -o $DIR/$tdir/foobar 4000
16146         # print attributes for debug purpose
16147         lsattr -d .
16148         # open dir
16149         multiop_bg_pause $DIR/$tdir D_Sc || return 1
16150         MULTIPID=$!
16151         # remove the files & current working dir
16152         unlinkmany $DIR/$tdir/foobar 4000
16153         rmdir $DIR/$tdir
16154         kill -USR1 $MULTIPID
16155         wait $MULTIPID
16156         stat $DIR/$tdir && error "open-unlinked dir was not removed!"
16157         return 0
16158 }
16159 run_test 181 "Test open-unlinked dir ========================"
16160
16161 test_182() {
16162         local fcount=1000
16163         local tcount=10
16164
16165         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
16166
16167         $LCTL set_param mdc.*.rpc_stats=clear
16168
16169         for (( i = 0; i < $tcount; i++ )) ; do
16170                 mkdir $DIR/$tdir/$i
16171         done
16172
16173         for (( i = 0; i < $tcount; i++ )) ; do
16174                 createmany -o $DIR/$tdir/$i/f- $fcount &
16175         done
16176         wait
16177
16178         for (( i = 0; i < $tcount; i++ )) ; do
16179                 unlinkmany $DIR/$tdir/$i/f- $fcount &
16180         done
16181         wait
16182
16183         $LCTL get_param mdc.*.rpc_stats
16184
16185         rm -rf $DIR/$tdir
16186 }
16187 run_test 182 "Test parallel modify metadata operations ================"
16188
16189 test_183() { # LU-2275
16190         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16191         remote_mds_nodsh && skip "remote MDS with nodsh"
16192         [[ $MDS1_VERSION -lt $(version_code 2.3.56) ]] &&
16193                 skip "Need MDS version at least 2.3.56"
16194
16195         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
16196         echo aaa > $DIR/$tdir/$tfile
16197
16198 #define OBD_FAIL_MDS_NEGATIVE_POSITIVE  0x148
16199         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x148
16200
16201         ls -l $DIR/$tdir && error "ls succeeded, should have failed"
16202         cat $DIR/$tdir/$tfile && error "cat succeeded, should have failed"
16203
16204         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
16205
16206         # Flush negative dentry cache
16207         touch $DIR/$tdir/$tfile
16208
16209         # We are not checking for any leaked references here, they'll
16210         # become evident next time we do cleanup with module unload.
16211         rm -rf $DIR/$tdir
16212 }
16213 run_test 183 "No crash or request leak in case of strange dispositions ========"
16214
16215 # test suite 184 is for LU-2016, LU-2017
16216 test_184a() {
16217         check_swap_layouts_support
16218
16219         dir0=$DIR/$tdir/$testnum
16220         test_mkdir -p -c1 $dir0
16221         ref1=/etc/passwd
16222         ref2=/etc/group
16223         file1=$dir0/f1
16224         file2=$dir0/f2
16225         $LFS setstripe -c1 $file1
16226         cp $ref1 $file1
16227         $LFS setstripe -c2 $file2
16228         cp $ref2 $file2
16229         gen1=$($LFS getstripe -g $file1)
16230         gen2=$($LFS getstripe -g $file2)
16231
16232         $LFS swap_layouts $file1 $file2 || error "swap of file layout failed"
16233         gen=$($LFS getstripe -g $file1)
16234         [[ $gen1 != $gen ]] ||
16235                 "Layout generation on $file1 does not change"
16236         gen=$($LFS getstripe -g $file2)
16237         [[ $gen2 != $gen ]] ||
16238                 "Layout generation on $file2 does not change"
16239
16240         cmp $ref1 $file2 || error "content compare failed ($ref1 != $file2)"
16241         cmp $ref2 $file1 || error "content compare failed ($ref2 != $file1)"
16242
16243         lfsck_verify_pfid $file1 $file2 || error "PFID are not transferred"
16244 }
16245 run_test 184a "Basic layout swap"
16246
16247 test_184b() {
16248         check_swap_layouts_support
16249
16250         dir0=$DIR/$tdir/$testnum
16251         mkdir -p $dir0 || error "creating dir $dir0"
16252         file1=$dir0/f1
16253         file2=$dir0/f2
16254         file3=$dir0/f3
16255         dir1=$dir0/d1
16256         dir2=$dir0/d2
16257         mkdir $dir1 $dir2
16258         $LFS setstripe -c1 $file1
16259         $LFS setstripe -c2 $file2
16260         $LFS setstripe -c1 $file3
16261         chown $RUNAS_ID $file3
16262         gen1=$($LFS getstripe -g $file1)
16263         gen2=$($LFS getstripe -g $file2)
16264
16265         $LFS swap_layouts $dir1 $dir2 &&
16266                 error "swap of directories layouts should fail"
16267         $LFS swap_layouts $dir1 $file1 &&
16268                 error "swap of directory and file layouts should fail"
16269         $RUNAS $LFS swap_layouts $file1 $file2 &&
16270                 error "swap of file we cannot write should fail"
16271         $LFS swap_layouts $file1 $file3 &&
16272                 error "swap of file with different owner should fail"
16273         /bin/true # to clear error code
16274 }
16275 run_test 184b "Forbidden layout swap (will generate errors)"
16276
16277 test_184c() {
16278         local cmpn_arg=$(cmp -n 2>&1 | grep "invalid option")
16279         [ -n "$cmpn_arg" ] && skip_env "cmp does not support -n"
16280         check_swap_layouts_support
16281         check_swap_layout_no_dom $DIR
16282
16283         local dir0=$DIR/$tdir/$testnum
16284         mkdir -p $dir0 || error "creating dir $dir0"
16285
16286         local ref1=$dir0/ref1
16287         local ref2=$dir0/ref2
16288         local file1=$dir0/file1
16289         local file2=$dir0/file2
16290         # create a file large enough for the concurrent test
16291         dd if=/dev/urandom of=$ref1 bs=1M count=$((RANDOM % 50 + 20))
16292         dd if=/dev/urandom of=$ref2 bs=1M count=$((RANDOM % 50 + 20))
16293         echo "ref file size: ref1($(stat -c %s $ref1))," \
16294              "ref2($(stat -c %s $ref2))"
16295
16296         cp $ref2 $file2
16297         dd if=$ref1 of=$file1 bs=16k &
16298         local DD_PID=$!
16299
16300         # Make sure dd starts to copy file, but wait at most 5 seconds
16301         local loops=0
16302         while [ ! -s $file1 -a $((loops++)) -lt 50 ]; do sleep 0.1; done
16303
16304         $LFS swap_layouts $file1 $file2
16305         local rc=$?
16306         wait $DD_PID
16307         [[ $? == 0 ]] || error "concurrent write on $file1 failed"
16308         [[ $rc == 0 ]] || error "swap of $file1 and $file2 failed"
16309
16310         # how many bytes copied before swapping layout
16311         local copied=$(stat -c %s $file2)
16312         local remaining=$(stat -c %s $ref1)
16313         remaining=$((remaining - copied))
16314         echo "Copied $copied bytes before swapping layout..."
16315
16316         cmp -n $copied $file1 $ref2 | grep differ &&
16317                 error "Content mismatch [0, $copied) of ref2 and file1"
16318         cmp -n $copied $file2 $ref1 ||
16319                 error "Content mismatch [0, $copied) of ref1 and file2"
16320         cmp -i $copied:$copied -n $remaining $file1 $ref1 ||
16321                 error "Content mismatch [$copied, EOF) of ref1 and file1"
16322
16323         # clean up
16324         rm -f $ref1 $ref2 $file1 $file2
16325 }
16326 run_test 184c "Concurrent write and layout swap"
16327
16328 test_184d() {
16329         check_swap_layouts_support
16330         check_swap_layout_no_dom $DIR
16331         [ -z "$(which getfattr 2>/dev/null)" ] &&
16332                 skip_env "no getfattr command"
16333
16334         local file1=$DIR/$tdir/$tfile-1
16335         local file2=$DIR/$tdir/$tfile-2
16336         local file3=$DIR/$tdir/$tfile-3
16337         local lovea1
16338         local lovea2
16339
16340         mkdir -p $DIR/$tdir
16341         touch $file1 || error "create $file1 failed"
16342         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file2 ||
16343                 error "create $file2 failed"
16344         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file3 ||
16345                 error "create $file3 failed"
16346         lovea1=$(get_layout_param $file1)
16347
16348         $LFS swap_layouts $file2 $file3 ||
16349                 error "swap $file2 $file3 layouts failed"
16350         $LFS swap_layouts $file1 $file2 ||
16351                 error "swap $file1 $file2 layouts failed"
16352
16353         lovea2=$(get_layout_param $file2)
16354         echo "$lovea1"
16355         echo "$lovea2"
16356         [ "$lovea1" == "$lovea2" ] || error "lovea $lovea1 != $lovea2"
16357
16358         lovea1=$(getfattr -n trusted.lov $file1 | grep ^trusted)
16359         [[ -z "$lovea1" ]] || error "$file1 shouldn't have lovea"
16360 }
16361 run_test 184d "allow stripeless layouts swap"
16362
16363 test_184e() {
16364         [[ $MDS1_VERSION -ge $(version_code 2.6.94) ]] ||
16365                 skip "Need MDS version at least 2.6.94"
16366         check_swap_layouts_support
16367         check_swap_layout_no_dom $DIR
16368         [ -z "$(which getfattr 2>/dev/null)" ] &&
16369                 skip_env "no getfattr command"
16370
16371         local file1=$DIR/$tdir/$tfile-1
16372         local file2=$DIR/$tdir/$tfile-2
16373         local file3=$DIR/$tdir/$tfile-3
16374         local lovea
16375
16376         mkdir -p $DIR/$tdir
16377         touch $file1 || error "create $file1 failed"
16378         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file2 ||
16379                 error "create $file2 failed"
16380         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file3 ||
16381                 error "create $file3 failed"
16382
16383         $LFS swap_layouts $file1 $file2 ||
16384                 error "swap $file1 $file2 layouts failed"
16385
16386         lovea=$(getfattr -n trusted.lov $file1 | grep ^trusted)
16387         [[ -z "$lovea" ]] || error "$file1 shouldn't have lovea"
16388
16389         echo 123 > $file1 || error "Should be able to write into $file1"
16390
16391         $LFS swap_layouts $file1 $file3 ||
16392                 error "swap $file1 $file3 layouts failed"
16393
16394         echo 123 > $file1 || error "Should be able to write into $file1"
16395
16396         rm -rf $file1 $file2 $file3
16397 }
16398 run_test 184e "Recreate layout after stripeless layout swaps"
16399
16400 test_184f() {
16401         # Create a file with name longer than sizeof(struct stat) ==
16402         # 144 to see if we can get chars from the file name to appear
16403         # in the returned striping. Note that 'f' == 0x66.
16404         local file=$(for ((i = 0; i < 200; i++)); do echo -n f; done)
16405
16406         mkdir -p $DIR/$tdir
16407         mcreate $DIR/$tdir/$file
16408         if lfs find --stripe-count 0x6666 $DIR/$tdir | grep $file; then
16409                 error "IOC_MDC_GETFILEINFO returned garbage striping"
16410         fi
16411 }
16412 run_test 184f "IOC_MDC_GETFILEINFO for files with long names but no striping"
16413
16414 test_185() { # LU-2441
16415         # LU-3553 - no volatile file support in old servers
16416         [[ $MDS1_VERSION -ge $(version_code 2.3.60) ]] ||
16417                 skip "Need MDS version at least 2.3.60"
16418
16419         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
16420         touch $DIR/$tdir/spoo
16421         local mtime1=$(stat -c "%Y" $DIR/$tdir)
16422         local fid=$($MULTIOP $DIR/$tdir VFw4096c) ||
16423                 error "cannot create/write a volatile file"
16424         [ "$FILESET" == "" ] &&
16425         $CHECKSTAT -t file $MOUNT/.lustre/fid/$fid 2>/dev/null &&
16426                 error "FID is still valid after close"
16427
16428         multiop_bg_pause $DIR/$tdir vVw4096_c
16429         local multi_pid=$!
16430
16431         local OLD_IFS=$IFS
16432         IFS=":"
16433         local fidv=($fid)
16434         IFS=$OLD_IFS
16435         # assume that the next FID for this client is sequential, since stdout
16436         # is unfortunately eaten by multiop_bg_pause
16437         local n=$((${fidv[1]} + 1))
16438         local next_fid="${fidv[0]}:$(printf "0x%x" $n):${fidv[2]}"
16439         if [ "$FILESET" == "" ]; then
16440                 $CHECKSTAT -t file $MOUNT/.lustre/fid/$next_fid ||
16441                         error "FID is missing before close"
16442         fi
16443         kill -USR1 $multi_pid
16444         # 1 second delay, so if mtime change we will see it
16445         sleep 1
16446         local mtime2=$(stat -c "%Y" $DIR/$tdir)
16447         [[ $mtime1 == $mtime2 ]] || error "mtime has changed"
16448 }
16449 run_test 185 "Volatile file support"
16450
16451 function create_check_volatile() {
16452         local idx=$1
16453         local tgt
16454
16455         $MULTIOP $MOUNT/.lustre/fid V${idx}Fw4096_c >&/tmp/${tfile}.fid &
16456         local PID=$!
16457         sleep 1
16458         local FID=$(cat /tmp/${tfile}.fid)
16459         [ "$FID" == "" ] && error "can't get FID for volatile"
16460         $CHECKSTAT -t file $MOUNT/.lustre/fid/$FID || error "can't stat $FID"
16461         tgt=$($LFS getstripe -m $MOUNT/.lustre/fid/$FID)
16462         [ "$tgt" != "$idx" ] && error "wrong MDS $tgt, expected $idx"
16463         kill -USR1 $PID
16464         wait
16465         sleep 1
16466         cancel_lru_locks mdc # flush opencache
16467         $CHECKSTAT -t file $MOUNT/.lustre/fid/$FID && error "can stat $FID"
16468         return 0
16469 }
16470
16471 test_185a(){
16472         # LU-12516 - volatile creation via .lustre
16473         [[ $MDS1_VERSION -ge $(version_code 2.12.55) ]] ||
16474                 skip "Need MDS version at least 2.3.55"
16475
16476         create_check_volatile 0
16477         [ $MDSCOUNT -lt 2 ] && return 0
16478
16479         # DNE case
16480         create_check_volatile 1
16481
16482         return 0
16483 }
16484 run_test 185a "Volatile file creation in .lustre/fid/"
16485
16486 test_187a() {
16487         remote_mds_nodsh && skip "remote MDS with nodsh"
16488         [ $MDS1_VERSION -lt $(version_code 2.3.0) ] &&
16489                 skip "Need MDS version at least 2.3.0"
16490
16491         local dir0=$DIR/$tdir/$testnum
16492         mkdir -p $dir0 || error "creating dir $dir0"
16493
16494         local file=$dir0/file1
16495         dd if=/dev/urandom of=$file count=10 bs=1M conv=fsync
16496         local dv1=$($LFS data_version $file)
16497         dd if=/dev/urandom of=$file seek=10 count=1 bs=1M conv=fsync
16498         local dv2=$($LFS data_version $file)
16499         [[ $dv1 != $dv2 ]] ||
16500                 error "data version did not change on write $dv1 == $dv2"
16501
16502         # clean up
16503         rm -f $file1
16504 }
16505 run_test 187a "Test data version change"
16506
16507 test_187b() {
16508         remote_mds_nodsh && skip "remote MDS with nodsh"
16509         [ $MDS1_VERSION -lt $(version_code 2.3.0) ] &&
16510                 skip "Need MDS version at least 2.3.0"
16511
16512         local dir0=$DIR/$tdir/$testnum
16513         mkdir -p $dir0 || error "creating dir $dir0"
16514
16515         declare -a DV=$($MULTIOP $dir0 Vw1000xYw1000xY | cut -f3 -d" ")
16516         [[ ${DV[0]} != ${DV[1]} ]] ||
16517                 error "data version did not change on write"\
16518                       " ${DV[0]} == ${DV[1]}"
16519
16520         # clean up
16521         rm -f $file1
16522 }
16523 run_test 187b "Test data version change on volatile file"
16524
16525 test_200() {
16526         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16527         remote_mgs_nodsh && skip "remote MGS with nodsh"
16528         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
16529
16530         local POOL=${POOL:-cea1}
16531         local POOL_ROOT=${POOL_ROOT:-$DIR/d200.pools}
16532         local POOL_DIR_NAME=${POOL_DIR_NAME:-dir_tst}
16533         # Pool OST targets
16534         local first_ost=0
16535         local last_ost=$(($OSTCOUNT - 1))
16536         local ost_step=2
16537         local ost_list=$(seq $first_ost $ost_step $last_ost)
16538         local ost_range="$first_ost $last_ost $ost_step"
16539         local test_path=$POOL_ROOT/$POOL_DIR_NAME
16540         local file_dir=$POOL_ROOT/file_tst
16541         local subdir=$test_path/subdir
16542         local rc=0
16543
16544         while : ; do
16545                 # former test_200a test_200b
16546                 pool_add $POOL                          || { rc=$? ; break; }
16547                 pool_add_targets  $POOL $ost_range      || { rc=$? ; break; }
16548                 # former test_200c test_200d
16549                 mkdir -p $test_path
16550                 pool_set_dir      $POOL $test_path      || { rc=$? ; break; }
16551                 pool_check_dir    $POOL $test_path      || { rc=$? ; break; }
16552                 mkdir -p $subdir
16553                 pool_check_dir    $POOL $subdir         || { rc=$? ; break; }
16554                 pool_dir_rel_path $POOL $POOL_DIR_NAME $POOL_ROOT \
16555                                                         || { rc=$? ; break; }
16556                 # former test_200e test_200f
16557                 local files=$((OSTCOUNT*3))
16558                 pool_alloc_files  $POOL $test_path $files "$ost_list" \
16559                                                         || { rc=$? ; break; }
16560                 pool_create_files $POOL $file_dir $files "$ost_list" \
16561                                                         || { rc=$? ; break; }
16562                 # former test_200g test_200h
16563                 pool_lfs_df $POOL                       || { rc=$? ; break; }
16564                 pool_file_rel_path $POOL $test_path     || { rc=$? ; break; }
16565
16566                 # former test_201a test_201b test_201c
16567                 pool_remove_first_target $POOL          || { rc=$? ; break; }
16568
16569                 local f=$test_path/$tfile
16570                 pool_remove_all_targets $POOL $f        || { rc=$? ; break; }
16571                 pool_remove $POOL $f                    || { rc=$? ; break; }
16572                 break
16573         done
16574
16575         destroy_test_pools
16576
16577         return $rc
16578 }
16579 run_test 200 "OST pools"
16580
16581 # usage: default_attr <count | size | offset>
16582 default_attr() {
16583         $LCTL get_param -n lov.$FSNAME-clilov-\*.stripe${1}
16584 }
16585
16586 # usage: check_default_stripe_attr
16587 check_default_stripe_attr() {
16588         ACTUAL=$($LFS getstripe $* $DIR/$tdir)
16589         case $1 in
16590         --stripe-count|-c)
16591                 [ -n "$2" ] && EXPECTED=0 || EXPECTED=$(default_attr count);;
16592         --stripe-size|-S)
16593                 [ -n "$2" ] && EXPECTED=0 || EXPECTED=$(default_attr size);;
16594         --stripe-index|-i)
16595                 EXPECTED=-1;;
16596         *)
16597                 error "unknown getstripe attr '$1'"
16598         esac
16599
16600         [ $ACTUAL == $EXPECTED ] ||
16601                 error "$DIR/$tdir has $1 '$ACTUAL', not '$EXPECTED'"
16602 }
16603
16604 test_204a() {
16605         test_mkdir $DIR/$tdir
16606         $LFS setstripe --stripe-count 0 --stripe-size 0 --stripe-index -1 $DIR/$tdir
16607
16608         check_default_stripe_attr --stripe-count
16609         check_default_stripe_attr --stripe-size
16610         check_default_stripe_attr --stripe-index
16611 }
16612 run_test 204a "Print default stripe attributes"
16613
16614 test_204b() {
16615         test_mkdir $DIR/$tdir
16616         $LFS setstripe --stripe-count 1 $DIR/$tdir
16617
16618         check_default_stripe_attr --stripe-size
16619         check_default_stripe_attr --stripe-index
16620 }
16621 run_test 204b "Print default stripe size and offset"
16622
16623 test_204c() {
16624         test_mkdir $DIR/$tdir
16625         $LFS setstripe --stripe-size 65536 $DIR/$tdir
16626
16627         check_default_stripe_attr --stripe-count
16628         check_default_stripe_attr --stripe-index
16629 }
16630 run_test 204c "Print default stripe count and offset"
16631
16632 test_204d() {
16633         test_mkdir $DIR/$tdir
16634         $LFS setstripe --stripe-index 0 $DIR/$tdir
16635
16636         check_default_stripe_attr --stripe-count
16637         check_default_stripe_attr --stripe-size
16638 }
16639 run_test 204d "Print default stripe count and size"
16640
16641 test_204e() {
16642         test_mkdir $DIR/$tdir
16643         $LFS setstripe -d $DIR/$tdir
16644
16645         check_default_stripe_attr --stripe-count --raw
16646         check_default_stripe_attr --stripe-size --raw
16647         check_default_stripe_attr --stripe-index --raw
16648 }
16649 run_test 204e "Print raw stripe attributes"
16650
16651 test_204f() {
16652         test_mkdir $DIR/$tdir
16653         $LFS setstripe --stripe-count 1 $DIR/$tdir
16654
16655         check_default_stripe_attr --stripe-size --raw
16656         check_default_stripe_attr --stripe-index --raw
16657 }
16658 run_test 204f "Print raw stripe size and offset"
16659
16660 test_204g() {
16661         test_mkdir $DIR/$tdir
16662         $LFS setstripe --stripe-size 65536 $DIR/$tdir
16663
16664         check_default_stripe_attr --stripe-count --raw
16665         check_default_stripe_attr --stripe-index --raw
16666 }
16667 run_test 204g "Print raw stripe count and offset"
16668
16669 test_204h() {
16670         test_mkdir $DIR/$tdir
16671         $LFS setstripe --stripe-index 0 $DIR/$tdir
16672
16673         check_default_stripe_attr --stripe-count --raw
16674         check_default_stripe_attr --stripe-size --raw
16675 }
16676 run_test 204h "Print raw stripe count and size"
16677
16678 # Figure out which job scheduler is being used, if any,
16679 # or use a fake one
16680 if [ -n "$SLURM_JOB_ID" ]; then # SLURM
16681         JOBENV=SLURM_JOB_ID
16682 elif [ -n "$LSB_JOBID" ]; then # Load Sharing Facility
16683         JOBENV=LSB_JOBID
16684 elif [ -n "$PBS_JOBID" ]; then # PBS/Maui/Moab
16685         JOBENV=PBS_JOBID
16686 elif [ -n "$LOADL_STEPID" ]; then # LoadLeveller
16687         JOBENV=LOADL_STEP_ID
16688 elif [ -n "$JOB_ID" ]; then # Sun Grid Engine
16689         JOBENV=JOB_ID
16690 else
16691         $LCTL list_param jobid_name > /dev/null 2>&1
16692         if [ $? -eq 0 ]; then
16693                 JOBENV=nodelocal
16694         else
16695                 JOBENV=FAKE_JOBID
16696         fi
16697 fi
16698 LUSTRE_JOBID_SIZE=31 # plus NUL terminator
16699
16700 verify_jobstats() {
16701         local cmd=($1)
16702         shift
16703         local facets="$@"
16704
16705 # we don't really need to clear the stats for this test to work, since each
16706 # command has a unique jobid, but it makes debugging easier if needed.
16707 #       for facet in $facets; do
16708 #               local dev=$(convert_facet2label $facet)
16709 #               # clear old jobstats
16710 #               do_facet $facet lctl set_param *.$dev.job_stats="clear"
16711 #       done
16712
16713         # use a new JobID for each test, or we might see an old one
16714         [ "$JOBENV" = "FAKE_JOBID" ] &&
16715                 FAKE_JOBID=id.$testnum.$(basename ${cmd[0]}).$RANDOM
16716
16717         JOBVAL=${!JOBENV:0:$LUSTRE_JOBID_SIZE}
16718
16719         [ "$JOBENV" = "nodelocal" ] && {
16720                 FAKE_JOBID=id.$testnum.%e.$RANDOM
16721                 $LCTL set_param jobid_name=$FAKE_JOBID
16722                 JOBVAL=${FAKE_JOBID/\%e/$(basename ${cmd[0]})}
16723         }
16724
16725         log "Test: ${cmd[*]}"
16726         log "Using JobID environment $($LCTL get_param -n jobid_var)=$JOBVAL"
16727
16728         if [ $JOBENV = "FAKE_JOBID" ]; then
16729                 FAKE_JOBID=$JOBVAL ${cmd[*]}
16730         else
16731                 ${cmd[*]}
16732         fi
16733
16734         # all files are created on OST0000
16735         for facet in $facets; do
16736                 local stats="*.$(convert_facet2label $facet).job_stats"
16737
16738                 # strip out libtool wrappers for in-tree executables
16739                 if [ $(do_facet $facet lctl get_param $stats |
16740                        sed -e 's/\.lt-/./' | grep -c $JOBVAL) -ne 1 ]; then
16741                         do_facet $facet lctl get_param $stats
16742                         error "No jobstats for $JOBVAL found on $facet::$stats"
16743                 fi
16744         done
16745 }
16746
16747 jobstats_set() {
16748         local new_jobenv=$1
16749
16750         set_persistent_param_and_check client "jobid_var" \
16751                 "$FSNAME.sys.jobid_var" $new_jobenv
16752 }
16753
16754 test_205a() { # Job stats
16755         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16756         [[ $MDS1_VERSION -ge $(version_code 2.7.1) ]] ||
16757                 skip "Need MDS version with at least 2.7.1"
16758         remote_mgs_nodsh && skip "remote MGS with nodsh"
16759         remote_mds_nodsh && skip "remote MDS with nodsh"
16760         remote_ost_nodsh && skip "remote OST with nodsh"
16761         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep jobstats)" ] &&
16762                 skip "Server doesn't support jobstats"
16763         [[ $JOBID_VAR = disable ]] && skip_env "jobstats is disabled"
16764
16765         local old_jobenv=$($LCTL get_param -n jobid_var)
16766         [ $old_jobenv != $JOBENV ] && jobstats_set $JOBENV
16767
16768         if [[ $PERM_CMD == *"set_param -P"* ]]; then
16769                 stack_trap "do_facet mgs $PERM_CMD jobid_var=$old_jobenv" EXIT
16770         else
16771                 stack_trap "do_facet mgs $PERM_CMD \
16772                         $FSNAME.sys.jobid_var=$old_jobenv" EXIT
16773         fi
16774         changelog_register
16775
16776         local old_interval=$(do_facet $SINGLEMDS lctl get_param -n \
16777                                 mdt.*.job_cleanup_interval | head -n 1)
16778         local new_interval=5
16779         do_facet $SINGLEMDS \
16780                 $LCTL set_param mdt.*.job_cleanup_interval=$new_interval
16781         stack_trap "do_facet $SINGLEMDS \
16782                 $LCTL set_param mdt.*.job_cleanup_interval=$old_interval" EXIT
16783         local start=$SECONDS
16784
16785         local cmd
16786         # mkdir
16787         cmd="mkdir $DIR/$tdir"
16788         verify_jobstats "$cmd" "$SINGLEMDS"
16789         # rmdir
16790         cmd="rmdir $DIR/$tdir"
16791         verify_jobstats "$cmd" "$SINGLEMDS"
16792         # mkdir on secondary MDT
16793         if [ $MDSCOUNT -gt 1 ]; then
16794                 cmd="lfs mkdir -i 1 $DIR/$tdir.remote"
16795                 verify_jobstats "$cmd" "mds2"
16796         fi
16797         # mknod
16798         cmd="mknod $DIR/$tfile c 1 3"
16799         verify_jobstats "$cmd" "$SINGLEMDS"
16800         # unlink
16801         cmd="rm -f $DIR/$tfile"
16802         verify_jobstats "$cmd" "$SINGLEMDS"
16803         # create all files on OST0000 so verify_jobstats can find OST stats
16804         # open & close
16805         cmd="$LFS setstripe -i 0 -c 1 $DIR/$tfile"
16806         verify_jobstats "$cmd" "$SINGLEMDS"
16807         # setattr
16808         cmd="touch $DIR/$tfile"
16809         verify_jobstats "$cmd" "$SINGLEMDS ost1"
16810         # write
16811         cmd="dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=sync"
16812         verify_jobstats "$cmd" "ost1"
16813         # read
16814         cancel_lru_locks osc
16815         cmd="dd if=$DIR/$tfile of=/dev/null bs=1M count=1 iflag=direct"
16816         verify_jobstats "$cmd" "ost1"
16817         # truncate
16818         cmd="$TRUNCATE $DIR/$tfile 0"
16819         verify_jobstats "$cmd" "$SINGLEMDS ost1"
16820         # rename
16821         cmd="mv -f $DIR/$tfile $DIR/$tdir.rename"
16822         verify_jobstats "$cmd" "$SINGLEMDS"
16823         # jobstats expiry - sleep until old stats should be expired
16824         local left=$((new_interval + 5 - (SECONDS - start)))
16825         [ $left -ge 0 ] && wait_update_facet $SINGLEMDS \
16826                 "lctl get_param *.*.job_stats | grep -c 'job_id.*mkdir'" \
16827                         "0" $left
16828         cmd="mkdir $DIR/$tdir.expire"
16829         verify_jobstats "$cmd" "$SINGLEMDS"
16830         [ $(do_facet $SINGLEMDS lctl get_param *.*.job_stats |
16831             grep -c "job_id.*mkdir") -gt 1 ] && error "old jobstats not expired"
16832
16833         # Ensure that jobid are present in changelog (if supported by MDS)
16834         if [ $MDS1_VERSION -ge $(version_code 2.6.52) ];then
16835                 changelog_dump | tail -10
16836                 jobids=$(changelog_dump | tail -9 | grep -c "j=")
16837                 [ $jobids -eq 9 ] ||
16838                         error "Wrong changelog jobid count $jobids != 9"
16839
16840                 # LU-5862
16841                 JOBENV="disable"
16842                 jobstats_set $JOBENV
16843                 touch $DIR/$tfile
16844                 changelog_dump | grep $tfile
16845                 jobids=$(changelog_dump | grep $tfile | tail -1 | grep -c "j=")
16846                 [ $jobids -eq 0 ] ||
16847                         error "Unexpected jobids when jobid_var=$JOBENV"
16848         fi
16849
16850         # test '%j' access to environment variable - if supported
16851         if lctl set_param jobid_var=USER jobid_name="S.%j.%e.%u.%h.E"; then
16852                 JOBENV="JOBCOMPLEX"
16853                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname).E"
16854
16855                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
16856         fi
16857
16858         # test '%j' access to per-session jobid - if supported
16859         if lctl list_param jobid_this_session > /dev/null 2>&1
16860         then
16861                 lctl set_param jobid_var=session jobid_name="S.%j.%e.%u.%h.E"
16862                 lctl set_param jobid_this_session=$USER
16863
16864                 JOBENV="JOBCOMPLEX"
16865                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname).E"
16866
16867                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
16868         fi
16869 }
16870 run_test 205a "Verify job stats"
16871
16872 # LU-13117, LU-13597
16873 test_205b() {
16874         job_stats="mdt.*.job_stats"
16875         $LCTL set_param $job_stats=clear
16876         # Setting jobid_var to USER might not be supported
16877         $LCTL set_param jobid_var=USER || true
16878         $LCTL set_param jobid_name="%e.%u"
16879         env -i USERTESTJOBSTATS=foolish touch $DIR/$tfile.1
16880         do_facet $SINGLEMDS $LCTL get_param $job_stats |
16881                 grep "job_id:.*foolish" &&
16882                         error "Unexpected jobid found"
16883         do_facet $SINGLEMDS $LCTL get_param $job_stats |
16884                 grep "open:.*min.*max.*sum" ||
16885                         error "wrong job_stats format found"
16886 }
16887 run_test 205b "Verify job stats jobid and output format"
16888
16889 # LU-13733
16890 test_205c() {
16891         $LCTL set_param llite.*.stats=0
16892         dd if=/dev/zero of=$DIR/$tfile.1 bs=4k count=1
16893         $LCTL get_param llite.*.stats
16894         $LCTL get_param llite.*.stats | grep \
16895                 "write_bytes *1 samples \[bytes\] 4096 4096 4096 16777216" ||
16896                         error "wrong client stats format found"
16897 }
16898 run_test 205c "Verify client stats format"
16899
16900 # LU-1480, LU-1773 and LU-1657
16901 test_206() {
16902         mkdir -p $DIR/$tdir
16903         $LFS setstripe -c -1 $DIR/$tdir
16904 #define OBD_FAIL_LOV_INIT 0x1403
16905         $LCTL set_param fail_loc=0xa0001403
16906         $LCTL set_param fail_val=1
16907         touch $DIR/$tdir/$tfile || true
16908 }
16909 run_test 206 "fail lov_init_raid0() doesn't lbug"
16910
16911 test_207a() {
16912         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((RANDOM%10+1))
16913         local fsz=`stat -c %s $DIR/$tfile`
16914         cancel_lru_locks mdc
16915
16916         # do not return layout in getattr intent
16917 #define OBD_FAIL_MDS_NO_LL_GETATTR 0x170
16918         $LCTL set_param fail_loc=0x170
16919         local sz=`stat -c %s $DIR/$tfile`
16920
16921         [ $fsz -eq $sz ] || error "file size expected $fsz, actual $sz"
16922
16923         rm -rf $DIR/$tfile
16924 }
16925 run_test 207a "can refresh layout at glimpse"
16926
16927 test_207b() {
16928         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((RANDOM%10+1))
16929         local cksum=`md5sum $DIR/$tfile`
16930         local fsz=`stat -c %s $DIR/$tfile`
16931         cancel_lru_locks mdc
16932         cancel_lru_locks osc
16933
16934         # do not return layout in getattr intent
16935 #define OBD_FAIL_MDS_NO_LL_OPEN 0x171
16936         $LCTL set_param fail_loc=0x171
16937
16938         # it will refresh layout after the file is opened but before read issues
16939         echo checksum is "$cksum"
16940         echo "$cksum" |md5sum -c --quiet || error "file differs"
16941
16942         rm -rf $DIR/$tfile
16943 }
16944 run_test 207b "can refresh layout at open"
16945
16946 test_208() {
16947         # FIXME: in this test suite, only RD lease is used. This is okay
16948         # for now as only exclusive open is supported. After generic lease
16949         # is done, this test suite should be revised. - Jinshan
16950
16951         remote_mds_nodsh && skip "remote MDS with nodsh"
16952         [[ $MDS1_VERSION -ge $(version_code 2.4.52) ]] ||
16953                 skip "Need MDS version at least 2.4.52"
16954
16955         echo "==== test 1: verify get lease work"
16956         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:eRE+eU || error "get lease error"
16957
16958         echo "==== test 2: verify lease can be broken by upcoming open"
16959         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E-eUc &
16960         local PID=$!
16961         sleep 1
16962
16963         $MULTIOP $DIR/$tfile oO_RDONLY:c
16964         kill -USR1 $PID && wait $PID || error "break lease error"
16965
16966         echo "==== test 3: verify lease can't be granted if an open already exists"
16967         $MULTIOP $DIR/$tfile oO_RDONLY:_c &
16968         local PID=$!
16969         sleep 1
16970
16971         $MULTIOP $DIR/$tfile oO_RDONLY:eReUc && error "apply lease should fail"
16972         kill -USR1 $PID && wait $PID || error "open file error"
16973
16974         echo "==== test 4: lease can sustain over recovery"
16975         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E+eUc &
16976         PID=$!
16977         sleep 1
16978
16979         fail mds1
16980
16981         kill -USR1 $PID && wait $PID || error "lease broken over recovery"
16982
16983         echo "==== test 5: lease broken can't be regained by replay"
16984         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E-eUc &
16985         PID=$!
16986         sleep 1
16987
16988         # open file to break lease and then recovery
16989         $MULTIOP $DIR/$tfile oO_RDWR:c || error "open file error"
16990         fail mds1
16991
16992         kill -USR1 $PID && wait $PID || error "lease not broken over recovery"
16993
16994         rm -f $DIR/$tfile
16995 }
16996 run_test 208 "Exclusive open"
16997
16998 test_209() {
16999         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep disp_stripe)" ] &&
17000                 skip_env "must have disp_stripe"
17001
17002         touch $DIR/$tfile
17003         sync; sleep 5; sync;
17004
17005         echo 3 > /proc/sys/vm/drop_caches
17006         [ -f /sys/kernel/slab/ptlrpc_cache/shrink ] &&
17007                 echo 1 > /sys/kernel/slab/ptlrpc_cache/shrink
17008         req_before=$(awk '/ptlrpc_cache / { print $2 }' /proc/slabinfo)
17009
17010         # open/close 500 times
17011         for i in $(seq 500); do
17012                 cat $DIR/$tfile
17013         done
17014
17015         echo 3 > /proc/sys/vm/drop_caches
17016         [ -f /sys/kernel/slab/ptlrpc_cache/shrink ] &&
17017                 echo 1 > /sys/kernel/slab/ptlrpc_cache/shrink
17018         req_after=$(awk '/ptlrpc_cache / { print $2 }' /proc/slabinfo)
17019
17020         echo "before: $req_before, after: $req_after"
17021         [ $((req_after - req_before)) -ge 300 ] &&
17022                 error "open/close requests are not freed"
17023         return 0
17024 }
17025 run_test 209 "read-only open/close requests should be freed promptly"
17026
17027 test_210() {
17028         local pid
17029
17030         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:eW_E+eUc &
17031         pid=$!
17032         sleep 1
17033
17034         $LFS getstripe $DIR/$tfile
17035         kill -USR1 $pid
17036         wait $pid || error "multiop failed"
17037
17038         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E+eUc &
17039         pid=$!
17040         sleep 1
17041
17042         $LFS getstripe $DIR/$tfile
17043         kill -USR1 $pid
17044         wait $pid || error "multiop failed"
17045 }
17046 run_test 210 "lfs getstripe does not break leases"
17047
17048 test_212() {
17049         size=`date +%s`
17050         size=$((size % 8192 + 1))
17051         dd if=/dev/urandom of=$DIR/f212 bs=1k count=$size
17052         sendfile $DIR/f212 $DIR/f212.xyz || error "sendfile wrong"
17053         rm -f $DIR/f212 $DIR/f212.xyz
17054 }
17055 run_test 212 "Sendfile test ============================================"
17056
17057 test_213() {
17058         dd if=/dev/zero of=$DIR/$tfile bs=4k count=4
17059         cancel_lru_locks osc
17060         lctl set_param fail_loc=0x8000040f
17061         # generate a read lock
17062         cat $DIR/$tfile > /dev/null
17063         # write to the file, it will try to cancel the above read lock.
17064         cat /etc/hosts >> $DIR/$tfile
17065 }
17066 run_test 213 "OSC lock completion and cancel race don't crash - bug 18829"
17067
17068 test_214() { # for bug 20133
17069         mkdir -p $DIR/$tdir/d214c || error "mkdir $DIR/$tdir/d214c failed"
17070         for (( i=0; i < 340; i++ )) ; do
17071                 touch $DIR/$tdir/d214c/a$i
17072         done
17073
17074         ls -l $DIR/$tdir || error "ls -l $DIR/d214p failed"
17075         mv $DIR/$tdir/d214c $DIR/ || error "mv $DIR/d214p/d214c $DIR/ failed"
17076         ls $DIR/d214c || error "ls $DIR/d214c failed"
17077         rm -rf $DIR/$tdir || error "rm -rf $DIR/d214* failed"
17078         rm -rf $DIR/d214* || error "rm -rf $DIR/d214* failed"
17079 }
17080 run_test 214 "hash-indexed directory test - bug 20133"
17081
17082 # having "abc" as 1st arg, creates $TMP/lnet_abc.out and $TMP/lnet_abc.sys
17083 create_lnet_proc_files() {
17084         lctl get_param -n $1 >$TMP/lnet_$1.sys || error "cannot read lnet.$1"
17085 }
17086
17087 # counterpart of create_lnet_proc_files
17088 remove_lnet_proc_files() {
17089         rm -f $TMP/lnet_$1.sys
17090 }
17091
17092 # uses 1st arg as trailing part of filename, 2nd arg as description for reports,
17093 # 3rd arg as regexp for body
17094 check_lnet_proc_stats() {
17095         local l=$(cat "$TMP/lnet_$1" |wc -l)
17096         [ $l = 1 ] || (cat "$TMP/lnet_$1" && error "$2 is not of 1 line: $l")
17097
17098         grep -E "$3" "$TMP/lnet_$1" || (cat "$TMP/lnet_$1" && error "$2 misformatted")
17099 }
17100
17101 # uses 1st arg as trailing part of filename, 2nd arg as description for reports,
17102 # 3rd arg as regexp for body, 4th arg as regexp for 1st line, 5th arg is
17103 # optional and can be regexp for 2nd line (lnet.routes case)
17104 check_lnet_proc_entry() {
17105         local blp=2          # blp stands for 'position of 1st line of body'
17106         [ -z "$5" ] || blp=3 # lnet.routes case
17107
17108         local l=$(cat "$TMP/lnet_$1" |wc -l)
17109         # subtracting one from $blp because the body can be empty
17110         [ "$l" -ge "$(($blp - 1))" ] || (cat "$TMP/lnet_$1" && error "$2 is too short: $l")
17111
17112         sed -n '1 p' "$TMP/lnet_$1" |grep -E "$4" >/dev/null ||
17113                 (cat "$TMP/lnet_$1" && error "1st line of $2 misformatted")
17114
17115         [ "$5" = "" ] || sed -n '2 p' "$TMP/lnet_$1" |grep -E "$5" >/dev/null ||
17116                 (cat "$TMP/lnet_$1" && error "2nd line of $2 misformatted")
17117
17118         # bail out if any unexpected line happened
17119         sed -n "$blp p" "$TMP/lnet_$1" | grep -Ev "$3"
17120         [ "$?" != 0 ] || error "$2 misformatted"
17121 }
17122
17123 test_215() { # for bugs 18102, 21079, 21517
17124         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17125
17126         local N='(0|[1-9][0-9]*)'       # non-negative numeric
17127         local P='[1-9][0-9]*'           # positive numeric
17128         local I='(0|-?[1-9][0-9]*|NA)'  # any numeric (0 | >0 | <0) or NA if no value
17129         local NET='[a-z][a-z0-9]*'      # LNET net like o2ib2
17130         local ADDR='[0-9.]+'            # LNET addr like 10.0.0.1
17131         local NID="$ADDR@$NET"          # LNET nid like 10.0.0.1@o2ib2
17132
17133         local L1 # regexp for 1st line
17134         local L2 # regexp for 2nd line (optional)
17135         local BR # regexp for the rest (body)
17136
17137         # lnet.stats should look as 11 space-separated non-negative numerics
17138         BR="^$N $N $N $N $N $N $N $N $N $N $N$"
17139         create_lnet_proc_files "stats"
17140         check_lnet_proc_stats "stats.sys" "lnet.stats" "$BR"
17141         remove_lnet_proc_files "stats"
17142
17143         # lnet.routes should look like this:
17144         # Routing disabled/enabled
17145         # net hops priority state router
17146         # where net is a string like tcp0, hops > 0, priority >= 0,
17147         # state is up/down,
17148         # router is a string like 192.168.1.1@tcp2
17149         L1="^Routing (disabled|enabled)$"
17150         L2="^net +hops +priority +state +router$"
17151         BR="^$NET +$N +(0|1) +(up|down) +$NID$"
17152         create_lnet_proc_files "routes"
17153         check_lnet_proc_entry "routes.sys" "lnet.routes" "$BR" "$L1" "$L2"
17154         remove_lnet_proc_files "routes"
17155
17156         # lnet.routers should look like this:
17157         # ref rtr_ref alive_cnt state last_ping ping_sent deadline down_ni router
17158         # where ref > 0, rtr_ref > 0, alive_cnt >= 0, state is up/down,
17159         # last_ping >= 0, ping_sent is boolean (0/1), deadline and down_ni are
17160         # numeric (0 or >0 or <0), router is a string like 192.168.1.1@tcp2
17161         L1="^ref +rtr_ref +alive +router$"
17162         BR="^$P +$P +(up|down) +$NID$"
17163         create_lnet_proc_files "routers"
17164         check_lnet_proc_entry "routers.sys" "lnet.routers" "$BR" "$L1"
17165         remove_lnet_proc_files "routers"
17166
17167         # lnet.peers should look like this:
17168         # nid refs state last max rtr min tx min queue
17169         # where nid is a string like 192.168.1.1@tcp2, refs > 0,
17170         # state is up/down/NA, max >= 0. last, rtr, min, tx, min are
17171         # numeric (0 or >0 or <0), queue >= 0.
17172         L1="^nid +refs +state +last +max +rtr +min +tx +min +queue$"
17173         BR="^$NID +$P +(up|down|NA) +$I +$N +$I +$I +$I +$I +$N$"
17174         create_lnet_proc_files "peers"
17175         check_lnet_proc_entry "peers.sys" "lnet.peers" "$BR" "$L1"
17176         remove_lnet_proc_files "peers"
17177
17178         # lnet.buffers  should look like this:
17179         # pages count credits min
17180         # where pages >=0, count >=0, credits and min are numeric (0 or >0 or <0)
17181         L1="^pages +count +credits +min$"
17182         BR="^ +$N +$N +$I +$I$"
17183         create_lnet_proc_files "buffers"
17184         check_lnet_proc_entry "buffers.sys" "lnet.buffers" "$BR" "$L1"
17185         remove_lnet_proc_files "buffers"
17186
17187         # lnet.nis should look like this:
17188         # nid status alive refs peer rtr max tx min
17189         # where nid is a string like 192.168.1.1@tcp2, status is up/down,
17190         # alive is numeric (0 or >0 or <0), refs >= 0, peer >= 0,
17191         # rtr >= 0, max >=0, tx and min are numeric (0 or >0 or <0).
17192         L1="^nid +status +alive +refs +peer +rtr +max +tx +min$"
17193         BR="^$NID +(up|down) +$I +$N +$N +$N +$N +$I +$I$"
17194         create_lnet_proc_files "nis"
17195         check_lnet_proc_entry "nis.sys" "lnet.nis" "$BR" "$L1"
17196         remove_lnet_proc_files "nis"
17197
17198         # can we successfully write to lnet.stats?
17199         lctl set_param -n stats=0 || error "cannot write to lnet.stats"
17200 }
17201 run_test 215 "lnet exists and has proper content - bugs 18102, 21079, 21517"
17202
17203 test_216() { # bug 20317
17204         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17205         remote_ost_nodsh && skip "remote OST with nodsh"
17206
17207         local node
17208         local facets=$(get_facets OST)
17209         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
17210
17211         save_lustre_params client "osc.*.contention_seconds" > $p
17212         save_lustre_params $facets \
17213                 "ldlm.namespaces.filter-*.max_nolock_bytes" >> $p
17214         save_lustre_params $facets \
17215                 "ldlm.namespaces.filter-*.contended_locks" >> $p
17216         save_lustre_params $facets \
17217                 "ldlm.namespaces.filter-*.contention_seconds" >> $p
17218         clear_stats osc.*.osc_stats
17219
17220         # agressive lockless i/o settings
17221         do_nodes $(comma_list $(osts_nodes)) \
17222                 "lctl set_param -n ldlm.namespaces.*.max_nolock_bytes=2000000 \
17223                         ldlm.namespaces.filter-*.contended_locks=0 \
17224                         ldlm.namespaces.filter-*.contention_seconds=60"
17225         lctl set_param -n osc.*.contention_seconds=60
17226
17227         $DIRECTIO write $DIR/$tfile 0 10 4096
17228         $CHECKSTAT -s 40960 $DIR/$tfile
17229
17230         # disable lockless i/o
17231         do_nodes $(comma_list $(osts_nodes)) \
17232                 "lctl set_param -n ldlm.namespaces.filter-*.max_nolock_bytes=0 \
17233                         ldlm.namespaces.filter-*.contended_locks=32 \
17234                         ldlm.namespaces.filter-*.contention_seconds=0"
17235         lctl set_param -n osc.*.contention_seconds=0
17236         clear_stats osc.*.osc_stats
17237
17238         dd if=/dev/zero of=$DIR/$tfile count=0
17239         $CHECKSTAT -s 0 $DIR/$tfile
17240
17241         restore_lustre_params <$p
17242         rm -f $p
17243         rm $DIR/$tfile
17244 }
17245 run_test 216 "check lockless direct write updates file size and kms correctly"
17246
17247 test_217() { # bug 22430
17248         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17249
17250         local node
17251         local nid
17252
17253         for node in $(nodes_list); do
17254                 nid=$(host_nids_address $node $NETTYPE)
17255                 if [[ $nid = *-* ]] ; then
17256                         echo "lctl ping $(h2nettype $nid)"
17257                         lctl ping $(h2nettype $nid)
17258                 else
17259                         echo "skipping $node (no hyphen detected)"
17260                 fi
17261         done
17262 }
17263 run_test 217 "check lctl ping for hostnames with hiphen ('-')"
17264
17265 test_218() {
17266        # do directio so as not to populate the page cache
17267        log "creating a 10 Mb file"
17268        $MULTIOP $DIR/$tfile oO_CREAT:O_DIRECT:O_RDWR:w$((10*1048576))c || error "multiop failed while creating a file"
17269        log "starting reads"
17270        dd if=$DIR/$tfile of=/dev/null bs=4096 &
17271        log "truncating the file"
17272        $MULTIOP $DIR/$tfile oO_TRUNC:c || error "multiop failed while truncating the file"
17273        log "killing dd"
17274        kill %+ || true # reads might have finished
17275        echo "wait until dd is finished"
17276        wait
17277        log "removing the temporary file"
17278        rm -rf $DIR/$tfile || error "tmp file removal failed"
17279 }
17280 run_test 218 "parallel read and truncate should not deadlock"
17281
17282 test_219() {
17283         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17284
17285         # write one partial page
17286         dd if=/dev/zero of=$DIR/$tfile bs=1024 count=1
17287         # set no grant so vvp_io_commit_write will do sync write
17288         $LCTL set_param fail_loc=0x411
17289         # write a full page at the end of file
17290         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 seek=1 conv=notrunc
17291
17292         $LCTL set_param fail_loc=0
17293         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 seek=3
17294         $LCTL set_param fail_loc=0x411
17295         dd if=/dev/zero of=$DIR/$tfile bs=1024 count=1 seek=2 conv=notrunc
17296
17297         # LU-4201
17298         dd if=/dev/zero of=$DIR/$tfile-2 bs=1024 count=1
17299         $CHECKSTAT -s 1024 $DIR/$tfile-2 || error "checkstat wrong size"
17300 }
17301 run_test 219 "LU-394: Write partial won't cause uncontiguous pages vec at LND"
17302
17303 test_220() { #LU-325
17304         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17305         remote_ost_nodsh && skip "remote OST with nodsh"
17306         remote_mds_nodsh && skip "remote MDS with nodsh"
17307         remote_mgs_nodsh && skip "remote MGS with nodsh"
17308
17309         local OSTIDX=0
17310
17311         # create on MDT0000 so the last_id and next_id are correct
17312         mkdir $DIR/$tdir
17313         local OST=$($LFS df $DIR | awk '/OST:'$OSTIDX'/ { print $1 }')
17314         OST=${OST%_UUID}
17315
17316         # on the mdt's osc
17317         local mdtosc_proc1=$(get_mdtosc_proc_path $SINGLEMDS $OST)
17318         local last_id=$(do_facet $SINGLEMDS lctl get_param -n \
17319                         osp.$mdtosc_proc1.prealloc_last_id)
17320         local next_id=$(do_facet $SINGLEMDS lctl get_param -n \
17321                         osp.$mdtosc_proc1.prealloc_next_id)
17322
17323         $LFS df -i
17324
17325         do_facet ost$((OSTIDX + 1)) lctl set_param fail_val=-1
17326         #define OBD_FAIL_OST_ENOINO              0x229
17327         do_facet ost$((OSTIDX + 1)) lctl set_param fail_loc=0x229
17328         create_pool $FSNAME.$TESTNAME || return 1
17329         do_facet mgs $LCTL pool_add $FSNAME.$TESTNAME $OST || return 2
17330
17331         $LFS setstripe $DIR/$tdir -i $OSTIDX -c 1 -p $FSNAME.$TESTNAME
17332
17333         MDSOBJS=$((last_id - next_id))
17334         echo "preallocated objects on MDS is $MDSOBJS" "($last_id - $next_id)"
17335
17336         blocks=$($LFS df $MOUNT | awk '($1 == '$OSTIDX') { print $4 }')
17337         echo "OST still has $count kbytes free"
17338
17339         echo "create $MDSOBJS files @next_id..."
17340         createmany -o $DIR/$tdir/f $MDSOBJS || return 3
17341
17342         local last_id2=$(do_facet mds${MDSIDX} lctl get_param -n \
17343                         osp.$mdtosc_proc1.prealloc_last_id)
17344         local next_id2=$(do_facet mds${MDSIDX} lctl get_param -n \
17345                         osp.$mdtosc_proc1.prealloc_next_id)
17346
17347         echo "after creation, last_id=$last_id2, next_id=$next_id2"
17348         $LFS df -i
17349
17350         echo "cleanup..."
17351
17352         do_facet ost$((OSTIDX + 1)) lctl set_param fail_val=0
17353         do_facet ost$((OSTIDX + 1)) lctl set_param fail_loc=0
17354
17355         do_facet mgs $LCTL pool_remove $FSNAME.$TESTNAME $OST ||
17356                 error "$LCTL pool_remove $FSNAME.$TESTNAME $OST failed"
17357         do_facet mgs $LCTL pool_destroy $FSNAME.$TESTNAME ||
17358                 error "$LCTL pool_destroy $FSNAME.$TESTNAME failed"
17359         echo "unlink $MDSOBJS files @$next_id..."
17360         unlinkmany $DIR/$tdir/f $MDSOBJS || error "unlinkmany failed"
17361 }
17362 run_test 220 "preallocated MDS objects still used if ENOSPC from OST"
17363
17364 test_221() {
17365         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17366
17367         dd if=`which date` of=$MOUNT/date oflag=sync
17368         chmod +x $MOUNT/date
17369
17370         #define OBD_FAIL_LLITE_FAULT_TRUNC_RACE  0x1401
17371         $LCTL set_param fail_loc=0x80001401
17372
17373         $MOUNT/date > /dev/null
17374         rm -f $MOUNT/date
17375 }
17376 run_test 221 "make sure fault and truncate race to not cause OOM"
17377
17378 test_222a () {
17379         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17380
17381         rm -rf $DIR/$tdir
17382         test_mkdir $DIR/$tdir
17383         $LFS setstripe -c 1 -i 0 $DIR/$tdir
17384         createmany -o $DIR/$tdir/$tfile 10
17385         cancel_lru_locks mdc
17386         cancel_lru_locks osc
17387         #define OBD_FAIL_LDLM_AGL_DELAY           0x31a
17388         $LCTL set_param fail_loc=0x31a
17389         ls -l $DIR/$tdir > /dev/null || error "AGL for ls failed"
17390         $LCTL set_param fail_loc=0
17391         rm -r $DIR/$tdir
17392 }
17393 run_test 222a "AGL for ls should not trigger CLIO lock failure"
17394
17395 test_222b () {
17396         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17397
17398         rm -rf $DIR/$tdir
17399         test_mkdir $DIR/$tdir
17400         $LFS setstripe -c 1 -i 0 $DIR/$tdir
17401         createmany -o $DIR/$tdir/$tfile 10
17402         cancel_lru_locks mdc
17403         cancel_lru_locks osc
17404         #define OBD_FAIL_LDLM_AGL_DELAY           0x31a
17405         $LCTL set_param fail_loc=0x31a
17406         rm -r $DIR/$tdir || error "AGL for rmdir failed"
17407         $LCTL set_param fail_loc=0
17408 }
17409 run_test 222b "AGL for rmdir should not trigger CLIO lock failure"
17410
17411 test_223 () {
17412         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17413
17414         rm -rf $DIR/$tdir
17415         test_mkdir $DIR/$tdir
17416         $LFS setstripe -c 1 -i 0 $DIR/$tdir
17417         createmany -o $DIR/$tdir/$tfile 10
17418         cancel_lru_locks mdc
17419         cancel_lru_locks osc
17420         #define OBD_FAIL_LDLM_AGL_NOLOCK          0x31b
17421         $LCTL set_param fail_loc=0x31b
17422         ls -l $DIR/$tdir > /dev/null || error "reenqueue failed"
17423         $LCTL set_param fail_loc=0
17424         rm -r $DIR/$tdir
17425 }
17426 run_test 223 "osc reenqueue if without AGL lock granted ======================="
17427
17428 test_224a() { # LU-1039, MRP-303
17429         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17430
17431         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB   0x508
17432         $LCTL set_param fail_loc=0x508
17433         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 conv=fsync
17434         $LCTL set_param fail_loc=0
17435         df $DIR
17436 }
17437 run_test 224a "Don't panic on bulk IO failure"
17438
17439 test_224b() { # LU-1039, MRP-303
17440         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17441
17442         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1
17443         cancel_lru_locks osc
17444         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB2   0x515
17445         $LCTL set_param fail_loc=0x515
17446         dd of=/dev/null if=$DIR/$tfile bs=4096 count=1
17447         $LCTL set_param fail_loc=0
17448         df $DIR
17449 }
17450 run_test 224b "Don't panic on bulk IO failure"
17451
17452 test_224c() { # LU-6441
17453         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17454         remote_mds_nodsh && skip "remote MDS with nodsh"
17455
17456         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
17457         save_writethrough $p
17458         set_cache writethrough on
17459
17460         local pages_per_rpc=$($LCTL get_param osc.*.max_pages_per_rpc)
17461         local at_max=$($LCTL get_param -n at_max)
17462         local timeout=$($LCTL get_param -n timeout)
17463         local test_at="at_max"
17464         local param_at="$FSNAME.sys.at_max"
17465         local test_timeout="timeout"
17466         local param_timeout="$FSNAME.sys.timeout"
17467
17468         $LCTL set_param -n osc.*.max_pages_per_rpc=1024
17469
17470         set_persistent_param_and_check client "$test_at" "$param_at" 0
17471         set_persistent_param_and_check client "$test_timeout" "$param_timeout" 5
17472
17473         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB3 0x520
17474         do_facet ost1 "$LCTL set_param fail_loc=0x520"
17475         $LFS setstripe -c 1 -i 0 $DIR/$tfile
17476         dd if=/dev/zero of=$DIR/$tfile bs=8MB count=1
17477         sync
17478         do_facet ost1 "$LCTL set_param fail_loc=0"
17479
17480         set_persistent_param_and_check client "$test_at" "$param_at" $at_max
17481         set_persistent_param_and_check client "$test_timeout" "$param_timeout" \
17482                 $timeout
17483
17484         $LCTL set_param -n $pages_per_rpc
17485         restore_lustre_params < $p
17486         rm -f $p
17487 }
17488 run_test 224c "Don't hang if one of md lost during large bulk RPC"
17489
17490 MDSSURVEY=${MDSSURVEY:-$(which mds-survey 2>/dev/null || true)}
17491 test_225a () {
17492         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17493         if [ -z ${MDSSURVEY} ]; then
17494                 skip_env "mds-survey not found"
17495         fi
17496         [ $MDS1_VERSION -ge $(version_code 2.2.51) ] ||
17497                 skip "Need MDS version at least 2.2.51"
17498
17499         local mds=$(facet_host $SINGLEMDS)
17500         local target=$(do_nodes $mds 'lctl dl' |
17501                        awk '{ if ($2 == "UP" && $3 == "mdt") { print $4 }}')
17502
17503         local cmd1="file_count=1000 thrhi=4"
17504         local cmd2="dir_count=2 layer=mdd stripe_count=0"
17505         local cmd3="rslt_loc=${TMP} targets=\"$mds:$target\" $MDSSURVEY"
17506         local cmd="$cmd1 $cmd2 $cmd3"
17507
17508         rm -f ${TMP}/mds_survey*
17509         echo + $cmd
17510         eval $cmd || error "mds-survey with zero-stripe failed"
17511         cat ${TMP}/mds_survey*
17512         rm -f ${TMP}/mds_survey*
17513 }
17514 run_test 225a "Metadata survey sanity with zero-stripe"
17515
17516 test_225b () {
17517         if [ -z ${MDSSURVEY} ]; then
17518                 skip_env "mds-survey not found"
17519         fi
17520         [ $MDS1_VERSION -ge $(version_code 2.2.51) ] ||
17521                 skip "Need MDS version at least 2.2.51"
17522         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17523         remote_mds_nodsh && skip "remote MDS with nodsh"
17524         if [ $($LCTL dl | grep -c osc) -eq 0 ]; then
17525                 skip_env "Need to mount OST to test"
17526         fi
17527
17528         local mds=$(facet_host $SINGLEMDS)
17529         local target=$(do_nodes $mds 'lctl dl' |
17530                        awk '{ if ($2 == "UP" && $3 == "mdt") { print $4 }}')
17531
17532         local cmd1="file_count=1000 thrhi=4"
17533         local cmd2="dir_count=2 layer=mdd stripe_count=1"
17534         local cmd3="rslt_loc=${TMP} targets=\"$mds:$target\" $MDSSURVEY"
17535         local cmd="$cmd1 $cmd2 $cmd3"
17536
17537         rm -f ${TMP}/mds_survey*
17538         echo + $cmd
17539         eval $cmd || error "mds-survey with stripe_count failed"
17540         cat ${TMP}/mds_survey*
17541         rm -f ${TMP}/mds_survey*
17542 }
17543 run_test 225b "Metadata survey sanity with stripe_count = 1"
17544
17545 mcreate_path2fid () {
17546         local mode=$1
17547         local major=$2
17548         local minor=$3
17549         local name=$4
17550         local desc=$5
17551         local path=$DIR/$tdir/$name
17552         local fid
17553         local rc
17554         local fid_path
17555
17556         $MCREATE --mode=$1 --major=$2 --minor=$3 $path ||
17557                 error "cannot create $desc"
17558
17559         fid=$($LFS path2fid $path | tr -d '[' | tr -d ']')
17560         rc=$?
17561         [ $rc -ne 0 ] && error "cannot get fid of a $desc"
17562
17563         fid_path=$($LFS fid2path $MOUNT $fid)
17564         rc=$?
17565         [ $rc -ne 0 ] && error "cannot get path of $desc by $DIR $path $fid"
17566
17567         [ "$path" == "$fid_path" ] ||
17568                 error "fid2path returned $fid_path, expected $path"
17569
17570         echo "pass with $path and $fid"
17571 }
17572
17573 test_226a () {
17574         rm -rf $DIR/$tdir
17575         mkdir -p $DIR/$tdir
17576
17577         mcreate_path2fid 0010666 0 0 fifo "FIFO"
17578         mcreate_path2fid 0020666 1 3 null "character special file (null)"
17579         mcreate_path2fid 0020666 1 255 none "character special file (no device)"
17580         mcreate_path2fid 0040666 0 0 dir "directory"
17581         mcreate_path2fid 0060666 7 0 loop0 "block special file (loop)"
17582         mcreate_path2fid 0100666 0 0 file "regular file"
17583         mcreate_path2fid 0120666 0 0 link "symbolic link"
17584         mcreate_path2fid 0140666 0 0 sock "socket"
17585 }
17586 run_test 226a "call path2fid and fid2path on files of all type"
17587
17588 test_226b () {
17589         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
17590
17591         local MDTIDX=1
17592
17593         rm -rf $DIR/$tdir
17594         mkdir -p $DIR/$tdir
17595         $LFS setdirstripe -i $MDTIDX $DIR/$tdir/remote_dir ||
17596                 error "create remote directory failed"
17597         mcreate_path2fid 0010666 0 0 "remote_dir/fifo" "FIFO"
17598         mcreate_path2fid 0020666 1 3 "remote_dir/null" \
17599                                 "character special file (null)"
17600         mcreate_path2fid 0020666 1 255 "remote_dir/none" \
17601                                 "character special file (no device)"
17602         mcreate_path2fid 0040666 0 0 "remote_dir/dir" "directory"
17603         mcreate_path2fid 0060666 7 0 "remote_dir/loop0" \
17604                                 "block special file (loop)"
17605         mcreate_path2fid 0100666 0 0 "remote_dir/file" "regular file"
17606         mcreate_path2fid 0120666 0 0 "remote_dir/link" "symbolic link"
17607         mcreate_path2fid 0140666 0 0 "remote_dir/sock" "socket"
17608 }
17609 run_test 226b "call path2fid and fid2path on files of all type under remote dir"
17610
17611 test_226c () {
17612         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
17613         [[ $MDS1_VERSION -ge $(version_code 2.13.55) ]] ||
17614                 skip "Need MDS version at least 2.13.55"
17615
17616         local submnt=/mnt/submnt
17617         local srcfile=/etc/passwd
17618         local dstfile=$submnt/passwd
17619         local path
17620         local fid
17621
17622         rm -rf $DIR/$tdir
17623         rm -rf $submnt
17624         $LFS setdirstripe -c -1 -i 1 $DIR/$tdir ||
17625                 error "create remote directory failed"
17626         mkdir -p $submnt || error "create $submnt failed"
17627         $MOUNT_CMD $MGSNID:/$FSNAME/$tdir $submnt ||
17628                 error "mount $submnt failed"
17629         stack_trap "umount $submnt" EXIT
17630
17631         cp $srcfile $dstfile
17632         fid=$($LFS path2fid $dstfile)
17633         path=$($LFS fid2path $submnt "$fid")
17634         [ "$path" = "$dstfile" ] ||
17635                 error "fid2path $submnt $fid failed ($path != $dstfile)"
17636 }
17637 run_test 226c "call path2fid and fid2path under remote dir with subdir mount"
17638
17639 # LU-1299 Executing or running ldd on a truncated executable does not
17640 # cause an out-of-memory condition.
17641 test_227() {
17642         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17643         [ -z "$(which ldd)" ] && skip_env "should have ldd tool"
17644
17645         dd if=$(which date) of=$MOUNT/date bs=1k count=1
17646         chmod +x $MOUNT/date
17647
17648         $MOUNT/date > /dev/null
17649         ldd $MOUNT/date > /dev/null
17650         rm -f $MOUNT/date
17651 }
17652 run_test 227 "running truncated executable does not cause OOM"
17653
17654 # LU-1512 try to reuse idle OI blocks
17655 test_228a() {
17656         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17657         remote_mds_nodsh && skip "remote MDS with nodsh"
17658         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
17659
17660         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
17661         local myDIR=$DIR/$tdir
17662
17663         mkdir -p $myDIR
17664         #define OBD_FAIL_SEQ_EXHAUST             0x1002
17665         $LCTL set_param fail_loc=0x80001002
17666         createmany -o $myDIR/t- 10000
17667         $LCTL set_param fail_loc=0
17668         # The guard is current the largest FID holder
17669         touch $myDIR/guard
17670         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
17671                     tr -d '[')
17672         local IDX=$(($SEQ % 64))
17673
17674         do_facet $SINGLEMDS sync
17675         # Make sure journal flushed.
17676         sleep 6
17677         local blk1=$(do_facet $SINGLEMDS \
17678                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
17679                      grep Blockcount | awk '{print $4}')
17680
17681         # Remove old files, some OI blocks will become idle.
17682         unlinkmany $myDIR/t- 10000
17683         # Create new files, idle OI blocks should be reused.
17684         createmany -o $myDIR/t- 2000
17685         do_facet $SINGLEMDS sync
17686         # Make sure journal flushed.
17687         sleep 6
17688         local blk2=$(do_facet $SINGLEMDS \
17689                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
17690                      grep Blockcount | awk '{print $4}')
17691
17692         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
17693 }
17694 run_test 228a "try to reuse idle OI blocks"
17695
17696 test_228b() {
17697         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17698         remote_mds_nodsh && skip "remote MDS with nodsh"
17699         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
17700
17701         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
17702         local myDIR=$DIR/$tdir
17703
17704         mkdir -p $myDIR
17705         #define OBD_FAIL_SEQ_EXHAUST             0x1002
17706         $LCTL set_param fail_loc=0x80001002
17707         createmany -o $myDIR/t- 10000
17708         $LCTL set_param fail_loc=0
17709         # The guard is current the largest FID holder
17710         touch $myDIR/guard
17711         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
17712                     tr -d '[')
17713         local IDX=$(($SEQ % 64))
17714
17715         do_facet $SINGLEMDS sync
17716         # Make sure journal flushed.
17717         sleep 6
17718         local blk1=$(do_facet $SINGLEMDS \
17719                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
17720                      grep Blockcount | awk '{print $4}')
17721
17722         # Remove old files, some OI blocks will become idle.
17723         unlinkmany $myDIR/t- 10000
17724
17725         # stop the MDT
17726         stop $SINGLEMDS || error "Fail to stop MDT."
17727         # remount the MDT
17728         start $SINGLEMDS $MDT_DEV $MDS_MOUNT_OPTS || error "Fail to start MDT."
17729
17730         df $MOUNT || error "Fail to df."
17731         # Create new files, idle OI blocks should be reused.
17732         createmany -o $myDIR/t- 2000
17733         do_facet $SINGLEMDS sync
17734         # Make sure journal flushed.
17735         sleep 6
17736         local blk2=$(do_facet $SINGLEMDS \
17737                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
17738                      grep Blockcount | awk '{print $4}')
17739
17740         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
17741 }
17742 run_test 228b "idle OI blocks can be reused after MDT restart"
17743
17744 #LU-1881
17745 test_228c() {
17746         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17747         remote_mds_nodsh && skip "remote MDS with nodsh"
17748         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
17749
17750         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
17751         local myDIR=$DIR/$tdir
17752
17753         mkdir -p $myDIR
17754         #define OBD_FAIL_SEQ_EXHAUST             0x1002
17755         $LCTL set_param fail_loc=0x80001002
17756         # 20000 files can guarantee there are index nodes in the OI file
17757         createmany -o $myDIR/t- 20000
17758         $LCTL set_param fail_loc=0
17759         # The guard is current the largest FID holder
17760         touch $myDIR/guard
17761         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
17762                     tr -d '[')
17763         local IDX=$(($SEQ % 64))
17764
17765         do_facet $SINGLEMDS sync
17766         # Make sure journal flushed.
17767         sleep 6
17768         local blk1=$(do_facet $SINGLEMDS \
17769                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
17770                      grep Blockcount | awk '{print $4}')
17771
17772         # Remove old files, some OI blocks will become idle.
17773         unlinkmany $myDIR/t- 20000
17774         rm -f $myDIR/guard
17775         # The OI file should become empty now
17776
17777         # Create new files, idle OI blocks should be reused.
17778         createmany -o $myDIR/t- 2000
17779         do_facet $SINGLEMDS sync
17780         # Make sure journal flushed.
17781         sleep 6
17782         local blk2=$(do_facet $SINGLEMDS \
17783                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
17784                      grep Blockcount | awk '{print $4}')
17785
17786         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
17787 }
17788 run_test 228c "NOT shrink the last entry in OI index node to recycle idle leaf"
17789
17790 test_229() { # LU-2482, LU-3448
17791         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17792         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
17793         [ $MDS1_VERSION -lt $(version_code 2.4.53) ] &&
17794                 skip "No HSM $(lustre_build_version $SINGLEMDS) MDS < 2.4.53"
17795
17796         rm -f $DIR/$tfile
17797
17798         # Create a file with a released layout and stripe count 2.
17799         $MULTIOP $DIR/$tfile H2c ||
17800                 error "failed to create file with released layout"
17801
17802         $LFS getstripe -v $DIR/$tfile
17803
17804         local pattern=$($LFS getstripe -L $DIR/$tfile)
17805         [ X"$pattern" = X"released" ] || error "pattern error ($pattern)"
17806
17807         local stripe_count=$($LFS getstripe -c $DIR/$tfile) ||
17808                 error "getstripe"
17809         [ $stripe_count -eq 2 ] || error "stripe count not 2 ($stripe_count)"
17810         stat $DIR/$tfile || error "failed to stat released file"
17811
17812         chown $RUNAS_ID $DIR/$tfile ||
17813                 error "chown $RUNAS_ID $DIR/$tfile failed"
17814
17815         chgrp $RUNAS_ID $DIR/$tfile ||
17816                 error "chgrp $RUNAS_ID $DIR/$tfile failed"
17817
17818         touch $DIR/$tfile || error "touch $DIR/$tfile failed"
17819         rm $DIR/$tfile || error "failed to remove released file"
17820 }
17821 run_test 229 "getstripe/stat/rm/attr changes work on released files"
17822
17823 test_230a() {
17824         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17825         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
17826         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
17827                 skip "Need MDS version at least 2.11.52"
17828
17829         local MDTIDX=1
17830
17831         test_mkdir $DIR/$tdir
17832         test_mkdir -i0 -c1 $DIR/$tdir/test_230_local
17833         local mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230_local)
17834         [ $mdt_idx -ne 0 ] &&
17835                 error "create local directory on wrong MDT $mdt_idx"
17836
17837         $LFS mkdir -i $MDTIDX $DIR/$tdir/test_230 ||
17838                         error "create remote directory failed"
17839         local mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230)
17840         [ $mdt_idx -ne $MDTIDX ] &&
17841                 error "create remote directory on wrong MDT $mdt_idx"
17842
17843         createmany -o $DIR/$tdir/test_230/t- 10 ||
17844                 error "create files on remote directory failed"
17845         mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230/t-0)
17846         [ $mdt_idx -ne $MDTIDX ] && error "create files on wrong MDT $mdt_idx"
17847         rm -r $DIR/$tdir || error "unlink remote directory failed"
17848 }
17849 run_test 230a "Create remote directory and files under the remote directory"
17850
17851 test_230b() {
17852         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17853         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
17854         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
17855                 skip "Need MDS version at least 2.11.52"
17856
17857         local MDTIDX=1
17858         local mdt_index
17859         local i
17860         local file
17861         local pid
17862         local stripe_count
17863         local migrate_dir=$DIR/$tdir/migrate_dir
17864         local other_dir=$DIR/$tdir/other_dir
17865
17866         test_mkdir $DIR/$tdir
17867         test_mkdir -i0 -c1 $migrate_dir
17868         test_mkdir -i0 -c1 $other_dir
17869         for ((i=0; i<10; i++)); do
17870                 mkdir -p $migrate_dir/dir_${i}
17871                 createmany -o $migrate_dir/dir_${i}/f 10 ||
17872                         error "create files under remote dir failed $i"
17873         done
17874
17875         cp /etc/passwd $migrate_dir/$tfile
17876         cp /etc/passwd $other_dir/$tfile
17877         chattr +SAD $migrate_dir
17878         chattr +SAD $migrate_dir/$tfile
17879
17880         local old_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
17881         local old_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
17882         local old_dir_mode=$(stat -c%f $migrate_dir)
17883         local old_file_mode=$(stat -c%f $migrate_dir/$tfile)
17884
17885         mkdir -p $migrate_dir/dir_default_stripe2
17886         $LFS setstripe -c 2 $migrate_dir/dir_default_stripe2
17887         $LFS setstripe -c 2 $migrate_dir/${tfile}_stripe2
17888
17889         mkdir -p $other_dir
17890         ln $migrate_dir/$tfile $other_dir/luna
17891         ln $migrate_dir/$tfile $migrate_dir/sofia
17892         ln $other_dir/$tfile $migrate_dir/david
17893         ln -s $migrate_dir/$tfile $other_dir/zachary
17894         ln -s $migrate_dir/$tfile $migrate_dir/${tfile}_ln
17895         ln -s $other_dir/$tfile $migrate_dir/${tfile}_ln_other
17896
17897         local len
17898         local lnktgt
17899
17900         # inline symlink
17901         for len in 58 59 60; do
17902                 lnktgt=$(str_repeat 'l' $len)
17903                 touch $migrate_dir/$lnktgt
17904                 ln -s $lnktgt $migrate_dir/${len}char_ln
17905         done
17906
17907         # PATH_MAX
17908         for len in 4094 4095; do
17909                 lnktgt=$(str_repeat 'l' $len)
17910                 ln -s $lnktgt $migrate_dir/${len}char_ln
17911         done
17912
17913         # NAME_MAX
17914         for len in 254 255; do
17915                 touch $migrate_dir/$(str_repeat 'l' $len)
17916         done
17917
17918         $LFS migrate -m $MDTIDX $migrate_dir ||
17919                 error "fails on migrating remote dir to MDT1"
17920
17921         echo "migratate to MDT1, then checking.."
17922         for ((i = 0; i < 10; i++)); do
17923                 for file in $(find $migrate_dir/dir_${i}); do
17924                         mdt_index=$($LFS getstripe -m $file)
17925                         # broken symlink getstripe will fail
17926                         [ $mdt_index -ne $MDTIDX ] && stat -L $file &&
17927                                 error "$file is not on MDT${MDTIDX}"
17928                 done
17929         done
17930
17931         # the multiple link file should still in MDT0
17932         mdt_index=$($LFS getstripe -m $migrate_dir/$tfile)
17933         [ $mdt_index == 0 ] ||
17934                 error "$file is not on MDT${MDTIDX}"
17935
17936         local new_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
17937         [ "$old_dir_flag" = "$new_dir_flag" ] ||
17938                 error " expect $old_dir_flag get $new_dir_flag"
17939
17940         local new_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
17941         [ "$old_file_flag" = "$new_file_flag" ] ||
17942                 error " expect $old_file_flag get $new_file_flag"
17943
17944         local new_dir_mode=$(stat -c%f $migrate_dir)
17945         [ "$old_dir_mode" = "$new_dir_mode" ] ||
17946                 error "expect mode $old_dir_mode get $new_dir_mode"
17947
17948         local new_file_mode=$(stat -c%f $migrate_dir/$tfile)
17949         [ "$old_file_mode" = "$new_file_mode" ] ||
17950                 error "expect mode $old_file_mode get $new_file_mode"
17951
17952         diff /etc/passwd $migrate_dir/$tfile ||
17953                 error "$tfile different after migration"
17954
17955         diff /etc/passwd $other_dir/luna ||
17956                 error "luna different after migration"
17957
17958         diff /etc/passwd $migrate_dir/sofia ||
17959                 error "sofia different after migration"
17960
17961         diff /etc/passwd $migrate_dir/david ||
17962                 error "david different after migration"
17963
17964         diff /etc/passwd $other_dir/zachary ||
17965                 error "zachary different after migration"
17966
17967         diff /etc/passwd $migrate_dir/${tfile}_ln ||
17968                 error "${tfile}_ln different after migration"
17969
17970         diff /etc/passwd $migrate_dir/${tfile}_ln_other ||
17971                 error "${tfile}_ln_other different after migration"
17972
17973         stripe_count=$($LFS getstripe -c $migrate_dir/dir_default_stripe2)
17974         [ $stripe_count = 2 ] ||
17975                 error "dir strpe_count $d != 2 after migration."
17976
17977         stripe_count=$($LFS getstripe -c $migrate_dir/${tfile}_stripe2)
17978         [ $stripe_count = 2 ] ||
17979                 error "file strpe_count $d != 2 after migration."
17980
17981         #migrate back to MDT0
17982         MDTIDX=0
17983
17984         $LFS migrate -m $MDTIDX $migrate_dir ||
17985                 error "fails on migrating remote dir to MDT0"
17986
17987         echo "migrate back to MDT0, checking.."
17988         for file in $(find $migrate_dir); do
17989                 mdt_index=$($LFS getstripe -m $file)
17990                 [ $mdt_index -ne $MDTIDX ] && stat -L $file &&
17991                         error "$file is not on MDT${MDTIDX}"
17992         done
17993
17994         local new_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
17995         [ "$old_dir_flag" = "$new_dir_flag" ] ||
17996                 error " expect $old_dir_flag get $new_dir_flag"
17997
17998         local new_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
17999         [ "$old_file_flag" = "$new_file_flag" ] ||
18000                 error " expect $old_file_flag get $new_file_flag"
18001
18002         local new_dir_mode=$(stat -c%f $migrate_dir)
18003         [ "$old_dir_mode" = "$new_dir_mode" ] ||
18004                 error "expect mode $old_dir_mode get $new_dir_mode"
18005
18006         local new_file_mode=$(stat -c%f $migrate_dir/$tfile)
18007         [ "$old_file_mode" = "$new_file_mode" ] ||
18008                 error "expect mode $old_file_mode get $new_file_mode"
18009
18010         diff /etc/passwd ${migrate_dir}/$tfile ||
18011                 error "$tfile different after migration"
18012
18013         diff /etc/passwd ${other_dir}/luna ||
18014                 error "luna different after migration"
18015
18016         diff /etc/passwd ${migrate_dir}/sofia ||
18017                 error "sofia different after migration"
18018
18019         diff /etc/passwd ${other_dir}/zachary ||
18020                 error "zachary different after migration"
18021
18022         diff /etc/passwd $migrate_dir/${tfile}_ln ||
18023                 error "${tfile}_ln different after migration"
18024
18025         diff /etc/passwd $migrate_dir/${tfile}_ln_other ||
18026                 error "${tfile}_ln_other different after migration"
18027
18028         stripe_count=$($LFS getstripe -c ${migrate_dir}/dir_default_stripe2)
18029         [ $stripe_count = 2 ] ||
18030                 error "dir strpe_count $d != 2 after migration."
18031
18032         stripe_count=$($LFS getstripe -c ${migrate_dir}/${tfile}_stripe2)
18033         [ $stripe_count = 2 ] ||
18034                 error "file strpe_count $d != 2 after migration."
18035
18036         rm -rf $DIR/$tdir || error "rm dir failed after migration"
18037 }
18038 run_test 230b "migrate directory"
18039
18040 test_230c() {
18041         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18042         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18043         remote_mds_nodsh && skip "remote MDS with nodsh"
18044         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
18045                 skip "Need MDS version at least 2.11.52"
18046
18047         local MDTIDX=1
18048         local total=3
18049         local mdt_index
18050         local file
18051         local migrate_dir=$DIR/$tdir/migrate_dir
18052
18053         #If migrating directory fails in the middle, all entries of
18054         #the directory is still accessiable.
18055         test_mkdir $DIR/$tdir
18056         test_mkdir -i0 -c1 $migrate_dir
18057         test_mkdir -i1 -c1 $DIR/$tdir/remote_dir
18058         stat $migrate_dir
18059         createmany -o $migrate_dir/f $total ||
18060                 error "create files under ${migrate_dir} failed"
18061
18062         # fail after migrating top dir, and this will fail only once, so the
18063         # first sub file migration will fail (currently f3), others succeed.
18064         #OBD_FAIL_MIGRATE_ENTRIES       0x1801
18065         do_facet mds1 lctl set_param fail_loc=0x1801
18066         local t=$(ls $migrate_dir | wc -l)
18067         $LFS migrate --mdt-index $MDTIDX $migrate_dir &&
18068                 error "migrate should fail"
18069         local u=$(ls $migrate_dir | wc -l)
18070         [ "$u" == "$t" ] || error "$u != $t during migration"
18071
18072         # add new dir/file should succeed
18073         mkdir $migrate_dir/dir ||
18074                 error "mkdir failed under migrating directory"
18075         touch $migrate_dir/file ||
18076                 error "create file failed under migrating directory"
18077
18078         # add file with existing name should fail
18079         for file in $migrate_dir/f*; do
18080                 stat $file > /dev/null || error "stat $file failed"
18081                 $OPENFILE -f O_CREAT:O_EXCL $file &&
18082                         error "open(O_CREAT|O_EXCL) $file should fail"
18083                 $MULTIOP $file m && error "create $file should fail"
18084                 touch $DIR/$tdir/remote_dir/$tfile ||
18085                         error "touch $tfile failed"
18086                 ln $DIR/$tdir/remote_dir/$tfile $file &&
18087                         error "link $file should fail"
18088                 mdt_index=$($LFS getstripe -m $file)
18089                 if [ $mdt_index == 0 ]; then
18090                         # file failed to migrate is not allowed to rename to
18091                         mv $DIR/$tdir/remote_dir/$tfile $file &&
18092                                 error "rename to $file should fail"
18093                 else
18094                         mv $DIR/$tdir/remote_dir/$tfile $file ||
18095                                 error "rename to $file failed"
18096                 fi
18097                 echo hello >> $file || error "write $file failed"
18098         done
18099
18100         # resume migration with different options should fail
18101         $LFS migrate -m 0 $migrate_dir &&
18102                 error "migrate -m 0 $migrate_dir should fail"
18103
18104         $LFS migrate -m $MDTIDX -c 2 $migrate_dir &&
18105                 error "migrate -c 2 $migrate_dir should fail"
18106
18107         # resume migration should succeed
18108         $LFS migrate -m $MDTIDX $migrate_dir ||
18109                 error "migrate $migrate_dir failed"
18110
18111         echo "Finish migration, then checking.."
18112         for file in $(find $migrate_dir); do
18113                 mdt_index=$($LFS getstripe -m $file)
18114                 [ $mdt_index == $MDTIDX ] ||
18115                         error "$file is not on MDT${MDTIDX}"
18116         done
18117
18118         rm -rf $DIR/$tdir || error "rm dir failed after migration"
18119 }
18120 run_test 230c "check directory accessiblity if migration failed"
18121
18122 test_230d() {
18123         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18124         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18125         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
18126                 skip "Need MDS version at least 2.11.52"
18127         # LU-11235
18128         [ "$mds1_FSTYPE" == "zfs" ] && skip "skip ZFS backend"
18129
18130         local migrate_dir=$DIR/$tdir/migrate_dir
18131         local old_index
18132         local new_index
18133         local old_count
18134         local new_count
18135         local new_hash
18136         local mdt_index
18137         local i
18138         local j
18139
18140         old_index=$((RANDOM % MDSCOUNT))
18141         old_count=$((MDSCOUNT - old_index))
18142         new_index=$((RANDOM % MDSCOUNT))
18143         new_count=$((MDSCOUNT - new_index))
18144         new_hash=1 # for all_char
18145
18146         [ $old_count -gt 1 ] && old_count=$((old_count - RANDOM % old_count))
18147         [ $new_count -gt 1 ] && new_count=$((new_count - RANDOM % new_count))
18148
18149         test_mkdir $DIR/$tdir
18150         test_mkdir -i $old_index -c $old_count $migrate_dir
18151
18152         for ((i=0; i<100; i++)); do
18153                 test_mkdir -i0 -c1 $migrate_dir/dir_${i}
18154                 createmany -o $migrate_dir/dir_${i}/f 100 ||
18155                         error "create files under remote dir failed $i"
18156         done
18157
18158         echo -n "Migrate from MDT$old_index "
18159         [ $old_count -gt 1 ] && echo -n "... MDT$((old_index + old_count - 1)) "
18160         echo -n "to MDT$new_index"
18161         [ $new_count -gt 1 ] && echo -n " ... MDT$((new_index + new_count - 1))"
18162         echo
18163
18164         echo "$LFS migrate -m$new_index -c$new_count -H $new_hash $migrate_dir"
18165         $LFS migrate -m $new_index -c $new_count -H $new_hash $migrate_dir ||
18166                 error "migrate remote dir error"
18167
18168         echo "Finish migration, then checking.."
18169         for file in $(find $migrate_dir); do
18170                 mdt_index=$($LFS getstripe -m $file)
18171                 if [ $mdt_index -lt $new_index ] ||
18172                    [ $mdt_index -gt $((new_index + new_count - 1)) ]; then
18173                         error "$file is on MDT$mdt_index"
18174                 fi
18175         done
18176
18177         rm -rf $DIR/$tdir || error "rm dir failed after migration"
18178 }
18179 run_test 230d "check migrate big directory"
18180
18181 test_230e() {
18182         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18183         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18184         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
18185                 skip "Need MDS version at least 2.11.52"
18186
18187         local i
18188         local j
18189         local a_fid
18190         local b_fid
18191
18192         mkdir -p $DIR/$tdir
18193         mkdir $DIR/$tdir/migrate_dir
18194         mkdir $DIR/$tdir/other_dir
18195         touch $DIR/$tdir/migrate_dir/a
18196         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/b
18197         ls $DIR/$tdir/other_dir
18198
18199         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
18200                 error "migrate dir fails"
18201
18202         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir)
18203         [ $mdt_index == 1 ] || error "migrate_dir is not on MDT1"
18204
18205         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
18206         [ $mdt_index == 0 ] || error "a is not on MDT0"
18207
18208         $LFS migrate -m 1 $DIR/$tdir/other_dir ||
18209                 error "migrate dir fails"
18210
18211         mdt_index=$($LFS getstripe -m $DIR/$tdir/other_dir)
18212         [ $mdt_index == 1 ] || error "other_dir is not on MDT1"
18213
18214         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
18215         [ $mdt_index == 1 ] || error "a is not on MDT1"
18216
18217         mdt_index=$($LFS getstripe -m $DIR/$tdir/other_dir/b)
18218         [ $mdt_index == 1 ] || error "b is not on MDT1"
18219
18220         a_fid=$($LFS path2fid $DIR/$tdir/migrate_dir/a)
18221         b_fid=$($LFS path2fid $DIR/$tdir/other_dir/b)
18222
18223         [ "$a_fid" = "$b_fid" ] || error "different fid after migration"
18224
18225         rm -rf $DIR/$tdir || error "rm dir failed after migration"
18226 }
18227 run_test 230e "migrate mulitple local link files"
18228
18229 test_230f() {
18230         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18231         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18232         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
18233                 skip "Need MDS version at least 2.11.52"
18234
18235         local a_fid
18236         local ln_fid
18237
18238         mkdir -p $DIR/$tdir
18239         mkdir $DIR/$tdir/migrate_dir
18240         $LFS mkdir -i1 $DIR/$tdir/other_dir
18241         touch $DIR/$tdir/migrate_dir/a
18242         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/ln1
18243         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/ln2
18244         ls $DIR/$tdir/other_dir
18245
18246         # a should be migrated to MDT1, since no other links on MDT0
18247         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
18248                 error "#1 migrate dir fails"
18249         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir)
18250         [ $mdt_index == 1 ] || error "migrate_dir is not on MDT1"
18251         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
18252         [ $mdt_index == 1 ] || error "a is not on MDT1"
18253
18254         # a should stay on MDT1, because it is a mulitple link file
18255         $LFS migrate -m 0 $DIR/$tdir/migrate_dir ||
18256                 error "#2 migrate dir fails"
18257         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
18258         [ $mdt_index == 1 ] || error "a is not on MDT1"
18259
18260         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
18261                 error "#3 migrate dir fails"
18262
18263         a_fid=$($LFS path2fid $DIR/$tdir/migrate_dir/a)
18264         ln_fid=$($LFS path2fid $DIR/$tdir/other_dir/ln1)
18265         [ "$a_fid" = "$ln_fid" ] || error "different fid after migrate to MDT1"
18266
18267         rm -rf $DIR/$tdir/other_dir/ln1 || error "unlink ln1 fails"
18268         rm -rf $DIR/$tdir/other_dir/ln2 || error "unlink ln2 fails"
18269
18270         # a should be migrated to MDT0, since no other links on MDT1
18271         $LFS migrate -m 0 $DIR/$tdir/migrate_dir ||
18272                 error "#4 migrate dir fails"
18273         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
18274         [ $mdt_index == 0 ] || error "a is not on MDT0"
18275
18276         rm -rf $DIR/$tdir || error "rm dir failed after migration"
18277 }
18278 run_test 230f "migrate mulitple remote link files"
18279
18280 test_230g() {
18281         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18282         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18283         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
18284                 skip "Need MDS version at least 2.11.52"
18285
18286         mkdir -p $DIR/$tdir/migrate_dir
18287
18288         $LFS migrate -m 1000 $DIR/$tdir/migrate_dir &&
18289                 error "migrating dir to non-exist MDT succeeds"
18290         true
18291 }
18292 run_test 230g "migrate dir to non-exist MDT"
18293
18294 test_230h() {
18295         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18296         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18297         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
18298                 skip "Need MDS version at least 2.11.52"
18299
18300         local mdt_index
18301
18302         mkdir -p $DIR/$tdir/migrate_dir
18303
18304         $LFS migrate -m1 $DIR &&
18305                 error "migrating mountpoint1 should fail"
18306
18307         $LFS migrate -m1 $DIR/$tdir/.. &&
18308                 error "migrating mountpoint2 should fail"
18309
18310         # same as mv
18311         $LFS migrate -m1 $DIR/$tdir/migrate_dir/.. &&
18312                 error "migrating $tdir/migrate_dir/.. should fail"
18313
18314         true
18315 }
18316 run_test 230h "migrate .. and root"
18317
18318 test_230i() {
18319         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18320         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18321         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
18322                 skip "Need MDS version at least 2.11.52"
18323
18324         mkdir -p $DIR/$tdir/migrate_dir
18325
18326         $LFS migrate -m 1 $DIR/$tdir/migrate_dir/ ||
18327                 error "migration fails with a tailing slash"
18328
18329         $LFS migrate -m 0 $DIR/$tdir/migrate_dir// ||
18330                 error "migration fails with two tailing slashes"
18331 }
18332 run_test 230i "lfs migrate -m tolerates trailing slashes"
18333
18334 test_230j() {
18335         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
18336         [ $MDS1_VERSION -lt $(version_code 2.13.52) ] &&
18337                 skip "Need MDS version at least 2.11.52"
18338
18339         $LFS mkdir -m 0 -c 1 $DIR/$tdir || error "mkdir $tdir failed"
18340         $LFS setstripe -E 1M -L mdt $DIR/$tdir/$tfile ||
18341                 error "create $tfile failed"
18342         cat /etc/passwd > $DIR/$tdir/$tfile
18343
18344         $LFS migrate -m 1 $DIR/$tdir || error "migrate failed"
18345
18346         cmp /etc/passwd $DIR/$tdir/$tfile ||
18347                 error "DoM file mismatch after migration"
18348 }
18349 run_test 230j "DoM file data not changed after dir migration"
18350
18351 test_230k() {
18352         [ $MDSCOUNT -lt 4 ] && skip "needs >= 4 MDTs"
18353         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
18354                 skip "Need MDS version at least 2.11.56"
18355
18356         local total=20
18357         local files_on_starting_mdt=0
18358
18359         $LFS mkdir -i -1 -c 2 $DIR/$tdir || error "mkdir failed"
18360         $LFS getdirstripe $DIR/$tdir
18361         for i in $(seq $total); do
18362                 echo $((i*i - i)) > $DIR/$tdir/$tfile.$i || error "write failed"
18363                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 0 ]] &&
18364                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
18365         done
18366
18367         echo "$files_on_starting_mdt files on MDT0"
18368
18369         $LFS migrate -m 1,3 $DIR/$tdir || error "migrate -m 1,3 failed"
18370         $LFS getdirstripe $DIR/$tdir
18371
18372         files_on_starting_mdt=0
18373         for i in $(seq $total); do
18374                 $(echo $((i*i - i)) | cmp $DIR/$tdir/$tfile.$i -) ||
18375                         error "file $tfile.$i mismatch after migration"
18376                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 1 ]] &&
18377                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
18378         done
18379
18380         echo "$files_on_starting_mdt files on MDT1 after migration"
18381         [[ $files_on_starting_mdt -eq $total ]] && error "all files on MDT1"
18382
18383         $LFS migrate -m 0 -c 2 $DIR/$tdir || error "migrate -m 0 -c 2 failed"
18384         $LFS getdirstripe $DIR/$tdir
18385
18386         files_on_starting_mdt=0
18387         for i in $(seq $total); do
18388                 $(echo $((i*i - i)) | cmp $DIR/$tdir/$tfile.$i -) ||
18389                         error "file $tfile.$i mismatch after 2nd migration"
18390                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 0 ]] &&
18391                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
18392         done
18393
18394         echo "$files_on_starting_mdt files on MDT0 after 2nd migration"
18395         [[ $files_on_starting_mdt -eq $total ]] && error "all files on MDT0"
18396
18397         true
18398 }
18399 run_test 230k "file data not changed after dir migration"
18400
18401 test_230l() {
18402         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
18403         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
18404                 skip "Need MDS version at least 2.11.56"
18405
18406         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "mkdir failed"
18407         createmany -o $DIR/$tdir/f___________________________________ 1000 ||
18408                 error "create files under remote dir failed $i"
18409         $LFS migrate -m 1 $DIR/$tdir || error "migrate failed"
18410 }
18411 run_test 230l "readdir between MDTs won't crash"
18412
18413 test_230m() {
18414         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
18415         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
18416                 skip "Need MDS version at least 2.11.56"
18417
18418         local MDTIDX=1
18419         local mig_dir=$DIR/$tdir/migrate_dir
18420         local longstr="aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
18421         local shortstr="b"
18422         local val
18423
18424         echo "Creating files and dirs with xattrs"
18425         test_mkdir $DIR/$tdir
18426         test_mkdir -i0 -c1 $mig_dir
18427         mkdir $mig_dir/dir
18428         setfattr -n user.attr1 -v $longstr $mig_dir/dir ||
18429                 error "cannot set xattr attr1 on dir"
18430         setfattr -n user.attr2 -v $shortstr $mig_dir/dir ||
18431                 error "cannot set xattr attr2 on dir"
18432         touch $mig_dir/dir/f0
18433         setfattr -n user.attr1 -v $longstr $mig_dir/dir/f0 ||
18434                 error "cannot set xattr attr1 on file"
18435         setfattr -n user.attr2 -v $shortstr $mig_dir/dir/f0 ||
18436                 error "cannot set xattr attr2 on file"
18437         sync ; sync ; echo 3 > /proc/sys/vm/drop_caches
18438         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir 2>/dev/null)
18439         [ "$val" = $longstr ] || error "xattr attr1 not set properly on dir"
18440         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir 2>/dev/null)
18441         [ "$val" = $shortstr ] || error "xattr attr2 not set properly on dir"
18442         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir/f0 2>/dev/null)
18443         [ "$val" = $longstr ] || error "xattr attr1 not set properly on file"
18444         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir/f0 2>/dev/null)
18445         [ "$val" = $shortstr ] || error "xattr attr2 not set properly on file"
18446
18447         echo "Migrating to MDT1"
18448         $LFS migrate -m $MDTIDX $mig_dir ||
18449                 error "fails on migrating dir to MDT1"
18450
18451         sync ; sync ; echo 3 > /proc/sys/vm/drop_caches
18452         echo "Checking xattrs"
18453         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir 2>/dev/null)
18454         [ "$val" = $longstr ] ||
18455                 error "expecting xattr1 $longstr on dir, found $val"
18456         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir 2>/dev/null)
18457         [ "$val" = $shortstr ] ||
18458                 error "expecting xattr2 $shortstr on dir, found $val"
18459         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir/f0 2>/dev/null)
18460         [ "$val" = $longstr ] ||
18461                 error "expecting xattr1 $longstr on file, found $val"
18462         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir/f0 2>/dev/null)
18463         [ "$val" = $shortstr ] ||
18464                 error "expecting xattr2 $shortstr on file, found $val"
18465 }
18466 run_test 230m "xattrs not changed after dir migration"
18467
18468 test_230n() {
18469         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
18470         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
18471                 skip "Need MDS version at least 2.13.53"
18472
18473         $LFS mkdir -i 0 $DIR/$tdir || error "mkdir $tdir failed"
18474         cat /etc/hosts > $DIR/$tdir/$tfile
18475         $LFS mirror extend -N1 $DIR/$tdir/$tfile || error "Mirroring failed"
18476         $LFS migrate -m 1 $DIR/$tdir || error "Migration failed"
18477
18478         cmp /etc/hosts $DIR/$tdir/$tfile ||
18479                 error "File data mismatch after migration"
18480 }
18481 run_test 230n "Dir migration with mirrored file"
18482
18483 test_230o() {
18484         [ $MDSCOUNT -ge 2 ] || skip "needs >= 2 MDTs"
18485         [ $MDS1_VERSION -ge $(version_code 2.13.52) ] ||
18486                 skip "Need MDS version at least 2.13.52"
18487
18488         local mdts=$(comma_list $(mdts_nodes))
18489         local timeout=100
18490
18491         local restripe_status
18492         local delta
18493         local i
18494         local j
18495
18496         [[ $(facet_fstype mds1) == zfs ]] && timeout=300
18497
18498         # in case "crush" hash type is not set
18499         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
18500
18501         restripe_status=$(do_facet mds1 $LCTL get_param -n \
18502                            mdt.*MDT0000.enable_dir_restripe)
18503         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=1"
18504         stack_trap "do_nodes $mdts $LCTL set_param \
18505                     mdt.*.enable_dir_restripe=$restripe_status"
18506
18507         mkdir $DIR/$tdir
18508         createmany -m $DIR/$tdir/f 100 ||
18509                 error "create files under remote dir failed $i"
18510         createmany -d $DIR/$tdir/d 100 ||
18511                 error "create dirs under remote dir failed $i"
18512
18513         for i in $(seq 2 $MDSCOUNT); do
18514                 do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear > /dev/null"
18515                 $LFS setdirstripe -c $i $DIR/$tdir ||
18516                         error "split -c $i $tdir failed"
18517                 wait_update $HOSTNAME \
18518                         "$LFS getdirstripe -H $DIR/$tdir" "crush" $timeout ||
18519                         error "dir split not finished"
18520                 delta=$(do_nodes $mdts "lctl get_param -n mdt.*MDT*.md_stats" |
18521                         awk '/migrate/ {sum += $2} END { print sum }')
18522                 echo "$delta files migrated when dir split from $((i - 1)) to $i stripes"
18523                 # delta is around total_files/stripe_count
18524                 [ $delta -lt $((200 /(i - 1))) ] ||
18525                         error "$delta files migrated"
18526         done
18527 }
18528 run_test 230o "dir split"
18529
18530 test_230p() {
18531         [ $MDSCOUNT -ge 2 ] || skip "needs >= 2 MDTs"
18532         [ $MDS1_VERSION -ge $(version_code 2.13.52) ] ||
18533                 skip "Need MDS version at least 2.13.52"
18534
18535         local mdts=$(comma_list $(mdts_nodes))
18536         local timeout=100
18537
18538         local restripe_status
18539         local delta
18540         local i
18541         local j
18542
18543         [[ $(facet_fstype mds1) == zfs ]] && timeout=300
18544
18545         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
18546
18547         restripe_status=$(do_facet mds1 $LCTL get_param -n \
18548                            mdt.*MDT0000.enable_dir_restripe)
18549         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=1"
18550         stack_trap "do_nodes $mdts $LCTL set_param \
18551                     mdt.*.enable_dir_restripe=$restripe_status"
18552
18553         test_mkdir -c $MDSCOUNT -H crush $DIR/$tdir
18554         createmany -m $DIR/$tdir/f 100 ||
18555                 error "create files under remote dir failed $i"
18556         createmany -d $DIR/$tdir/d 100 ||
18557                 error "create dirs under remote dir failed $i"
18558
18559         for i in $(seq $((MDSCOUNT - 1)) -1 1); do
18560                 local mdt_hash="crush"
18561
18562                 do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear > /dev/null"
18563                 $LFS setdirstripe -c $i $DIR/$tdir ||
18564                         error "split -c $i $tdir failed"
18565                 [ $i -eq 1 ] && mdt_hash="none"
18566                 wait_update $HOSTNAME \
18567                         "$LFS getdirstripe -H $DIR/$tdir" $mdt_hash $timeout ||
18568                         error "dir merge not finished"
18569                 delta=$(do_nodes $mdts "lctl get_param -n mdt.*MDT*.md_stats" |
18570                         awk '/migrate/ {sum += $2} END { print sum }')
18571                 echo "$delta files migrated when dir merge from $((i + 1)) to $i stripes"
18572                 # delta is around total_files/stripe_count
18573                 [ $delta -lt $((200 / i)) ] ||
18574                         error "$delta files migrated"
18575         done
18576 }
18577 run_test 230p "dir merge"
18578
18579 test_230q() {
18580         [ $MDSCOUNT -ge 2 ] || skip "needs >= 2 MDTs"
18581         [ $MDS1_VERSION -ge $(version_code 2.13.52) ] ||
18582                 skip "Need MDS version at least 2.13.52"
18583
18584         local mdts=$(comma_list $(mdts_nodes))
18585         local saved_threshold=$(do_facet mds1 \
18586                         $LCTL get_param -n mdt.*-MDT0000.dir_split_count)
18587         local saved_delta=$(do_facet mds1 \
18588                         $LCTL get_param -n mdt.*-MDT0000.dir_split_delta)
18589         local threshold=100
18590         local delta=2
18591         local total=0
18592         local stripe_count=0
18593         local stripe_index
18594         local nr_files
18595
18596         # test with fewer files on ZFS
18597         [ "$mds1_FSTYPE" == "zfs" ] && threshold=40
18598
18599         stack_trap "do_nodes $mdts $LCTL set_param \
18600                     mdt.*.dir_split_count=$saved_threshold"
18601         stack_trap "do_nodes $mdts $LCTL set_param \
18602                     mdt.*.dir_split_delta=$saved_delta"
18603         stack_trap "do_nodes $mdts $LCTL set_param mdt.*.dir_restripe_nsonly=1"
18604         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_auto_split=1"
18605         do_nodes $mdts "$LCTL set_param mdt.*.dir_split_count=$threshold"
18606         do_nodes $mdts "$LCTL set_param mdt.*.dir_split_delta=$delta"
18607         do_nodes $mdts "$LCTL set_param mdt.*.dir_restripe_nsonly=0"
18608         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
18609
18610         $LFS mkdir -i -1 -c 1 $DIR/$tdir || error "mkdir $tdir failed"
18611         stripe_index=$($LFS getdirstripe -i $DIR/$tdir)
18612
18613         while [ $stripe_count -lt $MDSCOUNT ]; do
18614                 createmany -m $DIR/$tdir/f $total $((threshold * 3 / 2)) ||
18615                         error "create sub files failed"
18616                 stat $DIR/$tdir > /dev/null
18617                 total=$((total + threshold * 3 / 2))
18618                 stripe_count=$((stripe_count + delta))
18619                 [ $stripe_count -gt $MDSCOUNT ] && stripe_count=$MDSCOUNT
18620
18621                 wait_update $HOSTNAME \
18622                         "$LFS getdirstripe -c $DIR/$tdir" "$stripe_count" 40 ||
18623                         error "stripe count $($LFS getdirstripe -c $DIR/$tdir) != $stripe_count"
18624
18625                 wait_update $HOSTNAME \
18626                         "$LFS getdirstripe -H $DIR/$tdir" "crush" 200 ||
18627                         error "stripe hash $($LFS getdirstripe -H $DIR/$tdir) != crush"
18628
18629                 nr_files=$($LFS getstripe -m $DIR/$tdir/* |
18630                            grep -w $stripe_index | wc -l)
18631                 echo "$nr_files files on MDT$stripe_index after split"
18632                 [ $nr_files -lt $((total / (stripe_count - 1))) ] ||
18633                         error "$nr_files files on MDT$stripe_index after split"
18634
18635                 nr_files=$(ls $DIR/$tdir | wc -w)
18636                 [ $nr_files -eq $total ] ||
18637                         error "total sub files $nr_files != $total"
18638         done
18639 }
18640 run_test 230q "dir auto split"
18641
18642 test_230r() {
18643         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
18644         [[ $MDSCOUNT -ge 2 ]] || skip_env "needs >= 2 MDTs"
18645         [[ $MDS1_VERSION -ge $(version_code 2.13.54) ]] ||
18646                 skip "Need MDS version at least 2.13.54"
18647
18648         # maximum amount of local locks:
18649         # parent striped dir - 2 locks
18650         # new stripe in parent to migrate to - 1 lock
18651         # source and target - 2 locks
18652         # Total 5 locks for regular file
18653         mkdir -p $DIR/$tdir
18654         $LFS mkdir -i1 -c2 $DIR/$tdir/dir1
18655         touch $DIR/$tdir/dir1/eee
18656
18657         # create 4 hardlink for 4 more locks
18658         # Total: 9 locks > RS_MAX_LOCKS (8)
18659         $LFS mkdir -i1 -c1 $DIR/$tdir/dir2
18660         $LFS mkdir -i1 -c1 $DIR/$tdir/dir3
18661         $LFS mkdir -i1 -c1 $DIR/$tdir/dir4
18662         $LFS mkdir -i1 -c1 $DIR/$tdir/dir5
18663         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir2/eee
18664         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir3/eee
18665         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir4/eee
18666         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir5/eee
18667
18668         cancel_lru_locks mdc
18669
18670         $LFS migrate -m1 -c1 $DIR/$tdir/dir1 ||
18671                 error "migrate dir fails"
18672
18673         rm -rf $DIR/$tdir || error "rm dir failed after migration"
18674 }
18675 run_test 230r "migrate with too many local locks"
18676
18677 test_231a()
18678 {
18679         # For simplicity this test assumes that max_pages_per_rpc
18680         # is the same across all OSCs
18681         local max_pages=$($LCTL get_param -n osc.*.max_pages_per_rpc | head -n1)
18682         local bulk_size=$((max_pages * PAGE_SIZE))
18683         local brw_size=$(do_facet ost1 $LCTL get_param -n obdfilter.*.brw_size |
18684                                        head -n 1)
18685
18686         mkdir -p $DIR/$tdir
18687         $LFS setstripe -S ${brw_size}M $DIR/$tdir ||
18688                 error "failed to set stripe with -S ${brw_size}M option"
18689
18690         # clear the OSC stats
18691         $LCTL set_param osc.*.stats=0 &>/dev/null
18692         stop_writeback
18693
18694         # Client writes $bulk_size - there must be 1 rpc for $max_pages.
18695         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=$bulk_size count=1 \
18696                 oflag=direct &>/dev/null || error "dd failed"
18697
18698         sync; sleep 1; sync # just to be safe
18699         local nrpcs=$($LCTL get_param osc.*.stats |awk '/ost_write/ {print $2}')
18700         if [ x$nrpcs != "x1" ]; then
18701                 $LCTL get_param osc.*.stats
18702                 error "found $nrpcs ost_write RPCs, not 1 as expected"
18703         fi
18704
18705         start_writeback
18706         # Drop the OSC cache, otherwise we will read from it
18707         cancel_lru_locks osc
18708
18709         # clear the OSC stats
18710         $LCTL set_param osc.*.stats=0 &>/dev/null
18711
18712         # Client reads $bulk_size.
18713         dd if=$DIR/$tdir/$tfile of=/dev/null bs=$bulk_size count=1 \
18714                 iflag=direct &>/dev/null || error "dd failed"
18715
18716         nrpcs=$($LCTL get_param osc.*.stats | awk '/ost_read/ { print $2 }')
18717         if [ x$nrpcs != "x1" ]; then
18718                 $LCTL get_param osc.*.stats
18719                 error "found $nrpcs ost_read RPCs, not 1 as expected"
18720         fi
18721 }
18722 run_test 231a "checking that reading/writing of BRW RPC size results in one RPC"
18723
18724 test_231b() {
18725         mkdir -p $DIR/$tdir
18726         local i
18727         for i in {0..1023}; do
18728                 dd if=/dev/zero of=$DIR/$tdir/$tfile conv=notrunc \
18729                         seek=$((2 * i)) bs=4096 count=1 &>/dev/null ||
18730                         error "dd of=$DIR/$tdir/$tfile seek=$((2 * i)) failed"
18731         done
18732         sync
18733 }
18734 run_test 231b "must not assert on fully utilized OST request buffer"
18735
18736 test_232a() {
18737         mkdir -p $DIR/$tdir
18738         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
18739
18740         #define OBD_FAIL_LDLM_OST_LVB            0x31c
18741         do_facet ost1 $LCTL set_param fail_loc=0x31c
18742
18743         # ignore dd failure
18744         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=1 || true
18745
18746         do_facet ost1 $LCTL set_param fail_loc=0
18747         umount_client $MOUNT || error "umount failed"
18748         mount_client $MOUNT || error "mount failed"
18749         stop ost1 || error "cannot stop ost1"
18750         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
18751 }
18752 run_test 232a "failed lock should not block umount"
18753
18754 test_232b() {
18755         [ $MDS1_VERSION -ge $(version_code 2.10.58) ] ||
18756                 skip "Need MDS version at least 2.10.58"
18757
18758         mkdir -p $DIR/$tdir
18759         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
18760         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=1
18761         sync
18762         cancel_lru_locks osc
18763
18764         #define OBD_FAIL_LDLM_OST_LVB            0x31c
18765         do_facet ost1 $LCTL set_param fail_loc=0x31c
18766
18767         # ignore failure
18768         $LFS data_version $DIR/$tdir/$tfile || true
18769
18770         do_facet ost1 $LCTL set_param fail_loc=0
18771         umount_client $MOUNT || error "umount failed"
18772         mount_client $MOUNT || error "mount failed"
18773         stop ost1 || error "cannot stop ost1"
18774         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
18775 }
18776 run_test 232b "failed data version lock should not block umount"
18777
18778 test_233a() {
18779         [ $MDS1_VERSION -ge $(version_code 2.3.64) ] ||
18780                 skip "Need MDS version at least 2.3.64"
18781         [ -n "$FILESET" ] && skip_env "SKIP due to FILESET set"
18782
18783         local fid=$($LFS path2fid $MOUNT)
18784
18785         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
18786                 error "cannot access $MOUNT using its FID '$fid'"
18787 }
18788 run_test 233a "checking that OBF of the FS root succeeds"
18789
18790 test_233b() {
18791         [ $MDS1_VERSION -ge $(version_code 2.5.90) ] ||
18792                 skip "Need MDS version at least 2.5.90"
18793         [ -n "$FILESET" ] && skip_env "SKIP due to FILESET set"
18794
18795         local fid=$($LFS path2fid $MOUNT/.lustre)
18796
18797         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
18798                 error "cannot access $MOUNT/.lustre using its FID '$fid'"
18799
18800         fid=$($LFS path2fid $MOUNT/.lustre/fid)
18801         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
18802                 error "cannot access $MOUNT/.lustre/fid using its FID '$fid'"
18803 }
18804 run_test 233b "checking that OBF of the FS .lustre succeeds"
18805
18806 test_234() {
18807         local p="$TMP/sanityN-$TESTNAME.parameters"
18808         save_lustre_params client "llite.*.xattr_cache" > $p
18809         lctl set_param llite.*.xattr_cache 1 ||
18810                 skip_env "xattr cache is not supported"
18811
18812         mkdir -p $DIR/$tdir || error "mkdir failed"
18813         touch $DIR/$tdir/$tfile || error "touch failed"
18814         # OBD_FAIL_LLITE_XATTR_ENOMEM
18815         $LCTL set_param fail_loc=0x1405
18816         getfattr -n user.attr $DIR/$tdir/$tfile &&
18817                 error "getfattr should have failed with ENOMEM"
18818         $LCTL set_param fail_loc=0x0
18819         rm -rf $DIR/$tdir
18820
18821         restore_lustre_params < $p
18822         rm -f $p
18823 }
18824 run_test 234 "xattr cache should not crash on ENOMEM"
18825
18826 test_235() {
18827         [ $MDS1_VERSION -lt $(version_code 2.4.52) ] &&
18828                 skip "Need MDS version at least 2.4.52"
18829
18830         flock_deadlock $DIR/$tfile
18831         local RC=$?
18832         case $RC in
18833                 0)
18834                 ;;
18835                 124) error "process hangs on a deadlock"
18836                 ;;
18837                 *) error "error executing flock_deadlock $DIR/$tfile"
18838                 ;;
18839         esac
18840 }
18841 run_test 235 "LU-1715: flock deadlock detection does not work properly"
18842
18843 #LU-2935
18844 test_236() {
18845         check_swap_layouts_support
18846
18847         local ref1=/etc/passwd
18848         local ref2=/etc/group
18849         local file1=$DIR/$tdir/f1
18850         local file2=$DIR/$tdir/f2
18851
18852         test_mkdir -c1 $DIR/$tdir
18853         $LFS setstripe -c 1 $file1 || error "cannot setstripe on '$file1': rc = $?"
18854         cp $ref1 $file1 || error "cp $ref1 $file1 failed: rc = $?"
18855         $LFS setstripe -c 2 $file2 || error "cannot setstripe on '$file2': rc = $?"
18856         cp $ref2 $file2 || error "cp $ref2 $file2 failed: rc = $?"
18857         local fd=$(free_fd)
18858         local cmd="exec $fd<>$file2"
18859         eval $cmd
18860         rm $file2
18861         $LFS swap_layouts $file1 /proc/self/fd/${fd} ||
18862                 error "cannot swap layouts of '$file1' and /proc/self/fd/${fd}"
18863         cmd="exec $fd>&-"
18864         eval $cmd
18865         cmp $ref2 $file1 || error "content compare failed ($ref2 != $file1)"
18866
18867         #cleanup
18868         rm -rf $DIR/$tdir
18869 }
18870 run_test 236 "Layout swap on open unlinked file"
18871
18872 # LU-4659 linkea consistency
18873 test_238() {
18874         [[ $MDS1_VERSION -gt $(version_code 2.5.57) ]] ||
18875                 [[ $MDS1_VERSION -gt $(version_code 2.5.1) &&
18876                    $MDS1_VERSION -lt $(version_code 2.5.50) ]] ||
18877                 skip "Need MDS version at least 2.5.58 or 2.5.2+"
18878
18879         touch $DIR/$tfile
18880         ln $DIR/$tfile $DIR/$tfile.lnk
18881         touch $DIR/$tfile.new
18882         mv $DIR/$tfile.new $DIR/$tfile
18883         local fid1=$($LFS path2fid $DIR/$tfile)
18884         local fid2=$($LFS path2fid $DIR/$tfile.lnk)
18885         local path1=$($LFS fid2path $FSNAME "$fid1")
18886         [ $tfile == $path1 ] || error "linkea inconsistent: $tfile $fid1 $path1"
18887         local path2=$($LFS fid2path $FSNAME "$fid2")
18888         [ $tfile.lnk == $path2 ] ||
18889                 error "linkea inconsistent: $tfile.lnk $fid2 $path2!"
18890         rm -f $DIR/$tfile*
18891 }
18892 run_test 238 "Verify linkea consistency"
18893
18894 test_239A() { # was test_239
18895         [ $MDS1_VERSION -lt $(version_code 2.5.60) ] &&
18896                 skip "Need MDS version at least 2.5.60"
18897
18898         local list=$(comma_list $(mdts_nodes))
18899
18900         mkdir -p $DIR/$tdir
18901         createmany -o $DIR/$tdir/f- 5000
18902         unlinkmany $DIR/$tdir/f- 5000
18903         [ $MDS1_VERSION -gt $(version_code 2.10.4) ] &&
18904                 do_nodes $list "lctl set_param -n osp.*.force_sync=1"
18905         changes=$(do_nodes $list "lctl get_param -n osp.*MDT*.sync_changes \
18906                         osp.*MDT*.sync_in_flight" | calc_sum)
18907         [ "$changes" -eq 0 ] || error "$changes not synced"
18908 }
18909 run_test 239A "osp_sync test"
18910
18911 test_239a() { #LU-5297
18912         remote_mds_nodsh && skip "remote MDS with nodsh"
18913
18914         touch $DIR/$tfile
18915         #define OBD_FAIL_OSP_CHECK_INVALID_REC     0x2100
18916         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2100
18917         chgrp $RUNAS_GID $DIR/$tfile
18918         wait_delete_completed
18919 }
18920 run_test 239a "process invalid osp sync record correctly"
18921
18922 test_239b() { #LU-5297
18923         remote_mds_nodsh && skip "remote MDS with nodsh"
18924
18925         touch $DIR/$tfile1
18926         #define OBD_FAIL_OSP_CHECK_ENOMEM     0x2101
18927         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2101
18928         chgrp $RUNAS_GID $DIR/$tfile1
18929         wait_delete_completed
18930         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
18931         touch $DIR/$tfile2
18932         chgrp $RUNAS_GID $DIR/$tfile2
18933         wait_delete_completed
18934 }
18935 run_test 239b "process osp sync record with ENOMEM error correctly"
18936
18937 test_240() {
18938         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18939         remote_mds_nodsh && skip "remote MDS with nodsh"
18940
18941         mkdir -p $DIR/$tdir
18942
18943         $LFS mkdir -i 0 $DIR/$tdir/d0 ||
18944                 error "failed to mkdir $DIR/$tdir/d0 on MDT0"
18945         $LFS mkdir -i 1 $DIR/$tdir/d0/d1 ||
18946                 error "failed to mkdir $DIR/$tdir/d0/d1 on MDT1"
18947
18948         umount_client $MOUNT || error "umount failed"
18949         #define OBD_FAIL_TGT_DELAY_CONDITIONAL   0x713
18950         do_facet mds2 lctl set_param fail_loc=0x713 fail_val=1
18951         mount_client $MOUNT || error "failed to mount client"
18952
18953         echo "stat $DIR/$tdir/d0/d1, should not fail/ASSERT"
18954         stat $DIR/$tdir/d0/d1 || error "fail to stat $DIR/$tdir/d0/d1"
18955 }
18956 run_test 240 "race between ldlm enqueue and the connection RPC (no ASSERT)"
18957
18958 test_241_bio() {
18959         local count=$1
18960         local bsize=$2
18961
18962         for LOOP in $(seq $count); do
18963                 dd if=$DIR/$tfile of=/dev/null bs=$bsize count=1 2>/dev/null
18964                 cancel_lru_locks $OSC || true
18965         done
18966 }
18967
18968 test_241_dio() {
18969         local count=$1
18970         local bsize=$2
18971
18972         for LOOP in $(seq $1); do
18973                 dd if=$DIR/$tfile of=/dev/null bs=$bsize count=1 iflag=direct \
18974                         2>/dev/null
18975         done
18976 }
18977
18978 test_241a() { # was test_241
18979         local bsize=$PAGE_SIZE
18980
18981         (( bsize < 40960 )) && bsize=40960
18982         dd if=/dev/zero of=$DIR/$tfile count=1 bs=$bsize
18983         ls -la $DIR/$tfile
18984         cancel_lru_locks $OSC
18985         test_241_bio 1000 $bsize &
18986         PID=$!
18987         test_241_dio 1000 $bsize
18988         wait $PID
18989 }
18990 run_test 241a "bio vs dio"
18991
18992 test_241b() {
18993         local bsize=$PAGE_SIZE
18994
18995         (( bsize < 40960 )) && bsize=40960
18996         dd if=/dev/zero of=$DIR/$tfile count=1 bs=$bsize
18997         ls -la $DIR/$tfile
18998         test_241_dio 1000 $bsize &
18999         PID=$!
19000         test_241_dio 1000 $bsize
19001         wait $PID
19002 }
19003 run_test 241b "dio vs dio"
19004
19005 test_242() {
19006         remote_mds_nodsh && skip "remote MDS with nodsh"
19007
19008         mkdir -p $DIR/$tdir
19009         touch $DIR/$tdir/$tfile
19010
19011         #define OBD_FAIL_MDS_READPAGE_PACK      0x105
19012         do_facet mds1 lctl set_param fail_loc=0x105
19013         /bin/ls $DIR/$tdir && error "ls $DIR/$tdir should fail"
19014
19015         do_facet mds1 lctl set_param fail_loc=0
19016         /bin/ls $DIR/$tdir || error "ls $DIR/$tdir failed"
19017 }
19018 run_test 242 "mdt_readpage failure should not cause directory unreadable"
19019
19020 test_243()
19021 {
19022         test_mkdir $DIR/$tdir
19023         group_lock_test -d $DIR/$tdir || error "A group lock test failed"
19024 }
19025 run_test 243 "various group lock tests"
19026
19027 test_244a()
19028 {
19029         test_mkdir $DIR/$tdir
19030         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=35
19031         sendfile_grouplock $DIR/$tdir/$tfile || \
19032                 error "sendfile+grouplock failed"
19033         rm -rf $DIR/$tdir
19034 }
19035 run_test 244a "sendfile with group lock tests"
19036
19037 test_244b()
19038 {
19039         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
19040
19041         local threads=50
19042         local size=$((1024*1024))
19043
19044         test_mkdir $DIR/$tdir
19045         for i in $(seq 1 $threads); do
19046                 local file=$DIR/$tdir/file_$((i / 10))
19047                 $MULTIOP $file OG1234w$size_$((i % 3))w$size_$((i % 4))g1234c &
19048                 local pids[$i]=$!
19049         done
19050         for i in $(seq 1 $threads); do
19051                 wait ${pids[$i]}
19052         done
19053 }
19054 run_test 244b "multi-threaded write with group lock"
19055
19056 test_245() {
19057         local flagname="multi_mod_rpcs"
19058         local connect_data_name="max_mod_rpcs"
19059         local out
19060
19061         # check if multiple modify RPCs flag is set
19062         out=$($LCTL get_param mdc.$FSNAME-MDT0000-*.import |
19063                 grep "connect_flags:")
19064         echo "$out"
19065
19066         echo "$out" | grep -qw $flagname
19067         if [ $? -ne 0 ]; then
19068                 echo "connect flag $flagname is not set"
19069                 return
19070         fi
19071
19072         # check if multiple modify RPCs data is set
19073         out=$($LCTL get_param mdc.$FSNAME-MDT0000-*.import)
19074         echo "$out"
19075
19076         echo "$out" | grep -qw $connect_data_name ||
19077                 error "import should have connect data $connect_data_name"
19078 }
19079 run_test 245 "check mdc connection flag/data: multiple modify RPCs"
19080
19081 cleanup_247() {
19082         local submount=$1
19083
19084         trap 0
19085         umount_client $submount
19086         rmdir $submount
19087 }
19088
19089 test_247a() {
19090         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
19091                 grep -q subtree ||
19092                 skip_env "Fileset feature is not supported"
19093
19094         local submount=${MOUNT}_$tdir
19095
19096         mkdir $MOUNT/$tdir
19097         mkdir -p $submount || error "mkdir $submount failed"
19098         FILESET="$FILESET/$tdir" mount_client $submount ||
19099                 error "mount $submount failed"
19100         trap "cleanup_247 $submount" EXIT
19101         echo foo > $submount/$tfile || error "write $submount/$tfile failed"
19102         [ $(cat $MOUNT/$tdir/$tfile) = "foo" ] ||
19103                 error "read $MOUNT/$tdir/$tfile failed"
19104         cleanup_247 $submount
19105 }
19106 run_test 247a "mount subdir as fileset"
19107
19108 test_247b() {
19109         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
19110                 skip_env "Fileset feature is not supported"
19111
19112         local submount=${MOUNT}_$tdir
19113
19114         rm -rf $MOUNT/$tdir
19115         mkdir -p $submount || error "mkdir $submount failed"
19116         SKIP_FILESET=1
19117         FILESET="$FILESET/$tdir" mount_client $submount &&
19118                 error "mount $submount should fail"
19119         rmdir $submount
19120 }
19121 run_test 247b "mount subdir that dose not exist"
19122
19123 test_247c() {
19124         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
19125                 skip_env "Fileset feature is not supported"
19126
19127         local submount=${MOUNT}_$tdir
19128
19129         mkdir -p $MOUNT/$tdir/dir1
19130         mkdir -p $submount || error "mkdir $submount failed"
19131         trap "cleanup_247 $submount" EXIT
19132         FILESET="$FILESET/$tdir" mount_client $submount ||
19133                 error "mount $submount failed"
19134         local fid=$($LFS path2fid $MOUNT/)
19135         $LFS fid2path $submount $fid && error "fid2path should fail"
19136         cleanup_247 $submount
19137 }
19138 run_test 247c "running fid2path outside subdirectory root"
19139
19140 test_247d() {
19141         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
19142                 skip "Fileset feature is not supported"
19143
19144         local submount=${MOUNT}_$tdir
19145
19146         mkdir -p $MOUNT/$tdir/dir1
19147         mkdir -p $submount || error "mkdir $submount failed"
19148         FILESET="$FILESET/$tdir" mount_client $submount ||
19149                 error "mount $submount failed"
19150         trap "cleanup_247 $submount" EXIT
19151
19152         local td=$submount/dir1
19153         local fid=$($LFS path2fid $td)
19154         [ -z "$fid" ] && error "path2fid unable to get $td FID"
19155
19156         # check that we get the same pathname back
19157         local rootpath
19158         local found
19159         for rootpath in "$submount" "$submount///" "$submount/dir1"; do
19160                 echo "$rootpath $fid"
19161                 found=$($LFS fid2path $rootpath "$fid")
19162                 [ -n "found" ] || error "fid2path should succeed"
19163                 [ "$found" == "$td" ] || error "fid2path $found != $td"
19164         done
19165         # check wrong root path format
19166         rootpath=$submount"_wrong"
19167         found=$($LFS fid2path $rootpath "$fid")
19168         [ -z "$found" ] || error "fid2path should fail ($rootpath != $submount)"
19169
19170         cleanup_247 $submount
19171 }
19172 run_test 247d "running fid2path inside subdirectory root"
19173
19174 # LU-8037
19175 test_247e() {
19176         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
19177                 grep -q subtree ||
19178                 skip "Fileset feature is not supported"
19179
19180         local submount=${MOUNT}_$tdir
19181
19182         mkdir $MOUNT/$tdir
19183         mkdir -p $submount || error "mkdir $submount failed"
19184         FILESET="$FILESET/.." mount_client $submount &&
19185                 error "mount $submount should fail"
19186         rmdir $submount
19187 }
19188 run_test 247e "mount .. as fileset"
19189
19190 test_247f() {
19191         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19192         [ $MDS1_VERSION -lt $(version_code 2.13.52) ] &&
19193                 skip "Need at least version 2.13.52"
19194         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
19195                 grep -q subtree ||
19196                 skip "Fileset feature is not supported"
19197
19198         mkdir $DIR/$tdir || error "mkdir $tdir failed"
19199         $LFS mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir/remote ||
19200                 error "mkdir remote failed"
19201         mkdir $DIR/$tdir/remote/subdir || error "mkdir remote/subdir failed"
19202         $LFS mkdir -c $MDSCOUNT $DIR/$tdir/striped ||
19203                 error "mkdir striped failed"
19204         mkdir $DIR/$tdir/striped/subdir || error "mkdir striped/subdir failed"
19205
19206         local submount=${MOUNT}_$tdir
19207
19208         mkdir -p $submount || error "mkdir $submount failed"
19209
19210         local dir
19211         local fileset=$FILESET
19212
19213         for dir in $tdir/remote $tdir/remote/subdir \
19214                    $tdir/striped $tdir/striped/subdir $tdir/striped/. ; do
19215                 FILESET="$fileset/$dir" mount_client $submount ||
19216                         error "mount $dir failed"
19217                 umount_client $submount
19218         done
19219 }
19220 run_test 247f "mount striped or remote directory as fileset"
19221
19222 test_248a() {
19223         local fast_read_sav=$($LCTL get_param -n llite.*.fast_read 2>/dev/null)
19224         [ -z "$fast_read_sav" ] && skip "no fast read support"
19225
19226         # create a large file for fast read verification
19227         dd if=/dev/zero of=$DIR/$tfile bs=1M count=128 > /dev/null 2>&1
19228
19229         # make sure the file is created correctly
19230         $CHECKSTAT -s $((128*1024*1024)) $DIR/$tfile ||
19231                 { rm -f $DIR/$tfile; skip "file creation error"; }
19232
19233         echo "Test 1: verify that fast read is 4 times faster on cache read"
19234
19235         # small read with fast read enabled
19236         $LCTL set_param -n llite.*.fast_read=1
19237         local t_fast=$(dd if=$DIR/$tfile of=/dev/null bs=4k 2>&1 |
19238                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
19239                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
19240         # small read with fast read disabled
19241         $LCTL set_param -n llite.*.fast_read=0
19242         local t_slow=$(dd if=$DIR/$tfile of=/dev/null bs=4k 2>&1 |
19243                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
19244                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
19245
19246         # verify that fast read is 4 times faster for cache read
19247         [ $(bc <<< "4 * $t_fast < $t_slow") -eq 1 ] ||
19248                 error_not_in_vm "fast read was not 4 times faster: " \
19249                            "$t_fast vs $t_slow"
19250
19251         echo "Test 2: verify the performance between big and small read"
19252         $LCTL set_param -n llite.*.fast_read=1
19253
19254         # 1k non-cache read
19255         cancel_lru_locks osc
19256         local t_1k=$(dd if=$DIR/$tfile of=/dev/null bs=1k 2>&1 |
19257                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
19258                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
19259
19260         # 1M non-cache read
19261         cancel_lru_locks osc
19262         local t_1m=$(dd if=$DIR/$tfile of=/dev/null bs=1k 2>&1 |
19263                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
19264                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
19265
19266         # verify that big IO is not 4 times faster than small IO
19267         [ $(bc <<< "4 * $t_1k >= $t_1m") -eq 1 ] ||
19268                 error_not_in_vm "bigger IO is way too fast: $t_1k vs $t_1m"
19269
19270         $LCTL set_param -n llite.*.fast_read=$fast_read_sav
19271         rm -f $DIR/$tfile
19272 }
19273 run_test 248a "fast read verification"
19274
19275 test_248b() {
19276         # Default short_io_bytes=16384, try both smaller and larger sizes.
19277         # Lustre O_DIRECT read and write needs to be a multiple of PAGE_SIZE.
19278         # 6017024 = 2^12*13*113 = 47008*128 = 11752*512 = 4096*1469 = 53248*113
19279         echo "bs=53248 count=113 normal buffered write"
19280         dd if=/dev/urandom of=$TMP/$tfile.0 bs=53248 count=113 ||
19281                 error "dd of initial data file failed"
19282         stack_trap "rm -f $DIR/$tfile.[0-3] $TMP/$tfile.[0-3]" EXIT
19283
19284         echo "bs=47008 count=128 oflag=dsync normal write $tfile.0"
19285         dd if=$TMP/$tfile.0 of=$DIR/$tfile.0 bs=47008 count=128 oflag=dsync ||
19286                 error "dd with sync normal writes failed"
19287         cmp $TMP/$tfile.0 $DIR/$tfile.0 || error "compare $DIR/$tfile.0 failed"
19288
19289         echo "bs=11752 count=512 oflag=dsync small write $tfile.1"
19290         dd if=$TMP/$tfile.0 of=$DIR/$tfile.1 bs=11752 count=512 oflag=dsync ||
19291                 error "dd with sync small writes failed"
19292         cmp $TMP/$tfile.0 $DIR/$tfile.1 || error "compare $DIR/$tfile.1 failed"
19293
19294         cancel_lru_locks osc
19295
19296         # calculate the small O_DIRECT size and count for the client PAGE_SIZE
19297         local num=$((13 * 113 / (PAGE_SIZE / 4096)))
19298         echo "bs=$PAGE_SIZE count=$num iflag=direct small read $tfile.1"
19299         dd if=$DIR/$tfile.1 of=$TMP/$tfile.1 bs=$PAGE_SIZE count=$num \
19300                 iflag=direct || error "dd with O_DIRECT small read failed"
19301         # adjust bytes checked to handle larger PAGE_SIZE for ARM/PPC
19302         cmp --bytes=$((PAGE_SIZE * num)) $TMP/$tfile.0 $TMP/$tfile.1 ||
19303                 error "compare $TMP/$tfile.1 failed"
19304
19305         local save=$($LCTL get_param -n osc.*OST000*.short_io_bytes | head -n 1)
19306         stack_trap "$LCTL set_param osc.$FSNAME-*.short_io_bytes=$save" EXIT
19307
19308         # just to see what the maximum tunable value is, and test parsing
19309         echo "test invalid parameter 2MB"
19310         $LCTL set_param osc.$FSNAME-OST0000*.short_io_bytes=2M &&
19311                 error "too-large short_io_bytes allowed"
19312         echo "test maximum parameter 512KB"
19313         # if we can set a larger short_io_bytes, run test regardless of version
19314         if ! $LCTL set_param osc.$FSNAME-OST0000*.short_io_bytes=512K; then
19315                 # older clients may not allow setting it this large, that's OK
19316                 [ $CLIENT_VERSION -ge $(version_code 2.13.50) ] ||
19317                         skip "Need at least client version 2.13.50"
19318                 error "medium short_io_bytes failed"
19319         fi
19320         $LCTL get_param osc.$FSNAME-OST0000*.short_io_bytes
19321         size=$($LCTL get_param -n osc.$FSNAME-OST0000*.short_io_bytes)
19322
19323         echo "test large parameter 64KB"
19324         $LCTL set_param osc.$FSNAME-*.short_io_bytes=65536
19325         $LCTL get_param osc.$FSNAME-OST0000*.short_io_bytes
19326
19327         echo "bs=47008 count=128 oflag=dsync large write $tfile.2"
19328         dd if=$TMP/$tfile.0 of=$DIR/$tfile.2 bs=47008 count=128 oflag=dsync ||
19329                 error "dd with sync large writes failed"
19330         cmp $TMP/$tfile.0 $DIR/$tfile.2 || error "compare $DIR/$tfile.2 failed"
19331
19332         # calculate the large O_DIRECT size and count for the client PAGE_SIZE
19333         local size=$(((4096 * 13 + PAGE_SIZE - 1) / PAGE_SIZE * PAGE_SIZE))
19334         num=$((113 * 4096 / PAGE_SIZE))
19335         echo "bs=$size count=$num oflag=direct large write $tfile.3"
19336         dd if=$TMP/$tfile.0 of=$DIR/$tfile.3 bs=$size count=$num oflag=direct ||
19337                 error "dd with O_DIRECT large writes failed"
19338         cmp --bytes=$((size * num)) $TMP/$tfile.0 $DIR/$tfile.3 ||
19339                 error "compare $DIR/$tfile.3 failed"
19340
19341         cancel_lru_locks osc
19342
19343         echo "bs=$size count=$num iflag=direct large read $tfile.2"
19344         dd if=$DIR/$tfile.2 of=$TMP/$tfile.2 bs=$size count=$num iflag=direct ||
19345                 error "dd with O_DIRECT large read failed"
19346         cmp --bytes=$((size * num)) $TMP/$tfile.0 $TMP/$tfile.2 ||
19347                 error "compare $TMP/$tfile.2 failed"
19348
19349         echo "bs=$size count=$num iflag=direct large read $tfile.3"
19350         dd if=$DIR/$tfile.3 of=$TMP/$tfile.3 bs=$size count=$num iflag=direct ||
19351                 error "dd with O_DIRECT large read failed"
19352         cmp --bytes=$((size * num)) $TMP/$tfile.0 $TMP/$tfile.3 ||
19353                 error "compare $TMP/$tfile.3 failed"
19354 }
19355 run_test 248b "test short_io read and write for both small and large sizes"
19356
19357 test_249() { # LU-7890
19358         [ $MDS1_VERSION -lt $(version_code 2.8.53) ] &&
19359                 skip "Need at least version 2.8.54"
19360
19361         rm -f $DIR/$tfile
19362         $LFS setstripe -c 1 $DIR/$tfile
19363         # Offset 2T == 4k * 512M
19364         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 seek=512M ||
19365                 error "dd to 2T offset failed"
19366 }
19367 run_test 249 "Write above 2T file size"
19368
19369 test_250() {
19370         [ "$(facet_fstype ost$(($($LFS getstripe -i $DIR/$tfile) + 1)))" = "zfs" ] \
19371          && skip "no 16TB file size limit on ZFS"
19372
19373         $LFS setstripe -c 1 $DIR/$tfile
19374         # ldiskfs extent file size limit is (16TB - 4KB - 1) bytes
19375         local size=$((16 * 1024 * 1024 * 1024 * 1024 - 4096 - 1))
19376         $TRUNCATE $DIR/$tfile $size || error "truncate $tfile to $size failed"
19377         dd if=/dev/zero of=$DIR/$tfile bs=10 count=1 oflag=append \
19378                 conv=notrunc,fsync && error "append succeeded"
19379         return 0
19380 }
19381 run_test 250 "Write above 16T limit"
19382
19383 test_251() {
19384         $LFS setstripe -c -1 -S 1048576 $DIR/$tfile
19385
19386         #define OBD_FAIL_LLITE_LOST_LAYOUT 0x1407
19387         #Skip once - writing the first stripe will succeed
19388         $LCTL set_param fail_loc=0xa0001407 fail_val=1
19389         $MULTIOP $DIR/$tfile o:O_RDWR:w2097152c 2>&1 | grep -q "short write" &&
19390                 error "short write happened"
19391
19392         $LCTL set_param fail_loc=0xa0001407 fail_val=1
19393         $MULTIOP $DIR/$tfile or2097152c 2>&1 | grep -q "short read" &&
19394                 error "short read happened"
19395
19396         rm -f $DIR/$tfile
19397 }
19398 run_test 251 "Handling short read and write correctly"
19399
19400 test_252() {
19401         remote_mds_nodsh && skip "remote MDS with nodsh"
19402         remote_ost_nodsh && skip "remote OST with nodsh"
19403         if [ "$ost1_FSTYPE" != ldiskfs ] || [ "$mds1_FSTYPE" != ldiskfs ]; then
19404                 skip_env "ldiskfs only test"
19405         fi
19406
19407         local tgt
19408         local dev
19409         local out
19410         local uuid
19411         local num
19412         local gen
19413
19414         # check lr_reader on OST0000
19415         tgt=ost1
19416         dev=$(facet_device $tgt)
19417         out=$(do_facet $tgt $LR_READER $dev)
19418         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
19419         echo "$out"
19420         uuid=$(echo "$out" | grep -i uuid | awk '{ print $2 }')
19421         [ "$uuid" == "$(ostuuid_from_index 0)" ] ||
19422                 error "Invalid uuid returned by $LR_READER on target $tgt"
19423         echo -e "uuid returned by $LR_READER is '$uuid'\n"
19424
19425         # check lr_reader -c on MDT0000
19426         tgt=mds1
19427         dev=$(facet_device $tgt)
19428         if ! do_facet $tgt $LR_READER -h | grep -q OPTIONS; then
19429                 skip "$LR_READER does not support additional options"
19430         fi
19431         out=$(do_facet $tgt $LR_READER -c $dev)
19432         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
19433         echo "$out"
19434         num=$(echo "$out" | grep -c "mdtlov")
19435         [ "$num" -eq $((MDSCOUNT - 1)) ] ||
19436                 error "Invalid number of mdtlov clients returned by $LR_READER"
19437         echo -e "Number of mdtlov clients returned by $LR_READER is '$num'\n"
19438
19439         # check lr_reader -cr on MDT0000
19440         out=$(do_facet $tgt $LR_READER -cr $dev)
19441         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
19442         echo "$out"
19443         echo "$out" | grep -q "^reply_data:$" ||
19444                 error "$LR_READER should have returned 'reply_data' section"
19445         num=$(echo "$out" | grep -c "client_generation")
19446         echo -e "Number of reply data returned by $LR_READER is '$num'\n"
19447 }
19448 run_test 252 "check lr_reader tool"
19449
19450 test_253() {
19451         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19452         remote_mds_nodsh && skip "remote MDS with nodsh"
19453         remote_mgs_nodsh && skip "remote MGS with nodsh"
19454
19455         local ostidx=0
19456         local rc=0
19457         local ost_name=$(ostname_from_index $ostidx)
19458
19459         # on the mdt's osc
19460         local mdtosc_proc1=$(get_mdtosc_proc_path $SINGLEMDS $ost_name)
19461         do_facet $SINGLEMDS $LCTL get_param -n \
19462                 osp.$mdtosc_proc1.reserved_mb_high ||
19463                 skip  "remote MDS does not support reserved_mb_high"
19464
19465         rm -rf $DIR/$tdir
19466         wait_mds_ost_sync
19467         wait_delete_completed
19468         mkdir $DIR/$tdir
19469
19470         pool_add $TESTNAME || error "Pool creation failed"
19471         pool_add_targets $TESTNAME 0 || error "Pool add targets failed"
19472
19473         $LFS setstripe $DIR/$tdir -i $ostidx -c 1 -p $FSNAME.$TESTNAME ||
19474                 error "Setstripe failed"
19475
19476         dd if=/dev/zero of=$DIR/$tdir/$tfile.0 bs=1M count=10
19477
19478         local wms=$(ost_watermarks_set_enospc $tfile $ostidx |
19479                     grep "watermarks")
19480         stack_trap "ost_watermarks_clear_enospc $tfile $ostidx $wms" EXIT
19481
19482         local oa_status=$(do_facet $SINGLEMDS $LCTL get_param -n \
19483                         osp.$mdtosc_proc1.prealloc_status)
19484         echo "prealloc_status $oa_status"
19485
19486         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=1M count=1 &&
19487                 error "File creation should fail"
19488
19489         #object allocation was stopped, but we still able to append files
19490         dd if=/dev/zero of=$DIR/$tdir/$tfile.0 bs=1M seek=6 count=5 \
19491                 oflag=append || error "Append failed"
19492
19493         rm -f $DIR/$tdir/$tfile.0
19494
19495         # For this test, we want to delete the files we created to go out of
19496         # space but leave the watermark, so we remain nearly out of space
19497         ost_watermarks_enospc_delete_files $tfile $ostidx
19498
19499         wait_delete_completed
19500
19501         sleep_maxage
19502
19503         for i in $(seq 10 12); do
19504                 dd if=/dev/zero of=$DIR/$tdir/$tfile.$i bs=1M count=1 \
19505                         2>/dev/null || error "File creation failed after rm"
19506         done
19507
19508         oa_status=$(do_facet $SINGLEMDS $LCTL get_param -n \
19509                         osp.$mdtosc_proc1.prealloc_status)
19510         echo "prealloc_status $oa_status"
19511
19512         if (( oa_status != 0 )); then
19513                 error "Object allocation still disable after rm"
19514         fi
19515 }
19516 run_test 253 "Check object allocation limit"
19517
19518 test_254() {
19519         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19520         remote_mds_nodsh && skip "remote MDS with nodsh"
19521         do_facet $SINGLEMDS $LCTL get_param -n mdd.$MDT0.changelog_size ||
19522                 skip "MDS does not support changelog_size"
19523
19524         local cl_user
19525         local MDT0=$(facet_svc $SINGLEMDS)
19526
19527         changelog_register || error "changelog_register failed"
19528
19529         changelog_clear 0 || error "changelog_clear failed"
19530
19531         local size1=$(do_facet $SINGLEMDS \
19532                       $LCTL get_param -n mdd.$MDT0.changelog_size)
19533         echo "Changelog size $size1"
19534
19535         rm -rf $DIR/$tdir
19536         $LFS mkdir -i 0 $DIR/$tdir
19537         # change something
19538         mkdir -p $DIR/$tdir/pics/2008/zachy
19539         touch $DIR/$tdir/pics/2008/zachy/timestamp
19540         cp /etc/hosts $DIR/$tdir/pics/2008/zachy/pic1.jpg
19541         mv $DIR/$tdir/pics/2008/zachy $DIR/$tdir/pics/zach
19542         ln $DIR/$tdir/pics/zach/pic1.jpg $DIR/$tdir/pics/2008/portland.jpg
19543         ln -s $DIR/$tdir/pics/2008/portland.jpg $DIR/$tdir/pics/desktop.jpg
19544         rm $DIR/$tdir/pics/desktop.jpg
19545
19546         local size2=$(do_facet $SINGLEMDS \
19547                       $LCTL get_param -n mdd.$MDT0.changelog_size)
19548         echo "Changelog size after work $size2"
19549
19550         (( $size2 > $size1 )) ||
19551                 error "new Changelog size=$size2 less than old size=$size1"
19552 }
19553 run_test 254 "Check changelog size"
19554
19555 ladvise_no_type()
19556 {
19557         local type=$1
19558         local file=$2
19559
19560         lfs ladvise -a invalid $file 2>&1 | grep "Valid types" |
19561                 awk -F: '{print $2}' | grep $type > /dev/null
19562         if [ $? -ne 0 ]; then
19563                 return 0
19564         fi
19565         return 1
19566 }
19567
19568 ladvise_no_ioctl()
19569 {
19570         local file=$1
19571
19572         lfs ladvise -a willread $file > /dev/null 2>&1
19573         if [ $? -eq 0 ]; then
19574                 return 1
19575         fi
19576
19577         lfs ladvise -a willread $file 2>&1 |
19578                 grep "Inappropriate ioctl for device" > /dev/null
19579         if [ $? -eq 0 ]; then
19580                 return 0
19581         fi
19582         return 1
19583 }
19584
19585 percent() {
19586         bc <<<"scale=2; ($1 - $2) * 100 / $2"
19587 }
19588
19589 # run a random read IO workload
19590 # usage: random_read_iops <filename> <filesize> <iosize>
19591 random_read_iops() {
19592         local file=$1
19593         local fsize=$2
19594         local iosize=${3:-4096}
19595
19596         $READS -f $file -s $fsize -b $iosize -n $((fsize / iosize)) -t 60 |
19597                 sed -e '/^$/d' -e 's#.*s, ##' -e 's#MB/s##'
19598 }
19599
19600 drop_file_oss_cache() {
19601         local file="$1"
19602         local nodes="$2"
19603
19604         $LFS ladvise -a dontneed $file 2>/dev/null ||
19605                 do_nodes $nodes "echo 3 > /proc/sys/vm/drop_caches"
19606 }
19607
19608 ladvise_willread_performance()
19609 {
19610         local repeat=10
19611         local average_origin=0
19612         local average_cache=0
19613         local average_ladvise=0
19614
19615         for ((i = 1; i <= $repeat; i++)); do
19616                 echo "Iter $i/$repeat: reading without willread hint"
19617                 cancel_lru_locks osc
19618                 drop_file_oss_cache $DIR/$tfile $(comma_list $(osts_nodes))
19619                 local speed_origin=$(random_read_iops $DIR/$tfile $size)
19620                 echo "Iter $i/$repeat: uncached speed: $speed_origin"
19621                 average_origin=$(bc <<<"$average_origin + $speed_origin")
19622
19623                 cancel_lru_locks osc
19624                 local speed_cache=$(random_read_iops $DIR/$tfile $size)
19625                 echo "Iter $i/$repeat: OSS cache speed: $speed_cache"
19626                 average_cache=$(bc <<<"$average_cache + $speed_cache")
19627
19628                 cancel_lru_locks osc
19629                 drop_file_oss_cache $DIR/$tfile $(comma_list $(osts_nodes))
19630                 $LFS ladvise -a willread $DIR/$tfile || error "ladvise failed"
19631                 local speed_ladvise=$(random_read_iops $DIR/$tfile $size)
19632                 echo "Iter $i/$repeat: ladvise speed: $speed_ladvise"
19633                 average_ladvise=$(bc <<<"$average_ladvise + $speed_ladvise")
19634         done
19635         average_origin=$(bc <<<"scale=2; $average_origin / $repeat")
19636         average_cache=$(bc <<<"scale=2; $average_cache / $repeat")
19637         average_ladvise=$(bc <<<"scale=2; $average_ladvise / $repeat")
19638
19639         speedup_cache=$(percent $average_cache $average_origin)
19640         speedup_ladvise=$(percent $average_ladvise $average_origin)
19641
19642         echo "Average uncached read: $average_origin"
19643         echo "Average speedup with OSS cached read: " \
19644                 "$average_cache = +$speedup_cache%"
19645         echo "Average speedup with ladvise willread: " \
19646                 "$average_ladvise = +$speedup_ladvise%"
19647
19648         local lowest_speedup=20
19649         if [ ${average_cache%.*} -lt $lowest_speedup ]; then
19650                 echo "Speedup with OSS cached read less than $lowest_speedup%," \
19651                         "got $average_cache%. Skipping ladvise willread check."
19652                 return 0
19653         fi
19654
19655         # the test won't work on ZFS until it supports 'ladvise dontneed', but
19656         # it is still good to run until then to exercise 'ladvise willread'
19657         ! $LFS ladvise -a dontneed $DIR/$tfile &&
19658                 [ "$ost1_FSTYPE" = "zfs" ] &&
19659                 echo "osd-zfs does not support dontneed or drop_caches" &&
19660                 return 0
19661
19662         lowest_speedup=$(bc <<<"scale=2; $average_cache / 2")
19663         [[ ${average_ladvise%.*} > $lowest_speedup ]] ||
19664                 error_not_in_vm "Speedup with willread is less than " \
19665                         "$lowest_speedup%, got $average_ladvise%"
19666 }
19667
19668 test_255a() {
19669         [ $OST1_VERSION -lt $(version_code 2.8.54) ] &&
19670                 skip "lustre < 2.8.54 does not support ladvise "
19671         remote_ost_nodsh && skip "remote OST with nodsh"
19672
19673         lfs setstripe -c -1 -i 0 $DIR/$tfile || error "$tfile failed"
19674
19675         ladvise_no_type willread $DIR/$tfile &&
19676                 skip "willread ladvise is not supported"
19677
19678         ladvise_no_ioctl $DIR/$tfile &&
19679                 skip "ladvise ioctl is not supported"
19680
19681         local size_mb=100
19682         local size=$((size_mb * 1048576))
19683         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=$size_mb ||
19684                 error "dd to $DIR/$tfile failed"
19685
19686         lfs ladvise -a willread $DIR/$tfile ||
19687                 error "Ladvise failed with no range argument"
19688
19689         lfs ladvise -a willread -s 0 $DIR/$tfile ||
19690                 error "Ladvise failed with no -l or -e argument"
19691
19692         lfs ladvise -a willread -e 1 $DIR/$tfile ||
19693                 error "Ladvise failed with only -e argument"
19694
19695         lfs ladvise -a willread -l 1 $DIR/$tfile ||
19696                 error "Ladvise failed with only -l argument"
19697
19698         lfs ladvise -a willread -s 2 -e 1 $DIR/$tfile &&
19699                 error "End offset should not be smaller than start offset"
19700
19701         lfs ladvise -a willread -s 2 -e 2 $DIR/$tfile &&
19702                 error "End offset should not be equal to start offset"
19703
19704         lfs ladvise -a willread -s $size -l 1 $DIR/$tfile ||
19705                 error "Ladvise failed with overflowing -s argument"
19706
19707         lfs ladvise -a willread -s 1 -e $((size + 1)) $DIR/$tfile ||
19708                 error "Ladvise failed with overflowing -e argument"
19709
19710         lfs ladvise -a willread -s 1 -l $size $DIR/$tfile ||
19711                 error "Ladvise failed with overflowing -l argument"
19712
19713         lfs ladvise -a willread -l 1 -e 2 $DIR/$tfile &&
19714                 error "Ladvise succeeded with conflicting -l and -e arguments"
19715
19716         echo "Synchronous ladvise should wait"
19717         local delay=4
19718 #define OBD_FAIL_OST_LADVISE_PAUSE       0x237
19719         do_nodes $(comma_list $(osts_nodes)) \
19720                 $LCTL set_param fail_val=$delay fail_loc=0x237
19721
19722         local start_ts=$SECONDS
19723         lfs ladvise -a willread $DIR/$tfile ||
19724                 error "Ladvise failed with no range argument"
19725         local end_ts=$SECONDS
19726         local inteval_ts=$((end_ts - start_ts))
19727
19728         if [ $inteval_ts -lt $(($delay - 1)) ]; then
19729                 error "Synchronous advice didn't wait reply"
19730         fi
19731
19732         echo "Asynchronous ladvise shouldn't wait"
19733         local start_ts=$SECONDS
19734         lfs ladvise -a willread -b $DIR/$tfile ||
19735                 error "Ladvise failed with no range argument"
19736         local end_ts=$SECONDS
19737         local inteval_ts=$((end_ts - start_ts))
19738
19739         if [ $inteval_ts -gt $(($delay / 2)) ]; then
19740                 error "Asynchronous advice blocked"
19741         fi
19742
19743         do_nodes $(comma_list $(osts_nodes)) $LCTL set_param fail_loc=0
19744         ladvise_willread_performance
19745 }
19746 run_test 255a "check 'lfs ladvise -a willread'"
19747
19748 facet_meminfo() {
19749         local facet=$1
19750         local info=$2
19751
19752         do_facet $facet "cat /proc/meminfo | grep ^${info}:" | awk '{print $2}'
19753 }
19754
19755 test_255b() {
19756         [ $OST1_VERSION -lt $(version_code 2.8.54) ] &&
19757                 skip "lustre < 2.8.54 does not support ladvise "
19758         remote_ost_nodsh && skip "remote OST with nodsh"
19759
19760         lfs setstripe -c 1 -i 0 $DIR/$tfile
19761
19762         ladvise_no_type dontneed $DIR/$tfile &&
19763                 skip "dontneed ladvise is not supported"
19764
19765         ladvise_no_ioctl $DIR/$tfile &&
19766                 skip "ladvise ioctl is not supported"
19767
19768         ! $LFS ladvise -a dontneed $DIR/$tfile &&
19769                 [ "$ost1_FSTYPE" = "zfs" ] &&
19770                 skip "zfs-osd does not support 'ladvise dontneed'"
19771
19772         local size_mb=100
19773         local size=$((size_mb * 1048576))
19774         # In order to prevent disturbance of other processes, only check 3/4
19775         # of the memory usage
19776         local kibibytes=$((size_mb * 1024 * 3 / 4))
19777
19778         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=$size_mb ||
19779                 error "dd to $DIR/$tfile failed"
19780
19781         #force write to complete before dropping OST cache & checking memory
19782         sync
19783
19784         local total=$(facet_meminfo ost1 MemTotal)
19785         echo "Total memory: $total KiB"
19786
19787         do_facet ost1 "sync && echo 3 > /proc/sys/vm/drop_caches"
19788         local before_read=$(facet_meminfo ost1 Cached)
19789         echo "Cache used before read: $before_read KiB"
19790
19791         lfs ladvise -a willread $DIR/$tfile ||
19792                 error "Ladvise willread failed"
19793         local after_read=$(facet_meminfo ost1 Cached)
19794         echo "Cache used after read: $after_read KiB"
19795
19796         lfs ladvise -a dontneed $DIR/$tfile ||
19797                 error "Ladvise dontneed again failed"
19798         local no_read=$(facet_meminfo ost1 Cached)
19799         echo "Cache used after dontneed ladvise: $no_read KiB"
19800
19801         if [ $total -lt $((before_read + kibibytes)) ]; then
19802                 echo "Memory is too small, abort checking"
19803                 return 0
19804         fi
19805
19806         if [ $((before_read + kibibytes)) -gt $after_read ]; then
19807                 error "Ladvise willread should use more memory" \
19808                         "than $kibibytes KiB"
19809         fi
19810
19811         if [ $((no_read + kibibytes)) -gt $after_read ]; then
19812                 error "Ladvise dontneed should release more memory" \
19813                         "than $kibibytes KiB"
19814         fi
19815 }
19816 run_test 255b "check 'lfs ladvise -a dontneed'"
19817
19818 test_255c() {
19819         [ $OST1_VERSION -lt $(version_code 2.10.50) ] &&
19820                 skip "lustre < 2.10.50 does not support lockahead"
19821
19822         local count
19823         local new_count
19824         local difference
19825         local i
19826         local rc
19827
19828         test_mkdir -p $DIR/$tdir
19829         $LFS setstripe -i 0 -c 1 $DIR/$tdir
19830
19831         #test 10 returns only success/failure
19832         i=10
19833         lockahead_test -d $DIR/$tdir -t $i -f $tfile
19834         rc=$?
19835         if [ $rc -eq 255 ]; then
19836                 error "Ladvise test${i} failed, ${rc}"
19837         fi
19838
19839         #test 11 counts lock enqueue requests, all others count new locks
19840         i=11
19841         count=$(do_facet ost1 \
19842                 $LCTL get_param -n ost.OSS.ost.stats)
19843         count=$(echo "$count" | grep ldlm_extent_enqueue | awk '{ print $2 }')
19844
19845         lockahead_test -d $DIR/$tdir -t $i -f $tfile
19846         rc=$?
19847         if [ $rc -eq 255 ]; then
19848                 error "Ladvise test${i} failed, ${rc}"
19849         fi
19850
19851         new_count=$(do_facet ost1 \
19852                 $LCTL get_param -n ost.OSS.ost.stats)
19853         new_count=$(echo "$new_count" | grep ldlm_extent_enqueue | \
19854                    awk '{ print $2 }')
19855
19856         difference="$((new_count - count))"
19857         if [ $difference -ne $rc ]; then
19858                 error "Ladvise test${i}, bad enqueue count, returned " \
19859                       "${rc}, actual ${difference}"
19860         fi
19861
19862         for i in $(seq 12 21); do
19863                 # If we do not do this, we run the risk of having too many
19864                 # locks and starting lock cancellation while we are checking
19865                 # lock counts.
19866                 cancel_lru_locks osc
19867
19868                 count=$($LCTL get_param -n \
19869                        ldlm.namespaces.$FSNAME-OST0000*osc-[-0-9a-f]*.lock_unused_count)
19870
19871                 lockahead_test -d $DIR/$tdir -t $i -f $tfile
19872                 rc=$?
19873                 if [ $rc -eq 255 ]; then
19874                         error "Ladvise test ${i} failed, ${rc}"
19875                 fi
19876
19877                 new_count=$($LCTL get_param -n \
19878                        ldlm.namespaces.$FSNAME-OST0000*osc-[-0-9a-f]*.lock_unused_count)
19879                 difference="$((new_count - count))"
19880
19881                 # Test 15 output is divided by 100 to map down to valid return
19882                 if [ $i -eq 15 ]; then
19883                         rc="$((rc * 100))"
19884                 fi
19885
19886                 if [ $difference -ne $rc ]; then
19887                         error "Ladvise test ${i}, bad lock count, returned " \
19888                               "${rc}, actual ${difference}"
19889                 fi
19890         done
19891
19892         #test 22 returns only success/failure
19893         i=22
19894         lockahead_test -d $DIR/$tdir -t $i -f $tfile
19895         rc=$?
19896         if [ $rc -eq 255 ]; then
19897                 error "Ladvise test${i} failed, ${rc}"
19898         fi
19899 }
19900 run_test 255c "suite of ladvise lockahead tests"
19901
19902 test_256() {
19903         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19904         remote_mds_nodsh && skip "remote MDS with nodsh"
19905         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip "ldiskfs only test"
19906         changelog_users $SINGLEMDS | grep "^cl" &&
19907                 skip "active changelog user"
19908
19909         local cl_user
19910         local cat_sl
19911         local mdt_dev
19912
19913         mdt_dev=$(mdsdevname 1)
19914         echo $mdt_dev
19915
19916         changelog_register || error "changelog_register failed"
19917
19918         rm -rf $DIR/$tdir
19919         mkdir -p $DIR/$tdir
19920
19921         changelog_clear 0 || error "changelog_clear failed"
19922
19923         # change something
19924         touch $DIR/$tdir/{1..10}
19925
19926         # stop the MDT
19927         stop $SINGLEMDS || error "Fail to stop MDT"
19928
19929         # remount the MDT
19930
19931         start $SINGLEMDS $mdt_dev $MDS_MOUNT_OPTS || error "Fail to start MDT"
19932
19933         #after mount new plainllog is used
19934         touch $DIR/$tdir/{11..19}
19935         local tmpfile="$(mktemp --tmpdir -u $tfile.XXXXXX)"
19936         stack_trap "rm -f $tmpfile"
19937         cat_sl=$(do_facet $SINGLEMDS "sync; \
19938                  $DEBUGFS -c -R 'dump changelog_catalog $tmpfile' $mdt_dev; \
19939                  llog_reader $tmpfile | grep -c type=1064553b")
19940         do_facet $SINGLEMDS llog_reader $tmpfile
19941
19942         [ $cat_sl != 2 ] && error "Changelog catalog has $cat_sl != 2 slots"
19943
19944         changelog_clear 0 || error "changelog_clear failed"
19945
19946         cat_sl=$(do_facet $SINGLEMDS "sync; \
19947                  $DEBUGFS -c -R 'dump changelog_catalog $tmpfile' $mdt_dev; \
19948                  llog_reader $tmpfile | grep -c type=1064553b")
19949
19950         if (( cat_sl == 2 )); then
19951                 error "Empty plain llog was not deleted from changelog catalog"
19952         elif (( cat_sl != 1 )); then
19953                 error "Active plain llog shouldn't be deleted from catalog"
19954         fi
19955 }
19956 run_test 256 "Check llog delete for empty and not full state"
19957
19958 test_257() {
19959         remote_mds_nodsh && skip "remote MDS with nodsh"
19960         [[ $MDS1_VERSION -lt $(version_code 2.8.55) ]] &&
19961                 skip "Need MDS version at least 2.8.55"
19962
19963         test_mkdir $DIR/$tdir
19964
19965         setfattr -n trusted.name1 -v value1 $DIR/$tdir ||
19966                 error "setfattr -n trusted.name1=value1 $DIR/$tdir failed"
19967         stat $DIR/$tdir
19968
19969 #define OBD_FAIL_MDS_XATTR_REP                  0x161
19970         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
19971         local facet=mds$((mdtidx + 1))
19972         set_nodes_failloc $(facet_active_host $facet) 0x80000161
19973         getfattr -n trusted.name1 $DIR/$tdir 2> /dev/null
19974
19975         stop $facet || error "stop MDS failed"
19976         start $facet $(mdsdevname $((mdtidx + 1))) $MDS_MOUNT_OPTS ||
19977                 error "start MDS fail"
19978         wait_recovery_complete $facet
19979 }
19980 run_test 257 "xattr locks are not lost"
19981
19982 # Verify we take the i_mutex when security requires it
19983 test_258a() {
19984 #define OBD_FAIL_IMUTEX_SEC 0x141c
19985         $LCTL set_param fail_loc=0x141c
19986         touch $DIR/$tfile
19987         chmod u+s $DIR/$tfile
19988         chmod a+rwx $DIR/$tfile
19989         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 oflag=append
19990         RC=$?
19991         if [ $RC -ne 0 ]; then
19992                 error "error, failed to take i_mutex, rc=$?"
19993         fi
19994         rm -f $DIR/$tfile
19995 }
19996 run_test 258a "verify i_mutex security behavior when suid attributes is set"
19997
19998 # Verify we do NOT take the i_mutex in the normal case
19999 test_258b() {
20000 #define OBD_FAIL_IMUTEX_NOSEC 0x141d
20001         $LCTL set_param fail_loc=0x141d
20002         touch $DIR/$tfile
20003         chmod a+rwx $DIR
20004         chmod a+rw $DIR/$tfile
20005         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 oflag=append
20006         RC=$?
20007         if [ $RC -ne 0 ]; then
20008                 error "error, took i_mutex unnecessarily, rc=$?"
20009         fi
20010         rm -f $DIR/$tfile
20011
20012 }
20013 run_test 258b "verify i_mutex security behavior"
20014
20015 test_259() {
20016         local file=$DIR/$tfile
20017         local before
20018         local after
20019
20020         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip "ldiskfs only test"
20021
20022         stack_trap "rm -f $file" EXIT
20023
20024         wait_delete_completed
20025         before=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
20026         echo "before: $before"
20027
20028         $LFS setstripe -i 0 -c 1 $file
20029         dd if=/dev/zero of=$file bs=1M count=10 || error "couldn't write"
20030         sync_all_data
20031         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
20032         echo "after write: $after"
20033
20034 #define OBD_FAIL_OSD_FAIL_AT_TRUNCATE          0x2301
20035         do_facet ost1 $LCTL set_param fail_loc=0x2301
20036         $TRUNCATE $file 0
20037         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
20038         echo "after truncate: $after"
20039
20040         stop ost1
20041         do_facet ost1 $LCTL set_param fail_loc=0
20042         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
20043         sleep 2
20044         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
20045         echo "after restart: $after"
20046         [ $((after - before)) -ge $(fs_log_size ost1) ] &&
20047                 error "missing truncate?"
20048
20049         return 0
20050 }
20051 run_test 259 "crash at delayed truncate"
20052
20053 test_260() {
20054 #define OBD_FAIL_MDC_CLOSE               0x806
20055         $LCTL set_param fail_loc=0x80000806
20056         touch $DIR/$tfile
20057
20058 }
20059 run_test 260 "Check mdc_close fail"
20060
20061 ### Data-on-MDT sanity tests ###
20062 test_270a() {
20063         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
20064                 skip "Need MDS version at least 2.10.55 for DoM"
20065
20066         # create DoM file
20067         local dom=$DIR/$tdir/dom_file
20068         local tmp=$DIR/$tdir/tmp_file
20069
20070         mkdir -p $DIR/$tdir
20071
20072         # basic checks for DoM component creation
20073         $LFS setstripe -E 1024K -E 2048K -L mdt $dom 2>/dev/null &&
20074                 error "Can set MDT layout to non-first entry"
20075
20076         $LFS setstripe -E 1024K -L mdt -E 2048K -L mdt $dom 2>/dev/null &&
20077                 error "Can define multiple entries as MDT layout"
20078
20079         $LFS setstripe -E 1M -L mdt $dom || error "Can't create DoM layout"
20080
20081         [ $($LFS getstripe -L $dom) == "mdt" ] || error "bad pattern"
20082         [ $($LFS getstripe -c $dom) == 0 ] || error "bad stripe count"
20083         [ $($LFS getstripe -S $dom) == 1048576 ] || error "bad stripe size"
20084
20085         local mdtidx=$($LFS getstripe -m $dom)
20086         local mdtname=MDT$(printf %04x $mdtidx)
20087         local facet=mds$((mdtidx + 1))
20088         local space_check=1
20089
20090         # Skip free space checks with ZFS
20091         [ "$(facet_fstype $facet)" == "zfs" ] && space_check=0
20092
20093         # write
20094         sync
20095         local size_tmp=$((65536 * 3))
20096         local mdtfree1=$(do_facet $facet \
20097                          lctl get_param -n osd*.*$mdtname.kbytesfree)
20098
20099         dd if=/dev/urandom of=$tmp bs=1024 count=$((size_tmp / 1024))
20100         # check also direct IO along write
20101         # IO size must be a multiple of PAGE_SIZE on all platforms (ARM=64KB)
20102         dd if=$tmp of=$dom bs=65536 count=$((size_tmp / 65536)) oflag=direct
20103         sync
20104         cmp $tmp $dom || error "file data is different"
20105         [ $(stat -c%s $dom) == $size_tmp ] ||
20106                 error "bad size after write: $(stat -c%s $dom) != $size_tmp"
20107         if [ $space_check == 1 ]; then
20108                 local mdtfree2=$(do_facet $facet \
20109                                  lctl get_param -n osd*.*$mdtname.kbytesfree)
20110
20111                 # increase in usage from by $size_tmp
20112                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_tmp / 1024)) ] ||
20113                         error "MDT free space wrong after write: " \
20114                               "$mdtfree1 >= $mdtfree2 + $size_tmp/1024"
20115         fi
20116
20117         # truncate
20118         local size_dom=10000
20119
20120         $TRUNCATE $dom $size_dom
20121         [ $(stat -c%s $dom) == $size_dom ] ||
20122                 error "bad size after truncate: $(stat -c%s $dom) != $size_dom"
20123         if [ $space_check == 1 ]; then
20124                 mdtfree1=$(do_facet $facet \
20125                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
20126                 # decrease in usage from $size_tmp to new $size_dom
20127                 [ $(($mdtfree1 - $mdtfree2)) -ge \
20128                   $(((size_tmp - size_dom) / 1024)) ] ||
20129                         error "MDT free space is wrong after truncate: " \
20130                               "$mdtfree1 >= $mdtfree2 + ($size_tmp - $size_dom) / 1024"
20131         fi
20132
20133         # append
20134         cat $tmp >> $dom
20135         sync
20136         size_dom=$((size_dom + size_tmp))
20137         [ $(stat -c%s $dom) == $size_dom ] ||
20138                 error "bad size after append: $(stat -c%s $dom) != $size_dom"
20139         if [ $space_check == 1 ]; then
20140                 mdtfree2=$(do_facet $facet \
20141                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
20142                 # increase in usage by $size_tmp from previous
20143                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_tmp / 1024)) ] ||
20144                         error "MDT free space is wrong after append: " \
20145                               "$mdtfree1 >= $mdtfree2 + $size_tmp/1024"
20146         fi
20147
20148         # delete
20149         rm $dom
20150         if [ $space_check == 1 ]; then
20151                 mdtfree1=$(do_facet $facet \
20152                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
20153                 # decrease in usage by $size_dom from previous
20154                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_dom / 1024)) ] ||
20155                         error "MDT free space is wrong after removal: " \
20156                               "$mdtfree1 >= $mdtfree2 + $size_dom/1024"
20157         fi
20158
20159         # combined striping
20160         $LFS setstripe -E 1024K -L mdt -E EOF $dom ||
20161                 error "Can't create DoM + OST striping"
20162
20163         size_tmp=2031616 # must be a multiple of PAGE_SIZE=65536 on ARM
20164         dd if=/dev/urandom of=$tmp bs=1024 count=$((size_tmp / 1024))
20165         # check also direct IO along write
20166         dd if=$tmp of=$dom bs=65536 count=$((size_tmp / 65536)) oflag=direct
20167         sync
20168         cmp $tmp $dom || error "file data is different"
20169         [ $(stat -c%s $dom) == $size_tmp ] ||
20170                 error "bad size after write: $(stat -c%s $dom) != $size_tmp"
20171         rm $dom $tmp
20172
20173         return 0
20174 }
20175 run_test 270a "DoM: basic functionality tests"
20176
20177 test_270b() {
20178         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
20179                 skip "Need MDS version at least 2.10.55"
20180
20181         local dom=$DIR/$tdir/dom_file
20182         local max_size=1048576
20183
20184         mkdir -p $DIR/$tdir
20185         $LFS setstripe -E $max_size -L mdt $dom
20186
20187         # truncate over the limit
20188         $TRUNCATE $dom $(($max_size + 1)) &&
20189                 error "successful truncate over the maximum size"
20190         # write over the limit
20191         dd if=/dev/zero of=$dom bs=$max_size seek=1 count=1 &&
20192                 error "successful write over the maximum size"
20193         # append over the limit
20194         dd if=/dev/zero of=$dom bs=$(($max_size - 3)) count=1
20195         echo "12345" >> $dom && error "successful append over the maximum size"
20196         rm $dom
20197
20198         return 0
20199 }
20200 run_test 270b "DoM: maximum size overflow checks for DoM-only file"
20201
20202 test_270c() {
20203         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
20204                 skip "Need MDS version at least 2.10.55"
20205
20206         mkdir -p $DIR/$tdir
20207         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
20208
20209         # check files inherit DoM EA
20210         touch $DIR/$tdir/first
20211         [ $($LFS getstripe -L $DIR/$tdir/first) == "mdt" ] ||
20212                 error "bad pattern"
20213         [ $($LFS getstripe -c $DIR/$tdir/first) == 0 ] ||
20214                 error "bad stripe count"
20215         [ $($LFS getstripe -S $DIR/$tdir/first) == 1048576 ] ||
20216                 error "bad stripe size"
20217
20218         # check directory inherits DoM EA and uses it as default
20219         mkdir $DIR/$tdir/subdir
20220         touch $DIR/$tdir/subdir/second
20221         [ $($LFS getstripe -L $DIR/$tdir/subdir/second) == "mdt" ] ||
20222                 error "bad pattern in sub-directory"
20223         [ $($LFS getstripe -c $DIR/$tdir/subdir/second) == 0 ] ||
20224                 error "bad stripe count in sub-directory"
20225         [ $($LFS getstripe -S $DIR/$tdir/subdir/second) == 1048576 ] ||
20226                 error "bad stripe size in sub-directory"
20227         return 0
20228 }
20229 run_test 270c "DoM: DoM EA inheritance tests"
20230
20231 test_270d() {
20232         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
20233                 skip "Need MDS version at least 2.10.55"
20234
20235         mkdir -p $DIR/$tdir
20236         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
20237
20238         # inherit default DoM striping
20239         mkdir $DIR/$tdir/subdir
20240         touch $DIR/$tdir/subdir/f1
20241
20242         # change default directory striping
20243         $LFS setstripe -c 1 $DIR/$tdir/subdir
20244         touch $DIR/$tdir/subdir/f2
20245         [ $($LFS getstripe -c $DIR/$tdir/subdir/f2) == 1 ] ||
20246                 error "wrong default striping in file 2"
20247         [ $($LFS getstripe -L $DIR/$tdir/subdir/f2) == "raid0" ] ||
20248                 error "bad pattern in file 2"
20249         return 0
20250 }
20251 run_test 270d "DoM: change striping from DoM to RAID0"
20252
20253 test_270e() {
20254         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
20255                 skip "Need MDS version at least 2.10.55"
20256
20257         mkdir -p $DIR/$tdir/dom
20258         mkdir -p $DIR/$tdir/norm
20259         DOMFILES=20
20260         NORMFILES=10
20261         $LFS setstripe -E 1M -L mdt $DIR/$tdir/dom
20262         $LFS setstripe -i 0 -S 2M $DIR/$tdir/norm
20263
20264         createmany -o $DIR/$tdir/dom/dom- $DOMFILES
20265         createmany -o $DIR/$tdir/norm/norm- $NORMFILES
20266
20267         # find DoM files by layout
20268         NUM=$($LFS find -L mdt -type f $DIR/$tdir 2>/dev/null | wc -l)
20269         [ $NUM -eq  $DOMFILES ] ||
20270                 error "lfs find -L: found $NUM, expected $DOMFILES"
20271         echo "Test 1: lfs find 20 DOM files by layout: OK"
20272
20273         # there should be 1 dir with default DOM striping
20274         NUM=$($LFS find -L mdt -type d $DIR/$tdir 2>/dev/null | wc -l)
20275         [ $NUM -eq  1 ] ||
20276                 error "lfs find -L: found $NUM, expected 1 dir"
20277         echo "Test 2: lfs find 1 DOM dir by layout: OK"
20278
20279         # find DoM files by stripe size
20280         NUM=$($LFS find -S -1200K -type f $DIR/$tdir 2>/dev/null | wc -l)
20281         [ $NUM -eq  $DOMFILES ] ||
20282                 error "lfs find -S: found $NUM, expected $DOMFILES"
20283         echo "Test 4: lfs find 20 DOM files by stripe size: OK"
20284
20285         # find files by stripe offset except DoM files
20286         NUM=$($LFS find -i 0 -type f $DIR/$tdir 2>/dev/null | wc -l)
20287         [ $NUM -eq  $NORMFILES ] ||
20288                 error "lfs find -i: found $NUM, expected $NORMFILES"
20289         echo "Test 5: lfs find no DOM files by stripe index: OK"
20290         return 0
20291 }
20292 run_test 270e "DoM: lfs find with DoM files test"
20293
20294 test_270f() {
20295         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
20296                 skip "Need MDS version at least 2.10.55"
20297
20298         local mdtname=${FSNAME}-MDT0000-mdtlov
20299         local dom=$DIR/$tdir/dom_file
20300         local dom_limit_saved=$(do_facet mds1 $LCTL get_param -n \
20301                                                 lod.$mdtname.dom_stripesize)
20302         local dom_limit=131072
20303
20304         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=$dom_limit
20305         local dom_current=$(do_facet mds1 $LCTL get_param -n \
20306                                                 lod.$mdtname.dom_stripesize)
20307         [ ${dom_limit} -eq ${dom_current} ] ||
20308                 error "Cannot change per-MDT DoM stripe limit to $dom_limit"
20309
20310         $LFS mkdir -i 0 -c 1 $DIR/$tdir
20311         $LFS setstripe -d $DIR/$tdir
20312         $LFS setstripe -E $dom_limit -L mdt $DIR/$tdir ||
20313                 error "Can't set directory default striping"
20314
20315         # exceed maximum stripe size
20316         $LFS setstripe -E $((dom_limit * 2)) -L mdt $dom ||
20317                 error "Can't create file with $((dom_limit * 2)) DoM stripe"
20318         [ $($LFS getstripe -S $dom) -eq $((dom_limit * 2)) ] &&
20319                 error "Able to create DoM component size more than LOD limit"
20320
20321         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=0
20322         dom_current=$(do_facet mds1 $LCTL get_param -n \
20323                                                 lod.$mdtname.dom_stripesize)
20324         [ 0 -eq ${dom_current} ] ||
20325                 error "Can't set zero DoM stripe limit"
20326         rm $dom
20327
20328         # attempt to create DoM file on server with disabled DoM should
20329         # remove DoM entry from layout and be succeed
20330         $LFS setstripe -E $dom_limit -L mdt -E -1 $dom ||
20331                 error "Can't create DoM file (DoM is disabled)"
20332         [ $($LFS getstripe -L $dom) == "mdt" ] &&
20333                 error "File has DoM component while DoM is disabled"
20334         rm $dom
20335
20336         # attempt to create DoM file with only DoM stripe should return error
20337         $LFS setstripe -E $dom_limit -L mdt $dom &&
20338                 error "Able to create DoM-only file while DoM is disabled"
20339
20340         # too low values to be aligned with smallest stripe size 64K
20341         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=30000
20342         dom_current=$(do_facet mds1 $LCTL get_param -n \
20343                                                 lod.$mdtname.dom_stripesize)
20344         [ 30000 -eq ${dom_current} ] &&
20345                 error "Can set too small DoM stripe limit"
20346
20347         # 64K is a minimal stripe size in Lustre, expect limit of that size
20348         [ 65536 -eq ${dom_current} ] ||
20349                 error "Limit is not set to 64K but ${dom_current}"
20350
20351         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=2147483648
20352         dom_current=$(do_facet mds1 $LCTL get_param -n \
20353                                                 lod.$mdtname.dom_stripesize)
20354         echo $dom_current
20355         [ 2147483648 -eq ${dom_current} ] &&
20356                 error "Can set too large DoM stripe limit"
20357
20358         do_facet mds1 $LCTL set_param -n \
20359                                 lod.$mdtname.dom_stripesize=$((dom_limit * 2))
20360         $LFS setstripe -E $((dom_limit * 2)) -L mdt $dom ||
20361                 error "Can't create DoM component size after limit change"
20362         do_facet mds1 $LCTL set_param -n \
20363                                 lod.$mdtname.dom_stripesize=$((dom_limit / 2))
20364         $LFS setstripe -E $dom_limit -L mdt ${dom}_big ||
20365                 error "Can't create DoM file after limit decrease"
20366         [ $($LFS getstripe -S ${dom}_big) -eq $((dom_limit / 2)) ] ||
20367                 error "Can create big DoM component after limit decrease"
20368         touch ${dom}_def ||
20369                 error "Can't create file with old default layout"
20370
20371         do_facet mds1 $LCTL set_param -n lod.*.dom_stripesize=$dom_limit_saved
20372         return 0
20373 }
20374 run_test 270f "DoM: maximum DoM stripe size checks"
20375
20376 test_270g() {
20377         [ $MDS1_VERSION -ge $(version_code 2.13.52) ] ||
20378                 skip "Need MDS version at least 2.13.52"
20379         local dom=$DIR/$tdir/$tfile
20380
20381         $LFS mkdir -i 0 -c 1 $DIR/$tdir
20382         local lodname=${FSNAME}-MDT0000-mdtlov
20383
20384         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
20385         save_lustre_params mds1 "lod.${lodname}.dom_stripesize_max_kb" > $save
20386         save_lustre_params mds1 "lod.${lodname}.dom_threshold_free_mb" >> $save
20387         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
20388
20389         local dom_limit=1024
20390         local dom_threshold="50%"
20391
20392         $LFS setstripe -d $DIR/$tdir
20393         $LFS setstripe -E ${dom_limit}K -L mdt $DIR/$tdir ||
20394                 error "Can't set directory default striping"
20395
20396         do_facet mds1 $LCTL set_param -n \
20397                                 lod.${lodname}.dom_stripesize_max_kb=$dom_limit
20398         # set 0 threshold and create DOM file to change tunable stripesize
20399         do_facet mds1 $LCTL set_param -n lod.${lodname}.dom_threshold_free_mb=0
20400         $LFS setstripe -E ${dom_limit}K -L mdt -E -1 $dom ||
20401                 error "Failed to create $dom file"
20402         # now tunable dom_cur_stripesize should reach maximum
20403         local dom_current=$(do_facet mds1 $LCTL get_param -n \
20404                                         lod.${lodname}.dom_stripesize_cur_kb)
20405         [[ $dom_current == $dom_limit ]] ||
20406                 error "Current DOM stripesize is not maximum"
20407         rm $dom
20408
20409         # set threshold for further tests
20410         do_facet mds1 $LCTL set_param -n \
20411                         lod.${lodname}.dom_threshold_free_mb=$dom_threshold
20412         echo "DOM threshold is $dom_threshold free space"
20413         local dom_def
20414         local dom_set
20415         # Spoof bfree to exceed threshold
20416         #define OBD_FAIL_MDS_STATFS_SPOOF   0x168
20417         do_facet mds1 $LCTL set_param -n fail_loc=0x0168
20418         for spfree in 40 20 0 15 30 55; do
20419                 do_facet mds1 $LCTL set_param -n fail_val=$spfree
20420                 $LFS setstripe -E ${dom_limit}K -L mdt -E -1 $dom ||
20421                         error "Failed to create $dom file"
20422                 dom_def=$(do_facet mds1 $LCTL get_param -n \
20423                                         lod.${lodname}.dom_stripesize_cur_kb)
20424                 echo "Free space: ${spfree}%, default DOM stripe: ${dom_def}K"
20425                 [[ $dom_def != $dom_current ]] ||
20426                         error "Default stripe size was not changed"
20427                 if [[ $spfree > 0 ]] ; then
20428                         dom_set=$($LFS getstripe -S $dom)
20429                         [[ $dom_set == $((dom_def * 1024)) ]] ||
20430                                 error "DOM component size is still old"
20431                 else
20432                         [[ $($LFS getstripe -L $dom) != "mdt" ]] ||
20433                                 error "DoM component is set with no free space"
20434                 fi
20435                 rm $dom
20436                 dom_current=$dom_def
20437         done
20438 }
20439 run_test 270g "DoM: default DoM stripe size depends on free space"
20440
20441 test_270h() {
20442         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
20443                 skip "Need MDS version at least 2.13.53"
20444
20445         local mdtname=${FSNAME}-MDT0000-mdtlov
20446         local dom=$DIR/$tdir/$tfile
20447         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
20448
20449         save_lustre_params mds1 "lod.*.dom_stripesize" > $save
20450         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
20451
20452         $LFS mkdir -i 0 -c 1 $DIR/$tdir
20453         $LFS setstripe -E 1M -c1  -E -1 -c2 ${dom}_1 ||
20454                 error "can't create OST file"
20455         # mirrored file with DOM entry in the second mirror
20456         $LFS mirror extend -N -E 1M -L mdt -E eof -c2 ${dom}_1 ||
20457                 error "can't create mirror with DoM component"
20458
20459         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=0
20460
20461         # DOM component in the middle and has other enries in the same mirror,
20462         # should succeed but lost DoM component
20463         $LFS setstripe --copy=${dom}_1 $dom ||
20464                 error "Can't create file from OST|DOM mirror layout"
20465         # check new file has no DoM layout after all
20466         [[ $($LFS getstripe -L $dom) != "mdt" ]] ||
20467                 error "File has DoM component while DoM is disabled"
20468 }
20469 run_test 270h "DoM: DoM stripe removal when disabled on server"
20470
20471 test_271a() {
20472         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
20473                 skip "Need MDS version at least 2.10.55"
20474
20475         local dom=$DIR/$tdir/dom
20476
20477         mkdir -p $DIR/$tdir
20478
20479         $LFS setstripe -E 1024K -L mdt $dom
20480
20481         lctl set_param -n mdc.*.stats=clear
20482         dd if=/dev/zero of=$dom bs=4096 count=1 || return 1
20483         cat $dom > /dev/null
20484         local reads=$(lctl get_param -n mdc.*.stats | grep -c ost_read)
20485         [ $reads -eq 0 ] || error "Unexpected $reads READ RPCs"
20486         ls $dom
20487         rm -f $dom
20488 }
20489 run_test 271a "DoM: data is cached for read after write"
20490
20491 test_271b() {
20492         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
20493                 skip "Need MDS version at least 2.10.55"
20494
20495         local dom=$DIR/$tdir/dom
20496
20497         mkdir -p $DIR/$tdir
20498
20499         $LFS setstripe -E 1024K -L mdt -E EOF $dom
20500
20501         lctl set_param -n mdc.*.stats=clear
20502         dd if=/dev/zero of=$dom bs=4096 count=1 || return 1
20503         cancel_lru_locks mdc
20504         $CHECKSTAT -t file -s 4096 $dom || error "stat #1 fails"
20505         # second stat to check size is cached on client
20506         $CHECKSTAT -t file -s 4096 $dom || error "stat #2 fails"
20507         local gls=$(lctl get_param -n mdc.*.stats | grep -c ldlm_glimpse)
20508         [ $gls -eq 0 ] || error "Unexpected $gls glimpse RPCs"
20509         rm -f $dom
20510 }
20511 run_test 271b "DoM: no glimpse RPC for stat (DoM only file)"
20512
20513 test_271ba() {
20514         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
20515                 skip "Need MDS version at least 2.10.55"
20516
20517         local dom=$DIR/$tdir/dom
20518
20519         mkdir -p $DIR/$tdir
20520
20521         $LFS setstripe -E 1024K -L mdt -E EOF $dom
20522
20523         lctl set_param -n mdc.*.stats=clear
20524         lctl set_param -n osc.*.stats=clear
20525         dd if=/dev/zero of=$dom bs=2048K count=1 || return 1
20526         cancel_lru_locks mdc
20527         $CHECKSTAT -t file -s 2097152 $dom || error "stat"
20528         # second stat to check size is cached on client
20529         $CHECKSTAT -t file -s 2097152 $dom || error "stat"
20530         local gls=$(lctl get_param -n mdc.*.stats | grep -c ldlm_glimpse)
20531         [ $gls == 0 ] || error "Unexpected $gls glimpse RPCs"
20532         local gls=$(lctl get_param -n osc.*.stats | grep -c ldlm_glimpse)
20533         [ $gls == 0 ] || error "Unexpected $gls OSC glimpse RPCs"
20534         rm -f $dom
20535 }
20536 run_test 271ba "DoM: no glimpse RPC for stat (combined file)"
20537
20538
20539 get_mdc_stats() {
20540         local mdtidx=$1
20541         local param=$2
20542         local mdt=MDT$(printf %04x $mdtidx)
20543
20544         if [ -z $param ]; then
20545                 lctl get_param -n mdc.*$mdt*.stats
20546         else
20547                 lctl get_param -n mdc.*$mdt*.stats | awk "/$param/"'{print $2}'
20548         fi
20549 }
20550
20551 test_271c() {
20552         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
20553                 skip "Need MDS version at least 2.10.55"
20554
20555         local dom=$DIR/$tdir/dom
20556
20557         mkdir -p $DIR/$tdir
20558
20559         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
20560
20561         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
20562         local facet=mds$((mdtidx + 1))
20563
20564         cancel_lru_locks mdc
20565         do_facet $facet lctl set_param -n mdt.*.dom_lock=0
20566         createmany -o $dom 1000
20567         lctl set_param -n mdc.*.stats=clear
20568         smalliomany -w $dom 1000 200
20569         get_mdc_stats $mdtidx
20570         local enq=$(get_mdc_stats $mdtidx ldlm_ibits_enqueue)
20571         # Each file has 1 open, 1 IO enqueues, total 2000
20572         # but now we have also +1 getxattr for security.capability, total 3000
20573         [ $enq -ge 2000 ] || error "Too few enqueues $enq, expected > 2000"
20574         unlinkmany $dom 1000
20575
20576         cancel_lru_locks mdc
20577         do_facet $facet lctl set_param -n mdt.*.dom_lock=1
20578         createmany -o $dom 1000
20579         lctl set_param -n mdc.*.stats=clear
20580         smalliomany -w $dom 1000 200
20581         local enq_2=$(get_mdc_stats $mdtidx ldlm_ibits_enqueue)
20582         # Expect to see reduced amount of RPCs by 1000 due to single enqueue
20583         # for OPEN and IO lock.
20584         [ $((enq - enq_2)) -ge 1000 ] ||
20585                 error "Too many enqueues $enq_2, expected about $((enq - 1000))"
20586         unlinkmany $dom 1000
20587         return 0
20588 }
20589 run_test 271c "DoM: IO lock at open saves enqueue RPCs"
20590
20591 cleanup_271def_tests() {
20592         trap 0
20593         rm -f $1
20594 }
20595
20596 test_271d() {
20597         [ $MDS1_VERSION -lt $(version_code 2.10.57) ] &&
20598                 skip "Need MDS version at least 2.10.57"
20599
20600         local dom=$DIR/$tdir/dom
20601         local tmp=$TMP/$tfile
20602         trap "cleanup_271def_tests $tmp" EXIT
20603
20604         mkdir -p $DIR/$tdir
20605
20606         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
20607
20608         local mdtidx=$($LFS getstripe --mdt-index $DIR/$tdir)
20609
20610         cancel_lru_locks mdc
20611         dd if=/dev/urandom of=$tmp bs=1000 count=1
20612         dd if=$tmp of=$dom bs=1000 count=1
20613         cancel_lru_locks mdc
20614
20615         cat /etc/hosts >> $tmp
20616         lctl set_param -n mdc.*.stats=clear
20617
20618         # append data to the same file it should update local page
20619         echo "Append to the same page"
20620         cat /etc/hosts >> $dom
20621         local num=$(get_mdc_stats $mdtidx ost_read)
20622         local ra=$(get_mdc_stats $mdtidx req_active)
20623         local rw=$(get_mdc_stats $mdtidx req_waittime)
20624
20625         [ -z $num ] || error "$num READ RPC occured"
20626         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
20627         echo "... DONE"
20628
20629         # compare content
20630         cmp $tmp $dom || error "file miscompare"
20631
20632         cancel_lru_locks mdc
20633         lctl set_param -n mdc.*.stats=clear
20634
20635         echo "Open and read file"
20636         cat $dom > /dev/null
20637         local num=$(get_mdc_stats $mdtidx ost_read)
20638         local ra=$(get_mdc_stats $mdtidx req_active)
20639         local rw=$(get_mdc_stats $mdtidx req_waittime)
20640
20641         [ -z $num ] || error "$num READ RPC occured"
20642         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
20643         echo "... DONE"
20644
20645         # compare content
20646         cmp $tmp $dom || error "file miscompare"
20647
20648         return 0
20649 }
20650 run_test 271d "DoM: read on open (1K file in reply buffer)"
20651
20652 test_271f() {
20653         [ $MDS1_VERSION -lt $(version_code 2.10.57) ] &&
20654                 skip "Need MDS version at least 2.10.57"
20655
20656         local dom=$DIR/$tdir/dom
20657         local tmp=$TMP/$tfile
20658         trap "cleanup_271def_tests $tmp" EXIT
20659
20660         mkdir -p $DIR/$tdir
20661
20662         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
20663
20664         local mdtidx=$($LFS getstripe --mdt-index $DIR/$tdir)
20665
20666         cancel_lru_locks mdc
20667         dd if=/dev/urandom of=$tmp bs=265000 count=1
20668         dd if=$tmp of=$dom bs=265000 count=1
20669         cancel_lru_locks mdc
20670         cat /etc/hosts >> $tmp
20671         lctl set_param -n mdc.*.stats=clear
20672
20673         echo "Append to the same page"
20674         cat /etc/hosts >> $dom
20675         local num=$(get_mdc_stats $mdtidx ost_read)
20676         local ra=$(get_mdc_stats $mdtidx req_active)
20677         local rw=$(get_mdc_stats $mdtidx req_waittime)
20678
20679         [ -z $num ] || error "$num READ RPC occured"
20680         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
20681         echo "... DONE"
20682
20683         # compare content
20684         cmp $tmp $dom || error "file miscompare"
20685
20686         cancel_lru_locks mdc
20687         lctl set_param -n mdc.*.stats=clear
20688
20689         echo "Open and read file"
20690         cat $dom > /dev/null
20691         local num=$(get_mdc_stats $mdtidx ost_read)
20692         local ra=$(get_mdc_stats $mdtidx req_active)
20693         local rw=$(get_mdc_stats $mdtidx req_waittime)
20694
20695         [ -z $num ] && num=0
20696         [ $num -eq 1 ] || error "expect 1 READ RPC, $num occured"
20697         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
20698         echo "... DONE"
20699
20700         # compare content
20701         cmp $tmp $dom || error "file miscompare"
20702
20703         return 0
20704 }
20705 run_test 271f "DoM: read on open (200K file and read tail)"
20706
20707 test_271g() {
20708         [[ $($LCTL get_param mdc.*.import) =~ async_discard ]] ||
20709                 skip "Skipping due to old client or server version"
20710
20711         $LFS setstripe -E 1024K -L mdt -E EOF $DIR1/$tfile
20712         # to get layout
20713         $CHECKSTAT -t file $DIR1/$tfile
20714
20715         $MULTIOP $DIR1/$tfile Ow40960_w4096c &
20716         MULTIOP_PID=$!
20717         sleep 1
20718         #define OBD_FAIL_LDLM_CANCEL_BL_CB_RACE
20719         $LCTL set_param fail_loc=0x80000314
20720         rm $DIR1/$tfile || error "Unlink fails"
20721         RC=$?
20722         kill -USR1 $MULTIOP_PID && wait $MULTIOP_PID || error "multiop failure"
20723         [ $RC -eq 0 ] || error "Failed write to stale object"
20724 }
20725 run_test 271g "Discard DoM data vs client flush race"
20726
20727 test_272a() {
20728         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
20729                 skip "Need MDS version at least 2.11.50"
20730
20731         local dom=$DIR/$tdir/dom
20732         mkdir -p $DIR/$tdir
20733
20734         $LFS setstripe -E 256K -L mdt -E -1 -c1 $dom
20735         dd if=/dev/urandom of=$dom bs=512K count=1 ||
20736                 error "failed to write data into $dom"
20737         local old_md5=$(md5sum $dom)
20738
20739         $LFS migrate -E 256K -L mdt -E -1 -c2 $dom ||
20740                 error "failed to migrate to the same DoM component"
20741
20742         local new_md5=$(md5sum $dom)
20743
20744         [ "$old_md5" == "$new_md5" ] ||
20745                 error "md5sum differ: $old_md5, $new_md5"
20746
20747         [ $($LFS getstripe -c $dom) -eq 2 ] ||
20748                 error "bad final stripe count: $($LFS getstripe -c $dom) != 2"
20749 }
20750 run_test 272a "DoM migration: new layout with the same DOM component"
20751
20752 test_272b() {
20753         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
20754                 skip "Need MDS version at least 2.11.50"
20755
20756         local dom=$DIR/$tdir/dom
20757         mkdir -p $DIR/$tdir
20758         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
20759
20760         local mdtidx=$($LFS getstripe -m $dom)
20761         local mdtname=MDT$(printf %04x $mdtidx)
20762         local facet=mds$((mdtidx + 1))
20763
20764         local mdtfree1=$(do_facet $facet \
20765                 lctl get_param -n osd*.*$mdtname.kbytesfree)
20766         dd if=/dev/urandom of=$dom bs=2M count=1 ||
20767                 error "failed to write data into $dom"
20768         local old_md5=$(md5sum $dom)
20769         cancel_lru_locks mdc
20770         local mdtfree1=$(do_facet $facet \
20771                 lctl get_param -n osd*.*$mdtname.kbytesfree)
20772
20773         $LFS migrate -c2 $dom ||
20774                 error "failed to migrate to the new composite layout"
20775         [ $($LFS getstripe -L $dom) != 'mdt' ] ||
20776                 error "MDT stripe was not removed"
20777
20778         cancel_lru_locks mdc
20779         local new_md5=$(md5sum $dom)
20780         [ "$old_md5" == "$new_md5" ] ||
20781                 error "$old_md5 != $new_md5"
20782
20783         # Skip free space checks with ZFS
20784         if [ "$(facet_fstype $facet)" != "zfs" ]; then
20785                 local mdtfree2=$(do_facet $facet \
20786                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
20787                 [ $mdtfree2 -gt $mdtfree1 ] ||
20788                         error "MDT space is not freed after migration"
20789         fi
20790         return 0
20791 }
20792 run_test 272b "DoM migration: DOM file to the OST-striped file (plain)"
20793
20794 test_272c() {
20795         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
20796                 skip "Need MDS version at least 2.11.50"
20797
20798         local dom=$DIR/$tdir/$tfile
20799         mkdir -p $DIR/$tdir
20800         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
20801
20802         local mdtidx=$($LFS getstripe -m $dom)
20803         local mdtname=MDT$(printf %04x $mdtidx)
20804         local facet=mds$((mdtidx + 1))
20805
20806         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
20807                 error "failed to write data into $dom"
20808         local old_md5=$(md5sum $dom)
20809         cancel_lru_locks mdc
20810         local mdtfree1=$(do_facet $facet \
20811                 lctl get_param -n osd*.*$mdtname.kbytesfree)
20812
20813         $LFS migrate -E 2M -c1 -E -1 -c2 $dom ||
20814                 error "failed to migrate to the new composite layout"
20815         [ $($LFS getstripe -L $dom) == 'mdt' ] &&
20816                 error "MDT stripe was not removed"
20817
20818         cancel_lru_locks mdc
20819         local new_md5=$(md5sum $dom)
20820         [ "$old_md5" == "$new_md5" ] ||
20821                 error "$old_md5 != $new_md5"
20822
20823         # Skip free space checks with ZFS
20824         if [ "$(facet_fstype $facet)" != "zfs" ]; then
20825                 local mdtfree2=$(do_facet $facet \
20826                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
20827                 [ $mdtfree2 -gt $mdtfree1 ] ||
20828                         error "MDS space is not freed after migration"
20829         fi
20830         return 0
20831 }
20832 run_test 272c "DoM migration: DOM file to the OST-striped file (composite)"
20833
20834 test_272d() {
20835         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
20836                 skip "Need MDS version at least 2.12.55"
20837
20838         local dom=$DIR/$tdir/$tfile
20839         mkdir -p $DIR/$tdir
20840         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
20841
20842         local mdtidx=$($LFS getstripe -m $dom)
20843         local mdtname=MDT$(printf %04x $mdtidx)
20844         local facet=mds$((mdtidx + 1))
20845
20846         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
20847                 error "failed to write data into $dom"
20848         local old_md5=$(md5sum $dom)
20849         cancel_lru_locks mdc
20850         local mdtfree1=$(do_facet $facet \
20851                 lctl get_param -n osd*.*$mdtname.kbytesfree)
20852
20853         $LFS mirror extend -N -E 2M -c1 -E -1 -c2 $dom ||
20854                 error "failed mirroring to the new composite layout"
20855         $LFS mirror resync $dom ||
20856                 error "failed mirror resync"
20857         $LFS mirror split --mirror-id 1 -d $dom ||
20858                 error "failed mirror split"
20859
20860         [ $($LFS getstripe -L $dom) != 'mdt' ] ||
20861                 error "MDT stripe was not removed"
20862
20863         cancel_lru_locks mdc
20864         local new_md5=$(md5sum $dom)
20865         [ "$old_md5" == "$new_md5" ] ||
20866                 error "$old_md5 != $new_md5"
20867
20868         # Skip free space checks with ZFS
20869         if [ "$(facet_fstype $facet)" != "zfs" ]; then
20870                 local mdtfree2=$(do_facet $facet \
20871                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
20872                 [ $mdtfree2 -gt $mdtfree1 ] ||
20873                         error "MDS space is not freed after DOM mirror deletion"
20874         fi
20875         return 0
20876 }
20877 run_test 272d "DoM mirroring: OST-striped mirror to DOM file"
20878
20879 test_272e() {
20880         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
20881                 skip "Need MDS version at least 2.12.55"
20882
20883         local dom=$DIR/$tdir/$tfile
20884         mkdir -p $DIR/$tdir
20885         $LFS setstripe -c 2 $dom
20886
20887         dd if=/dev/urandom of=$dom bs=512K count=1 oflag=direct ||
20888                 error "failed to write data into $dom"
20889         local old_md5=$(md5sum $dom)
20890         cancel_lru_locks mdc
20891
20892         $LFS mirror extend -N -E 1M -L mdt -E eof -c2 $dom ||
20893                 error "failed mirroring to the DOM layout"
20894         $LFS mirror resync $dom ||
20895                 error "failed mirror resync"
20896         $LFS mirror split --mirror-id 1 -d $dom ||
20897                 error "failed mirror split"
20898
20899         [ $($LFS getstripe -L $dom) != 'mdt' ] ||
20900                 error "MDT stripe was not removed"
20901
20902         cancel_lru_locks mdc
20903         local new_md5=$(md5sum $dom)
20904         [ "$old_md5" == "$new_md5" ] ||
20905                 error "$old_md5 != $new_md5"
20906
20907         return 0
20908 }
20909 run_test 272e "DoM mirroring: DOM mirror to the OST-striped file"
20910
20911 test_272f() {
20912         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
20913                 skip "Need MDS version at least 2.12.55"
20914
20915         local dom=$DIR/$tdir/$tfile
20916         mkdir -p $DIR/$tdir
20917         $LFS setstripe -c 2 $dom
20918
20919         dd if=/dev/urandom of=$dom bs=512K count=1 oflag=direct ||
20920                 error "failed to write data into $dom"
20921         local old_md5=$(md5sum $dom)
20922         cancel_lru_locks mdc
20923
20924         $LFS migrate -E 1M -L mdt -E eof -c2 -v $dom ||
20925                 error "failed migrating to the DOM file"
20926
20927         cancel_lru_locks mdc
20928         local new_md5=$(md5sum $dom)
20929         [ "$old_md5" != "$new_md5" ] &&
20930                 error "$old_md5 != $new_md5"
20931
20932         return 0
20933 }
20934 run_test 272f "DoM migration: OST-striped file to DOM file"
20935
20936 test_273a() {
20937         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
20938                 skip "Need MDS version at least 2.11.50"
20939
20940         # Layout swap cannot be done if either file has DOM component,
20941         # this will never be supported, migration should be used instead
20942
20943         local dom=$DIR/$tdir/$tfile
20944         mkdir -p $DIR/$tdir
20945
20946         $LFS setstripe -c2 ${dom}_plain
20947         $LFS setstripe -E 1M -L mdt -E -1 -c2 ${dom}_dom
20948         $LFS swap_layouts ${dom}_plain ${dom}_dom &&
20949                 error "can swap layout with DoM component"
20950         $LFS swap_layouts ${dom}_dom ${dom}_plain &&
20951                 error "can swap layout with DoM component"
20952
20953         $LFS setstripe -E 1M -c1 -E -1 -c2 ${dom}_comp
20954         $LFS swap_layouts ${dom}_comp ${dom}_dom &&
20955                 error "can swap layout with DoM component"
20956         $LFS swap_layouts ${dom}_dom ${dom}_comp &&
20957                 error "can swap layout with DoM component"
20958         return 0
20959 }
20960 run_test 273a "DoM: layout swapping should fail with DOM"
20961
20962 test_275() {
20963         remote_ost_nodsh && skip "remote OST with nodsh"
20964         [ $OST1_VERSION -lt $(version_code 2.10.57) ] &&
20965                 skip "Need OST version >= 2.10.57"
20966
20967         local file=$DIR/$tfile
20968         local oss
20969
20970         oss=$(comma_list $(osts_nodes))
20971
20972         dd if=/dev/urandom of=$file bs=1M count=2 ||
20973                 error "failed to create a file"
20974         cancel_lru_locks osc
20975
20976         #lock 1
20977         dd if=$file of=/dev/null bs=1M count=1 iflag=direct ||
20978                 error "failed to read a file"
20979
20980 #define OBD_FAIL_LDLM_PAUSE_CANCEL2      0x31f
20981         $LCTL set_param fail_loc=0x8000031f
20982
20983         cancel_lru_locks osc &
20984         sleep 1
20985
20986 #define OBD_FAIL_LDLM_PROLONG_PAUSE      0x32b
20987         do_nodes $oss $LCTL set_param fail_loc=0x8000032b
20988         #IO takes another lock, but matches the PENDING one
20989         #and places it to the IO RPC
20990         dd if=$file of=/dev/null bs=1M count=1 iflag=direct ||
20991                 error "failed to read a file with PENDING lock"
20992 }
20993 run_test 275 "Read on a canceled duplicate lock"
20994
20995 test_276() {
20996         remote_ost_nodsh && skip "remote OST with nodsh"
20997         local pid
20998
20999         do_facet ost1 "(while true; do \
21000                 $LCTL get_param obdfilter.*.filesfree > /dev/null 2>&1; \
21001                 done) & pid=\\\$!; echo \\\$pid > $TMP/sanity_276_pid" &
21002         pid=$!
21003
21004         for LOOP in $(seq 20); do
21005                 stop ost1
21006                 start ost1 $(ostdevname 1) $OST_MOUNT_OPTS
21007         done
21008         kill -9 $pid
21009         do_facet ost1 "pid=\\\$(cat $TMP/sanity_276_pid); kill -9 \\\$pid; \
21010                 rm $TMP/sanity_276_pid"
21011 }
21012 run_test 276 "Race between mount and obd_statfs"
21013
21014 test_277() {
21015         $LCTL set_param ldlm.namespaces.*.lru_size=0
21016         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
21017         local cached_mb=$($LCTL get_param llite.*.max_cached_mb |
21018                         grep ^used_mb | awk '{print $2}')
21019         [ $cached_mb -eq 1 ] || error "expected mb 1 got $cached_mb"
21020         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 \
21021                 oflag=direct conv=notrunc
21022         cached_mb=$($LCTL get_param llite.*.max_cached_mb |
21023                         grep ^used_mb | awk '{print $2}')
21024         [ $cached_mb -eq 0 ] || error "expected mb 0 got $cached_mb"
21025 }
21026 run_test 277 "Direct IO shall drop page cache"
21027
21028 test_278() {
21029         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
21030         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
21031         [[ "$(facet_host mds1)" != "$(facet_host mds2)" ]] &&
21032                 skip "needs the same host for mdt1 mdt2" && return
21033
21034         local pid1
21035         local pid2
21036
21037 #define OBD_FAIL_OBD_STOP_MDS_RACE     0x60b
21038         do_facet mds2 $LCTL set_param fail_loc=0x8000060c
21039         stop mds2 &
21040         pid2=$!
21041
21042         stop mds1
21043
21044         echo "Starting MDTs"
21045         start mds1 $(mdsdevname 1) $MDS_MOUNT_OPTS
21046         wait $pid2
21047 #For the error assertion will happen. lu_env_get_key(..., &mdt_thread_key)
21048 #will return NULL
21049         do_facet mds2 $LCTL set_param fail_loc=0
21050
21051         start mds2 $(mdsdevname 2) $MDS_MOUNT_OPTS
21052         wait_recovery_complete mds2
21053 }
21054 run_test 278 "Race starting MDS between MDTs stop/start"
21055
21056 test_280() {
21057         [ $MGS_VERSION -lt $(version_code 2.13.52) ] &&
21058                 skip "Need MGS version at least 2.13.52"
21059         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21060         combined_mgs_mds || skip "needs combined MGS/MDT"
21061
21062         umount_client $MOUNT
21063 #define OBD_FAIL_MDS_LLOG_UMOUNT_RACE   0x15e
21064         do_facet mgs $LCTL set_param fail_loc=0x8000015e fail_val=0
21065
21066         mount_client $MOUNT &
21067         sleep 1
21068         stop mgs || error "stop mgs failed"
21069         #for a race mgs would crash
21070         start mgs $(mgsdevname) $MGS_MOUNT_OPTS || error "start mgs failed"
21071         mount_client $MOUNT || error "mount client failed"
21072 }
21073 run_test 280 "Race between MGS umount and client llog processing"
21074
21075 cleanup_test_300() {
21076         trap 0
21077         umask $SAVE_UMASK
21078 }
21079 test_striped_dir() {
21080         local mdt_index=$1
21081         local stripe_count
21082         local stripe_index
21083
21084         mkdir -p $DIR/$tdir
21085
21086         SAVE_UMASK=$(umask)
21087         trap cleanup_test_300 RETURN EXIT
21088
21089         $LFS setdirstripe -i $mdt_index -c 2 -H all_char -o 755 \
21090                                                 $DIR/$tdir/striped_dir ||
21091                 error "set striped dir error"
21092
21093         local mode=$(stat -c%a $DIR/$tdir/striped_dir)
21094         [ "$mode" = "755" ] || error "expect 755 got $mode"
21095
21096         $LFS getdirstripe $DIR/$tdir/striped_dir > /dev/null 2>&1 ||
21097                 error "getdirstripe failed"
21098         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir)
21099         if [ "$stripe_count" != "2" ]; then
21100                 error "1:stripe_count is $stripe_count, expect 2"
21101         fi
21102         stripe_count=$($LFS getdirstripe -T $DIR/$tdir/striped_dir)
21103         if [ "$stripe_count" != "2" ]; then
21104                 error "2:stripe_count is $stripe_count, expect 2"
21105         fi
21106
21107         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir)
21108         if [ "$stripe_index" != "$mdt_index" ]; then
21109                 error "stripe_index is $stripe_index, expect $mdt_index"
21110         fi
21111
21112         [ $(stat -c%h $DIR/$tdir/striped_dir) == '2' ] ||
21113                 error "nlink error after create striped dir"
21114
21115         mkdir $DIR/$tdir/striped_dir/a
21116         mkdir $DIR/$tdir/striped_dir/b
21117
21118         stat $DIR/$tdir/striped_dir/a ||
21119                 error "create dir under striped dir failed"
21120         stat $DIR/$tdir/striped_dir/b ||
21121                 error "create dir under striped dir failed"
21122
21123         [ $(stat -c%h $DIR/$tdir/striped_dir) == '4' ] ||
21124                 error "nlink error after mkdir"
21125
21126         rmdir $DIR/$tdir/striped_dir/a
21127         [ $(stat -c%h $DIR/$tdir/striped_dir) == '3' ] ||
21128                 error "nlink error after rmdir"
21129
21130         rmdir $DIR/$tdir/striped_dir/b
21131         [ $(stat -c%h $DIR/$tdir/striped_dir) == '2' ] ||
21132                 error "nlink error after rmdir"
21133
21134         chattr +i $DIR/$tdir/striped_dir
21135         createmany -o $DIR/$tdir/striped_dir/f 10 &&
21136                 error "immutable flags not working under striped dir!"
21137         chattr -i $DIR/$tdir/striped_dir
21138
21139         rmdir $DIR/$tdir/striped_dir ||
21140                 error "rmdir striped dir error"
21141
21142         cleanup_test_300
21143
21144         true
21145 }
21146
21147 test_300a() {
21148         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
21149                 skip "skipped for lustre < 2.7.0"
21150         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21151         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21152
21153         test_striped_dir 0 || error "failed on striped dir on MDT0"
21154         test_striped_dir 1 || error "failed on striped dir on MDT0"
21155 }
21156 run_test 300a "basic striped dir sanity test"
21157
21158 test_300b() {
21159         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
21160                 skip "skipped for lustre < 2.7.0"
21161         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21162         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21163
21164         local i
21165         local mtime1
21166         local mtime2
21167         local mtime3
21168
21169         test_mkdir $DIR/$tdir || error "mkdir fail"
21170         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
21171                 error "set striped dir error"
21172         for i in {0..9}; do
21173                 mtime1=$(stat -c %Y $DIR/$tdir/striped_dir)
21174                 sleep 1
21175                 touch $DIR/$tdir/striped_dir/file_$i || error "touch error $i"
21176                 mtime2=$(stat -c %Y $DIR/$tdir/striped_dir)
21177                 [ $mtime1 -eq $mtime2 ] && error "mtime unchanged after create"
21178                 sleep 1
21179                 rm -f $DIR/$tdir/striped_dir/file_$i || error "unlink error $i"
21180                 mtime3=$(stat -c %Y $DIR/$tdir/striped_dir)
21181                 [ $mtime2 -eq $mtime3 ] && error "mtime unchanged after unlink"
21182         done
21183         true
21184 }
21185 run_test 300b "check ctime/mtime for striped dir"
21186
21187 test_300c() {
21188         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
21189                 skip "skipped for lustre < 2.7.0"
21190         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21191         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21192
21193         local file_count
21194
21195         mkdir -p $DIR/$tdir
21196         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir ||
21197                 error "set striped dir error"
21198
21199         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/striped_dir ||
21200                 error "chown striped dir failed"
21201
21202         $RUNAS createmany -o $DIR/$tdir/striped_dir/f 5000 ||
21203                 error "create 5k files failed"
21204
21205         file_count=$(ls $DIR/$tdir/striped_dir | wc -l)
21206
21207         [ "$file_count" = 5000 ] || error "file count $file_count != 5000"
21208
21209         rm -rf $DIR/$tdir
21210 }
21211 run_test 300c "chown && check ls under striped directory"
21212
21213 test_300d() {
21214         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
21215                 skip "skipped for lustre < 2.7.0"
21216         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21217         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21218
21219         local stripe_count
21220         local file
21221
21222         mkdir -p $DIR/$tdir
21223         $LFS setstripe -c 2 $DIR/$tdir
21224
21225         #local striped directory
21226         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
21227                 error "set striped dir error"
21228         #look at the directories for debug purposes
21229         ls -l $DIR/$tdir
21230         $LFS getdirstripe $DIR/$tdir
21231         ls -l $DIR/$tdir/striped_dir
21232         $LFS getdirstripe $DIR/$tdir/striped_dir
21233         createmany -o $DIR/$tdir/striped_dir/f 10 ||
21234                 error "create 10 files failed"
21235
21236         #remote striped directory
21237         $LFS setdirstripe -i 1 -c 2 $DIR/$tdir/remote_striped_dir ||
21238                 error "set striped dir error"
21239         #look at the directories for debug purposes
21240         ls -l $DIR/$tdir
21241         $LFS getdirstripe $DIR/$tdir
21242         ls -l $DIR/$tdir/remote_striped_dir
21243         $LFS getdirstripe $DIR/$tdir/remote_striped_dir
21244         createmany -o $DIR/$tdir/remote_striped_dir/f 10 ||
21245                 error "create 10 files failed"
21246
21247         for file in $(find $DIR/$tdir); do
21248                 stripe_count=$($LFS getstripe -c $file)
21249                 [ $stripe_count -eq 2 ] ||
21250                         error "wrong stripe $stripe_count for $file"
21251         done
21252
21253         rm -rf $DIR/$tdir
21254 }
21255 run_test 300d "check default stripe under striped directory"
21256
21257 test_300e() {
21258         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
21259                 skip "Need MDS version at least 2.7.55"
21260         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21261         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21262
21263         local stripe_count
21264         local file
21265
21266         mkdir -p $DIR/$tdir
21267
21268         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
21269                 error "set striped dir error"
21270
21271         touch $DIR/$tdir/striped_dir/a
21272         touch $DIR/$tdir/striped_dir/b
21273         touch $DIR/$tdir/striped_dir/c
21274
21275         mkdir $DIR/$tdir/striped_dir/dir_a
21276         mkdir $DIR/$tdir/striped_dir/dir_b
21277         mkdir $DIR/$tdir/striped_dir/dir_c
21278
21279         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_a ||
21280                 error "set striped adir under striped dir error"
21281
21282         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_b ||
21283                 error "set striped bdir under striped dir error"
21284
21285         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_c ||
21286                 error "set striped cdir under striped dir error"
21287
21288         mrename $DIR/$tdir/striped_dir/dir_a $DIR/$tdir/striped_dir/dir_b ||
21289                 error "rename dir under striped dir fails"
21290
21291         mrename $DIR/$tdir/striped_dir/stp_a $DIR/$tdir/striped_dir/stp_b ||
21292                 error "rename dir under different stripes fails"
21293
21294         mrename $DIR/$tdir/striped_dir/a $DIR/$tdir/striped_dir/c ||
21295                 error "rename file under striped dir should succeed"
21296
21297         mrename $DIR/$tdir/striped_dir/dir_b $DIR/$tdir/striped_dir/dir_c ||
21298                 error "rename dir under striped dir should succeed"
21299
21300         rm -rf $DIR/$tdir
21301 }
21302 run_test 300e "check rename under striped directory"
21303
21304 test_300f() {
21305         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21306         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21307         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
21308                 skip "Need MDS version at least 2.7.55"
21309
21310         local stripe_count
21311         local file
21312
21313         rm -rf $DIR/$tdir
21314         mkdir -p $DIR/$tdir
21315
21316         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
21317                 error "set striped dir error"
21318
21319         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir1 ||
21320                 error "set striped dir error"
21321
21322         touch $DIR/$tdir/striped_dir/a
21323         mkdir $DIR/$tdir/striped_dir/dir_a
21324         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir/stp_a ||
21325                 error "create striped dir under striped dir fails"
21326
21327         touch $DIR/$tdir/striped_dir1/b
21328         mkdir $DIR/$tdir/striped_dir1/dir_b
21329         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir/stp_b ||
21330                 error "create striped dir under striped dir fails"
21331
21332         mrename $DIR/$tdir/striped_dir/dir_a $DIR/$tdir/striped_dir1/dir_b ||
21333                 error "rename dir under different striped dir should fail"
21334
21335         mrename $DIR/$tdir/striped_dir/stp_a $DIR/$tdir/striped_dir1/stp_b ||
21336                 error "rename striped dir under diff striped dir should fail"
21337
21338         mrename $DIR/$tdir/striped_dir/a $DIR/$tdir/striped_dir1/a ||
21339                 error "rename file under diff striped dirs fails"
21340
21341         rm -rf $DIR/$tdir
21342 }
21343 run_test 300f "check rename cross striped directory"
21344
21345 test_300_check_default_striped_dir()
21346 {
21347         local dirname=$1
21348         local default_count=$2
21349         local default_index=$3
21350         local stripe_count
21351         local stripe_index
21352         local dir_stripe_index
21353         local dir
21354
21355         echo "checking $dirname $default_count $default_index"
21356         $LFS setdirstripe -D -c $default_count -i $default_index \
21357                                 -t all_char $DIR/$tdir/$dirname ||
21358                 error "set default stripe on striped dir error"
21359         stripe_count=$($LFS getdirstripe -D -c $DIR/$tdir/$dirname)
21360         [ $stripe_count -eq $default_count ] ||
21361                 error "expect $default_count get $stripe_count for $dirname"
21362
21363         stripe_index=$($LFS getdirstripe -D -i $DIR/$tdir/$dirname)
21364         [ $stripe_index -eq $default_index ] ||
21365                 error "expect $default_index get $stripe_index for $dirname"
21366
21367         mkdir $DIR/$tdir/$dirname/{test1,test2,test3,test4} ||
21368                                                 error "create dirs failed"
21369
21370         createmany -o $DIR/$tdir/$dirname/f- 10 || error "create files failed"
21371         unlinkmany $DIR/$tdir/$dirname/f- 10    || error "unlink files failed"
21372         for dir in $(find $DIR/$tdir/$dirname/*); do
21373                 stripe_count=$($LFS getdirstripe -c $dir)
21374                 [ $stripe_count -eq $default_count ] ||
21375                 [ $stripe_count -eq 0 ] || [ $default_count -eq 1 ] ||
21376                 error "stripe count $default_count != $stripe_count for $dir"
21377
21378                 stripe_index=$($LFS getdirstripe -i $dir)
21379                 [ $default_index -eq -1 ] ||
21380                         [ $stripe_index -eq $default_index ] ||
21381                         error "$stripe_index != $default_index for $dir"
21382
21383                 #check default stripe
21384                 stripe_count=$($LFS getdirstripe -D -c $dir)
21385                 [ $stripe_count -eq $default_count ] ||
21386                 error "default count $default_count != $stripe_count for $dir"
21387
21388                 stripe_index=$($LFS getdirstripe -D -i $dir)
21389                 [ $stripe_index -eq $default_index ] ||
21390                 error "default index $default_index != $stripe_index for $dir"
21391         done
21392         rmdir $DIR/$tdir/$dirname/* || error "rmdir failed"
21393 }
21394
21395 test_300g() {
21396         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21397         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
21398                 skip "Need MDS version at least 2.7.55"
21399
21400         local dir
21401         local stripe_count
21402         local stripe_index
21403
21404         mkdir $DIR/$tdir
21405         mkdir $DIR/$tdir/normal_dir
21406
21407         #Checking when client cache stripe index
21408         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
21409         $LFS setdirstripe -D -i1 $DIR/$tdir/striped_dir ||
21410                 error "create striped_dir failed"
21411
21412         $LFS setdirstripe -i0 $DIR/$tdir/striped_dir/dir0 ||
21413                 error "create dir0 fails"
21414         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/dir0)
21415         [ $stripe_index -eq 0 ] ||
21416                 error "dir0 expect index 0 got $stripe_index"
21417
21418         mkdir $DIR/$tdir/striped_dir/dir1 ||
21419                 error "create dir1 fails"
21420         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/dir1)
21421         [ $stripe_index -eq 1 ] ||
21422                 error "dir1 expect index 1 got $stripe_index"
21423
21424         #check default stripe count/stripe index
21425         test_300_check_default_striped_dir normal_dir $MDSCOUNT 1
21426         test_300_check_default_striped_dir normal_dir 1 0
21427         test_300_check_default_striped_dir normal_dir 2 1
21428         test_300_check_default_striped_dir normal_dir 2 -1
21429
21430         #delete default stripe information
21431         echo "delete default stripeEA"
21432         $LFS setdirstripe -d $DIR/$tdir/normal_dir ||
21433                 error "set default stripe on striped dir error"
21434
21435         mkdir -p $DIR/$tdir/normal_dir/{test1,test2,test3,test4}
21436         for dir in $(find $DIR/$tdir/normal_dir/*); do
21437                 stripe_count=$($LFS getdirstripe -c $dir)
21438                 [ $stripe_count -eq 0 ] ||
21439                         error "expect 1 get $stripe_count for $dir"
21440                 stripe_index=$($LFS getdirstripe -i $dir)
21441                 [ $stripe_index -eq 0 ] ||
21442                         error "expect 0 get $stripe_index for $dir"
21443         done
21444 }
21445 run_test 300g "check default striped directory for normal directory"
21446
21447 test_300h() {
21448         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21449         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
21450                 skip "Need MDS version at least 2.7.55"
21451
21452         local dir
21453         local stripe_count
21454
21455         mkdir $DIR/$tdir
21456         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
21457                 error "set striped dir error"
21458
21459         test_300_check_default_striped_dir striped_dir $MDSCOUNT 1
21460         test_300_check_default_striped_dir striped_dir 1 0
21461         test_300_check_default_striped_dir striped_dir 2 1
21462         test_300_check_default_striped_dir striped_dir 2 -1
21463
21464         #delete default stripe information
21465         $LFS setdirstripe -d $DIR/$tdir/striped_dir ||
21466                 error "set default stripe on striped dir error"
21467
21468         mkdir -p $DIR/$tdir/striped_dir/{test1,test2,test3,test4}
21469         for dir in $(find $DIR/$tdir/striped_dir/*); do
21470                 stripe_count=$($LFS getdirstripe -c $dir)
21471                 [ $stripe_count -eq 0 ] ||
21472                         error "expect 1 get $stripe_count for $dir"
21473         done
21474 }
21475 run_test 300h "check default striped directory for striped directory"
21476
21477 test_300i() {
21478         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21479         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21480         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
21481                 skip "Need MDS version at least 2.7.55"
21482
21483         local stripe_count
21484         local file
21485
21486         mkdir $DIR/$tdir
21487
21488         $LFS setdirstripe -i 0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
21489                 error "set striped dir error"
21490
21491         createmany -o $DIR/$tdir/striped_dir/f- 10 ||
21492                 error "create files under striped dir failed"
21493
21494         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/hashdir ||
21495                 error "set striped hashdir error"
21496
21497         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/hashdir/d0 ||
21498                 error "create dir0 under hash dir failed"
21499         $LFS setdirstripe -i0 -c$MDSCOUNT -H fnv_1a_64 $DIR/$tdir/hashdir/d1 ||
21500                 error "create dir1 under hash dir failed"
21501
21502         # unfortunately, we need to umount to clear dir layout cache for now
21503         # once we fully implement dir layout, we can drop this
21504         umount_client $MOUNT || error "umount failed"
21505         mount_client $MOUNT || error "mount failed"
21506
21507         $LFS find -H fnv_1a_64 $DIR/$tdir/hashdir
21508         local dircnt=$($LFS find -H fnv_1a_64 $DIR/$tdir/hashdir | wc -l)
21509         [ $dircnt -eq 1 ] || error "lfs find striped dir got:$dircnt,except:1"
21510
21511         #set the stripe to be unknown hash type
21512         #define OBD_FAIL_UNKNOWN_LMV_STRIPE     0x1901
21513         $LCTL set_param fail_loc=0x1901
21514         for ((i = 0; i < 10; i++)); do
21515                 $CHECKSTAT -t file $DIR/$tdir/striped_dir/f-$i ||
21516                         error "stat f-$i failed"
21517                 rm $DIR/$tdir/striped_dir/f-$i || error "unlink f-$i failed"
21518         done
21519
21520         touch $DIR/$tdir/striped_dir/f0 &&
21521                 error "create under striped dir with unknown hash should fail"
21522
21523         $LCTL set_param fail_loc=0
21524
21525         umount_client $MOUNT || error "umount failed"
21526         mount_client $MOUNT || error "mount failed"
21527
21528         return 0
21529 }
21530 run_test 300i "client handle unknown hash type striped directory"
21531
21532 test_300j() {
21533         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21534         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21535         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
21536                 skip "Need MDS version at least 2.7.55"
21537
21538         local stripe_count
21539         local file
21540
21541         mkdir $DIR/$tdir
21542
21543         #define OBD_FAIL_SPLIT_UPDATE_REC       0x1702
21544         $LCTL set_param fail_loc=0x1702
21545         $LFS setdirstripe -i 0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
21546                 error "set striped dir error"
21547
21548         createmany -o $DIR/$tdir/striped_dir/f- 10 ||
21549                 error "create files under striped dir failed"
21550
21551         $LCTL set_param fail_loc=0
21552
21553         rm -rf $DIR/$tdir || error "unlink striped dir fails"
21554
21555         return 0
21556 }
21557 run_test 300j "test large update record"
21558
21559 test_300k() {
21560         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21561         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21562         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
21563                 skip "Need MDS version at least 2.7.55"
21564
21565         # this test needs a huge transaction
21566         local kb
21567         kb=$(do_facet $SINGLEMDS "$LCTL get_param -n \
21568              osd*.$FSNAME-MDT0000.kbytestotal")
21569         [ $kb -lt $((1024*1024)) ] && skip "MDT0 too small: $kb"
21570
21571         local stripe_count
21572         local file
21573
21574         mkdir $DIR/$tdir
21575
21576         #define OBD_FAIL_LARGE_STRIPE   0x1703
21577         $LCTL set_param fail_loc=0x1703
21578         $LFS setdirstripe -i 0 -c192 $DIR/$tdir/striped_dir ||
21579                 error "set striped dir error"
21580         $LCTL set_param fail_loc=0
21581
21582         $LFS getdirstripe $DIR/$tdir/striped_dir ||
21583                 error "getstripeddir fails"
21584         rm -rf $DIR/$tdir/striped_dir ||
21585                 error "unlink striped dir fails"
21586
21587         return 0
21588 }
21589 run_test 300k "test large striped directory"
21590
21591 test_300l() {
21592         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21593         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21594         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
21595                 skip "Need MDS version at least 2.7.55"
21596
21597         local stripe_index
21598
21599         test_mkdir -p $DIR/$tdir/striped_dir
21600         chown $RUNAS_ID $DIR/$tdir/striped_dir ||
21601                         error "chown $RUNAS_ID failed"
21602         $LFS setdirstripe -i 1 -D $DIR/$tdir/striped_dir ||
21603                 error "set default striped dir failed"
21604
21605         #define OBD_FAIL_MDS_STALE_DIR_LAYOUT    0x158
21606         $LCTL set_param fail_loc=0x80000158
21607         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir || error "create dir fails"
21608
21609         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/test_dir)
21610         [ $stripe_index -eq 1 ] ||
21611                 error "expect 1 get $stripe_index for $dir"
21612 }
21613 run_test 300l "non-root user to create dir under striped dir with stale layout"
21614
21615 test_300m() {
21616         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21617         [ $MDSCOUNT -ge 2 ] && skip_env "Only for single MDT"
21618         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
21619                 skip "Need MDS version at least 2.7.55"
21620
21621         mkdir -p $DIR/$tdir/striped_dir
21622         $LFS setdirstripe -D -c 1 $DIR/$tdir/striped_dir ||
21623                 error "set default stripes dir error"
21624
21625         mkdir $DIR/$tdir/striped_dir/a || error "mkdir a fails"
21626
21627         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir/a)
21628         [ $stripe_count -eq 0 ] ||
21629                         error "expect 0 get $stripe_count for a"
21630
21631         $LFS setdirstripe -D -c 2 $DIR/$tdir/striped_dir ||
21632                 error "set default stripes dir error"
21633
21634         mkdir $DIR/$tdir/striped_dir/b || error "mkdir b fails"
21635
21636         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir/b)
21637         [ $stripe_count -eq 0 ] ||
21638                         error "expect 0 get $stripe_count for b"
21639
21640         $LFS setdirstripe -D -c1 -i2 $DIR/$tdir/striped_dir ||
21641                 error "set default stripes dir error"
21642
21643         mkdir $DIR/$tdir/striped_dir/c &&
21644                 error "default stripe_index is invalid, mkdir c should fails"
21645
21646         rm -rf $DIR/$tdir || error "rmdir fails"
21647 }
21648 run_test 300m "setstriped directory on single MDT FS"
21649
21650 cleanup_300n() {
21651         local list=$(comma_list $(mdts_nodes))
21652
21653         trap 0
21654         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
21655 }
21656
21657 test_300n() {
21658         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21659         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21660         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
21661                 skip "Need MDS version at least 2.7.55"
21662         remote_mds_nodsh && skip "remote MDS with nodsh"
21663
21664         local stripe_index
21665         local list=$(comma_list $(mdts_nodes))
21666
21667         trap cleanup_300n RETURN EXIT
21668         mkdir -p $DIR/$tdir
21669         chmod 777 $DIR/$tdir
21670         $RUNAS $LFS setdirstripe -i0 -c$MDSCOUNT \
21671                                 $DIR/$tdir/striped_dir > /dev/null 2>&1 &&
21672                 error "create striped dir succeeds with gid=0"
21673
21674         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=-1
21675         $RUNAS $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir ||
21676                 error "create striped dir fails with gid=-1"
21677
21678         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
21679         $RUNAS $LFS setdirstripe -i 1 -c$MDSCOUNT -D \
21680                                 $DIR/$tdir/striped_dir > /dev/null 2>&1 &&
21681                 error "set default striped dir succeeds with gid=0"
21682
21683
21684         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=-1
21685         $RUNAS $LFS setdirstripe -i 1 -c$MDSCOUNT -D $DIR/$tdir/striped_dir ||
21686                 error "set default striped dir fails with gid=-1"
21687
21688
21689         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
21690         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir ||
21691                                         error "create test_dir fails"
21692         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir1 ||
21693                                         error "create test_dir1 fails"
21694         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir2 ||
21695                                         error "create test_dir2 fails"
21696         cleanup_300n
21697 }
21698 run_test 300n "non-root user to create dir under striped dir with default EA"
21699
21700 test_300o() {
21701         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21702         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21703         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
21704                 skip "Need MDS version at least 2.7.55"
21705
21706         local numfree1
21707         local numfree2
21708
21709         mkdir -p $DIR/$tdir
21710
21711         numfree1=$(lctl get_param -n mdc.*MDT0000*.filesfree)
21712         numfree2=$(lctl get_param -n mdc.*MDT0001*.filesfree)
21713         if [ $numfree1 -lt 66000 ] || [ $numfree2 -lt 66000 ]; then
21714                 skip "not enough free inodes $numfree1 $numfree2"
21715         fi
21716
21717         numfree1=$(lctl get_param -n mdc.*MDT0000-mdc-*.kbytesfree)
21718         numfree2=$(lctl get_param -n mdc.*MDT0001-mdc-*.kbytesfree)
21719         if [ $numfree1 -lt 300000 ] || [ $numfree2 -lt 300000 ]; then
21720                 skip "not enough free space $numfree1 $numfree2"
21721         fi
21722
21723         $LFS setdirstripe -c2 $DIR/$tdir/striped_dir ||
21724                 error "setdirstripe fails"
21725
21726         createmany -d $DIR/$tdir/striped_dir/d 131000 ||
21727                 error "create dirs fails"
21728
21729         $LCTL set_param ldlm.namespaces.*mdc-*.lru_size=0
21730         ls $DIR/$tdir/striped_dir > /dev/null ||
21731                 error "ls striped dir fails"
21732         unlinkmany -d $DIR/$tdir/striped_dir/d 131000 ||
21733                 error "unlink big striped dir fails"
21734 }
21735 run_test 300o "unlink big sub stripe(> 65000 subdirs)"
21736
21737 test_300p() {
21738         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21739         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21740         remote_mds_nodsh && skip "remote MDS with nodsh"
21741
21742         mkdir -p $DIR/$tdir
21743
21744         #define OBD_FAIL_OUT_ENOSPC     0x1704
21745         do_facet mds2 lctl set_param fail_loc=0x80001704
21746         $LFS setdirstripe -i 0 -c2 $DIR/$tdir/bad_striped_dir > /dev/null 2>&1 \
21747                  && error "create striped directory should fail"
21748
21749         [ -e $DIR/$tdir/bad_striped_dir ] && error "striped dir exists"
21750
21751         $LFS setdirstripe -c2 $DIR/$tdir/bad_striped_dir
21752         true
21753 }
21754 run_test 300p "create striped directory without space"
21755
21756 test_300q() {
21757         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21758         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21759
21760         local fd=$(free_fd)
21761         local cmd="exec $fd<$tdir"
21762         cd $DIR
21763         $LFS mkdir -c $MDSCOUNT $tdir || error "create $tdir fails"
21764         eval $cmd
21765         cmd="exec $fd<&-"
21766         trap "eval $cmd" EXIT
21767         cd $tdir || error "cd $tdir fails"
21768         rmdir  ../$tdir || error "rmdir $tdir fails"
21769         mkdir local_dir && error "create dir succeeds"
21770         $LFS setdirstripe -i1 remote_dir && error "create remote dir succeeds"
21771         eval $cmd
21772         return 0
21773 }
21774 run_test 300q "create remote directory under orphan directory"
21775
21776 test_300r() {
21777         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
21778                 skip "Need MDS version at least 2.7.55" && return
21779         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
21780
21781         mkdir $DIR/$tdir
21782
21783         $LFS setdirstripe -i 0 -c -1 $DIR/$tdir/striped_dir ||
21784                 error "set striped dir error"
21785
21786         $LFS getdirstripe $DIR/$tdir/striped_dir ||
21787                 error "getstripeddir fails"
21788
21789         local stripe_count
21790         stripe_count=$($LFS getdirstripe $DIR/$tdir/striped_dir |
21791                       awk '/lmv_stripe_count:/ { print $2 }')
21792
21793         [ $MDSCOUNT -ne $stripe_count ] &&
21794                 error "wrong stripe count $stripe_count expected $MDSCOUNT"
21795
21796         rm -rf $DIR/$tdir/striped_dir ||
21797                 error "unlink striped dir fails"
21798 }
21799 run_test 300r "test -1 striped directory"
21800
21801 test_300s_helper() {
21802         local count=$1
21803
21804         local stripe_dir=$DIR/$tdir/striped_dir.$count
21805
21806         $LFS mkdir -c $count $stripe_dir ||
21807                 error "lfs mkdir -c error"
21808
21809         $LFS getdirstripe $stripe_dir ||
21810                 error "lfs getdirstripe fails"
21811
21812         local stripe_count
21813         stripe_count=$($LFS getdirstripe $stripe_dir |
21814                       awk '/lmv_stripe_count:/ { print $2 }')
21815
21816         [ $count -ne $stripe_count ] &&
21817                 error_noexit "bad stripe count $stripe_count expected $count"
21818
21819         local dupe_stripes
21820         dupe_stripes=$($LFS getdirstripe $stripe_dir |
21821                 awk '/0x/ {count[$1] += 1}; END {
21822                         for (idx in count) {
21823                                 if (count[idx]>1) {
21824                                         print "index " idx " count " count[idx]
21825                                 }
21826                         }
21827                 }')
21828
21829         if [[ -n "$dupe_stripes" ]] ; then
21830                 lfs getdirstripe $stripe_dir
21831                 error_noexit "Dupe MDT above: $dupe_stripes "
21832         fi
21833
21834         rm -rf $stripe_dir ||
21835                 error_noexit "unlink $stripe_dir fails"
21836 }
21837
21838 test_300s() {
21839         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
21840                 skip "Need MDS version at least 2.7.55" && return
21841         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
21842
21843         mkdir $DIR/$tdir
21844         for count in $(seq 2 $MDSCOUNT); do
21845                 test_300s_helper $count
21846         done
21847 }
21848 run_test 300s "test lfs mkdir -c without -i"
21849
21850
21851 prepare_remote_file() {
21852         mkdir $DIR/$tdir/src_dir ||
21853                 error "create remote source failed"
21854
21855         cp /etc/hosts $DIR/$tdir/src_dir/a ||
21856                  error "cp to remote source failed"
21857         touch $DIR/$tdir/src_dir/a
21858
21859         $LFS mkdir -i 1 $DIR/$tdir/tgt_dir ||
21860                 error "create remote target dir failed"
21861
21862         touch $DIR/$tdir/tgt_dir/b
21863
21864         mrename $DIR/$tdir/src_dir/a $DIR/$tdir/tgt_dir/b ||
21865                 error "rename dir cross MDT failed!"
21866
21867         $CHECKSTAT -t file $DIR/$tdir/src_dir/a &&
21868                 error "src_child still exists after rename"
21869
21870         $CHECKSTAT -t file $DIR/$tdir/tgt_dir/b ||
21871                 error "missing file(a) after rename"
21872
21873         diff /etc/hosts $DIR/$tdir/tgt_dir/b ||
21874                 error "diff after rename"
21875 }
21876
21877 test_310a() {
21878         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 4 MDTs"
21879         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21880
21881         local remote_file=$DIR/$tdir/tgt_dir/b
21882
21883         mkdir -p $DIR/$tdir
21884
21885         prepare_remote_file || error "prepare remote file failed"
21886
21887         #open-unlink file
21888         $OPENUNLINK $remote_file $remote_file ||
21889                 error "openunlink $remote_file failed"
21890         $CHECKSTAT -a $remote_file || error "$remote_file exists"
21891 }
21892 run_test 310a "open unlink remote file"
21893
21894 test_310b() {
21895         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 4 MDTs"
21896         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21897
21898         local remote_file=$DIR/$tdir/tgt_dir/b
21899
21900         mkdir -p $DIR/$tdir
21901
21902         prepare_remote_file || error "prepare remote file failed"
21903
21904         ln $remote_file $DIR/$tfile || error "link failed for remote file"
21905         $MULTIOP $DIR/$tfile Ouc || error "mulitop failed"
21906         $CHECKSTAT -t file $remote_file || error "check file failed"
21907 }
21908 run_test 310b "unlink remote file with multiple links while open"
21909
21910 test_310c() {
21911         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21912         [[ $MDSCOUNT -lt 4 ]] && skip_env "needs >= 4 MDTs"
21913
21914         local remote_file=$DIR/$tdir/tgt_dir/b
21915
21916         mkdir -p $DIR/$tdir
21917
21918         prepare_remote_file || error "prepare remote file failed"
21919
21920         ln $remote_file $DIR/$tfile || error "link failed for remote file"
21921         multiop_bg_pause $remote_file O_uc ||
21922                         error "mulitop failed for remote file"
21923         MULTIPID=$!
21924         $MULTIOP $DIR/$tfile Ouc
21925         kill -USR1 $MULTIPID
21926         wait $MULTIPID
21927 }
21928 run_test 310c "open-unlink remote file with multiple links"
21929
21930 #LU-4825
21931 test_311() {
21932         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21933         [ $OSTCOUNT -lt 2 ] && skip "needs >= 2 OSTs"
21934         [ $MDS1_VERSION -lt $(version_code 2.8.54) ] &&
21935                 skip "lustre < 2.8.54 does not contain LU-4825 fix"
21936         remote_mds_nodsh && skip "remote MDS with nodsh"
21937
21938         local old_iused=$($LFS df -i | grep OST0000 | awk '{ print $3 }')
21939         local mdts=$(comma_list $(mdts_nodes))
21940
21941         mkdir -p $DIR/$tdir
21942         $LFS setstripe -i 0 -c 1 $DIR/$tdir
21943         createmany -o $DIR/$tdir/$tfile. 1000
21944
21945         # statfs data is not real time, let's just calculate it
21946         old_iused=$((old_iused + 1000))
21947
21948         local count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
21949                         osp.*OST0000*MDT0000.create_count")
21950         local max_count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
21951                                 osp.*OST0000*MDT0000.max_create_count")
21952         do_nodes $mdts "$LCTL set_param -n osp.*OST0000*.max_create_count=0"
21953
21954         $LFS setstripe -i 0 $DIR/$tdir/$tfile || error "setstripe failed"
21955         local index=$($LFS getstripe -i $DIR/$tdir/$tfile)
21956         [ $index -ne 0 ] || error "$tfile stripe index is 0"
21957
21958         unlinkmany $DIR/$tdir/$tfile. 1000
21959
21960         do_nodes $mdts "$LCTL set_param -n \
21961                         osp.*OST0000*.max_create_count=$max_count"
21962         [ $MDS1_VERSION -lt $(version_code 2.12.51) ] &&
21963                 do_nodes $mdts "$LCTL set_param -n \
21964                                 osp.*OST0000*.create_count=$count"
21965         do_nodes $mdts "$LCTL get_param osp.*OST0000*.create_count" |
21966                         grep "=0" && error "create_count is zero"
21967
21968         local new_iused
21969         for i in $(seq 120); do
21970                 new_iused=$($LFS df -i | grep OST0000 | awk '{ print $3 }')
21971                 # system may be too busy to destroy all objs in time, use
21972                 # a somewhat small value to not fail autotest
21973                 [ $((old_iused - new_iused)) -gt 400 ] && break
21974                 sleep 1
21975         done
21976
21977         echo "waited $i sec, old Iused $old_iused, new Iused $new_iused"
21978         [ $((old_iused - new_iused)) -gt 400 ] ||
21979                 error "objs not destroyed after unlink"
21980 }
21981 run_test 311 "disable OSP precreate, and unlink should destroy objs"
21982
21983 zfs_oid_to_objid()
21984 {
21985         local ost=$1
21986         local objid=$2
21987
21988         local vdevdir=$(dirname $(facet_vdevice $ost))
21989         local cmd="$ZDB -e -p $vdevdir -ddddd $(facet_device $ost)"
21990         local zfs_zapid=$(do_facet $ost $cmd |
21991                           grep -w "/O/0/d$((objid%32))" -C 5 |
21992                           awk '/Object/{getline; print $1}')
21993         local zfs_objid=$(do_facet $ost $cmd $zfs_zapid |
21994                           awk "/$objid = /"'{printf $3}')
21995
21996         echo $zfs_objid
21997 }
21998
21999 zfs_object_blksz() {
22000         local ost=$1
22001         local objid=$2
22002
22003         local vdevdir=$(dirname $(facet_vdevice $ost))
22004         local cmd="$ZDB -e -p $vdevdir -dddd $(facet_device $ost)"
22005         local blksz=$(do_facet $ost $cmd $objid |
22006                       awk '/dblk/{getline; printf $4}')
22007
22008         case "${blksz: -1}" in
22009                 k|K) blksz=$((${blksz:0:$((${#blksz} - 1))}*1024)) ;;
22010                 m|M) blksz=$((${blksz:0:$((${#blksz} - 1))}*1024*1024)) ;;
22011                 *) ;;
22012         esac
22013
22014         echo $blksz
22015 }
22016
22017 test_312() { # LU-4856
22018         remote_ost_nodsh && skip "remote OST with nodsh"
22019         [ "$ost1_FSTYPE" = "zfs" ] ||
22020                 skip_env "the test only applies to zfs"
22021
22022         local max_blksz=$(do_facet ost1 \
22023                           $ZFS get -p recordsize $(facet_device ost1) |
22024                           awk '!/VALUE/{print $3}')
22025
22026         # to make life a little bit easier
22027         $LFS mkdir -c 1 -i 0 $DIR/$tdir
22028         $LFS setstripe -c 1 -i 0 $DIR/$tdir
22029
22030         local tf=$DIR/$tdir/$tfile
22031         touch $tf
22032         local oid=$($LFS getstripe $tf | awk '/obdidx/{getline; print $2}')
22033
22034         # Get ZFS object id
22035         local zfs_objid=$(zfs_oid_to_objid ost1 $oid)
22036         # block size change by sequential overwrite
22037         local bs
22038
22039         for ((bs=$PAGE_SIZE; bs <= max_blksz; bs *= 4)) ; do
22040                 dd if=/dev/zero of=$tf bs=$bs count=1 oflag=sync conv=notrunc
22041
22042                 local blksz=$(zfs_object_blksz ost1 $zfs_objid)
22043                 [ $blksz -eq $bs ] || error "blksz error: $blksz, expected: $bs"
22044         done
22045         rm -f $tf
22046
22047         # block size change by sequential append write
22048         dd if=/dev/zero of=$tf bs=$PAGE_SIZE count=1 oflag=sync conv=notrunc
22049         oid=$($LFS getstripe $tf | awk '/obdidx/{getline; print $2}')
22050         zfs_objid=$(zfs_oid_to_objid ost1 $oid)
22051         local count
22052
22053         for ((count = 1; count < $((max_blksz / PAGE_SIZE)); count *= 2)); do
22054                 dd if=/dev/zero of=$tf bs=$PAGE_SIZE count=$count seek=$count \
22055                         oflag=sync conv=notrunc
22056
22057                 blksz=$(zfs_object_blksz ost1 $zfs_objid)
22058                 [ $blksz -eq $((2 * count * PAGE_SIZE)) ] ||
22059                         error "blksz error, actual $blksz, " \
22060                                 "expected: 2 * $count * $PAGE_SIZE"
22061         done
22062         rm -f $tf
22063
22064         # random write
22065         touch $tf
22066         oid=$($LFS getstripe $tf | awk '/obdidx/{getline; print $2}')
22067         zfs_objid=$(zfs_oid_to_objid ost1 $oid)
22068
22069         dd if=/dev/zero of=$tf bs=1K count=1 oflag=sync conv=notrunc
22070         blksz=$(zfs_object_blksz ost1 $zfs_objid)
22071         [ $blksz -eq $PAGE_SIZE ] ||
22072                 error "blksz error: $blksz, expected: $PAGE_SIZE"
22073
22074         dd if=/dev/zero of=$tf bs=64K count=1 oflag=sync conv=notrunc seek=128
22075         blksz=$(zfs_object_blksz ost1 $zfs_objid)
22076         [ $blksz -eq 65536 ] || error "blksz error: $blksz, expected: 64k"
22077
22078         dd if=/dev/zero of=$tf bs=1M count=1 oflag=sync conv=notrunc
22079         blksz=$(zfs_object_blksz ost1 $zfs_objid)
22080         [ $blksz -eq 65536 ] || error "rewrite error: $blksz, expected: 64k"
22081 }
22082 run_test 312 "make sure ZFS adjusts its block size by write pattern"
22083
22084 test_313() {
22085         remote_ost_nodsh && skip "remote OST with nodsh"
22086
22087         local file=$DIR/$tfile
22088
22089         rm -f $file
22090         $LFS setstripe -c 1 -i 0 $file || error "setstripe failed"
22091
22092         # define OBD_FAIL_TGT_RCVD_EIO           0x720
22093         do_facet ost1 "$LCTL set_param fail_loc=0x720"
22094         dd if=/dev/zero of=$file bs=$PAGE_SIZE oflag=direct count=1 &&
22095                 error "write should failed"
22096         do_facet ost1 "$LCTL set_param fail_loc=0"
22097         rm -f $file
22098 }
22099 run_test 313 "io should fail after last_rcvd update fail"
22100
22101 test_314() {
22102         [ $OSTCOUNT -lt 2 ] && skip "needs >= 2 OSTs"
22103
22104         $LFS setstripe -c 2 -i 0 $DIR/$tfile || error "setstripe failed"
22105         do_facet ost1 "$LCTL set_param fail_loc=0x720"
22106         rm -f $DIR/$tfile
22107         wait_delete_completed
22108         do_facet ost1 "$LCTL set_param fail_loc=0"
22109 }
22110 run_test 314 "OSP shouldn't fail after last_rcvd update failure"
22111
22112 test_315() { # LU-618
22113         [ -f /proc/$$/io ] || skip_env "no IO accounting in kernel"
22114
22115         local file=$DIR/$tfile
22116         rm -f $file
22117
22118         $MULTIOP $file oO_CREAT:O_DIRECT:O_RDWR:w4063232c ||
22119                 error "multiop file write failed"
22120         $MULTIOP $file oO_RDONLY:r4063232_c &
22121         PID=$!
22122
22123         sleep 2
22124
22125         local rbytes=$(awk '/read_bytes/ { print $2 }' /proc/$PID/io)
22126         kill -USR1 $PID
22127
22128         [ $rbytes -gt 4000000 ] || error "read is not accounted ($rbytes)"
22129         rm -f $file
22130 }
22131 run_test 315 "read should be accounted"
22132
22133 test_316() {
22134         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
22135         large_xattr_enabled || skip_env "ea_inode feature disabled"
22136
22137         rm -rf $DIR/$tdir/d
22138         mkdir -p $DIR/$tdir/d
22139         chown nobody $DIR/$tdir/d
22140         touch $DIR/$tdir/d/file
22141
22142         $LFS mv -m1 $DIR/$tdir/d || error "lfs mv failed"
22143 }
22144 run_test 316 "lfs mv"
22145
22146 test_317() {
22147         [ $MDS1_VERSION -lt $(version_code 2.11.53) ] &&
22148                 skip "Need MDS version at least 2.11.53"
22149         if [ "$ost1_FSTYPE" == "zfs" ]; then
22150                 skip "LU-10370: no implementation for ZFS"
22151         fi
22152
22153         local trunc_sz
22154         local grant_blk_size
22155
22156         grant_blk_size=$($LCTL get_param osc.$FSNAME*.import |
22157                         awk '/grant_block_size:/ { print $2; exit; }')
22158         #
22159         # Create File of size 5M. Truncate it to below size's and verify
22160         # blocks count.
22161         #
22162         dd if=/dev/zero of=$DIR/$tfile bs=5M count=1 conv=fsync ||
22163                 error "Create file $DIR/$tfile failed"
22164         stack_trap "rm -f $DIR/$tfile" EXIT
22165
22166         for trunc_sz in 2097152 4097 4000 509 0; do
22167                 $TRUNCATE $DIR/$tfile $trunc_sz ||
22168                         error "truncate $tfile to $trunc_sz failed"
22169                 local sz=$(stat --format=%s $DIR/$tfile)
22170                 local blk=$(stat --format=%b $DIR/$tfile)
22171                 local trunc_blk=$((((trunc_sz + (grant_blk_size - 1) ) /
22172                                      grant_blk_size) * 8))
22173
22174                 if [[ $blk -ne $trunc_blk ]]; then
22175                         $(which stat) $DIR/$tfile
22176                         error "Expected Block $trunc_blk got $blk for $tfile"
22177                 fi
22178
22179                 $CHECKSTAT -s $trunc_sz $DIR/$tfile ||
22180                         error "Expected Size $trunc_sz got $sz for $tfile"
22181         done
22182
22183         #
22184         # sparse file test
22185         # Create file with a hole and write actual two blocks. Block count
22186         # must be 16.
22187         #
22188         dd if=/dev/zero of=$DIR/$tfile bs=$grant_blk_size count=2 seek=5 \
22189                 conv=fsync || error "Create file : $DIR/$tfile"
22190
22191         # Calculate the final truncate size.
22192         trunc_sz=$(($(stat --format=%s $DIR/$tfile) - (grant_blk_size + 1)))
22193
22194         #
22195         # truncate to size $trunc_sz bytes. Strip the last block
22196         # The block count must drop to 8
22197         #
22198         $TRUNCATE $DIR/$tfile $trunc_sz ||
22199                 error "truncate $tfile to $trunc_sz failed"
22200
22201         local trunc_bsz=$((grant_blk_size / $(stat --format=%B $DIR/$tfile)))
22202         sz=$(stat --format=%s $DIR/$tfile)
22203         blk=$(stat --format=%b $DIR/$tfile)
22204
22205         if [[ $blk -ne $trunc_bsz ]]; then
22206                 $(which stat) $DIR/$tfile
22207                 error "Expected Block $trunc_bsz got $blk for $tfile"
22208         fi
22209
22210         $CHECKSTAT -s $trunc_sz $DIR/$tfile ||
22211                 error "Expected Size $trunc_sz got $sz for $tfile"
22212 }
22213 run_test 317 "Verify blocks get correctly update after truncate"
22214
22215 test_318() {
22216         local old_max_active=$($LCTL get_param -n \
22217                             llite.*.max_read_ahead_async_active 2>/dev/null)
22218
22219         $LCTL set_param llite.*.max_read_ahead_async_active=256
22220         local max_active=$($LCTL get_param -n \
22221                            llite.*.max_read_ahead_async_active 2>/dev/null)
22222         [ $max_active -ne 256 ] && error "expected 256 but got $max_active"
22223
22224         $LCTL set_param llite.*.max_read_ahead_async_active=0 ||
22225                 error "set max_read_ahead_async_active should succeed"
22226
22227         $LCTL set_param llite.*.max_read_ahead_async_active=512
22228         max_active=$($LCTL get_param -n \
22229                      llite.*.max_read_ahead_async_active 2>/dev/null)
22230         [ $max_active -eq 512 ] || error "expected 512 but got $max_active"
22231
22232         # restore @max_active
22233         [ $old_max_active -ne 0 ] && $LCTL set_param \
22234                 llite.*.max_read_ahead_async_active=$old_max_active
22235
22236         local old_threshold=$($LCTL get_param -n \
22237                 llite.*.read_ahead_async_file_threshold_mb 2>/dev/null)
22238         local max_per_file_mb=$($LCTL get_param -n \
22239                 llite.*.max_read_ahead_per_file_mb 2>/dev/null)
22240
22241         local invalid=$(($max_per_file_mb + 1))
22242         $LCTL set_param \
22243                 llite.*.read_ahead_async_file_threshold_mb=$invalid\
22244                         && error "set $invalid should fail"
22245
22246         local valid=$(($invalid - 1))
22247         $LCTL set_param \
22248                 llite.*.read_ahead_async_file_threshold_mb=$valid ||
22249                         error "set $valid should succeed"
22250         local threshold=$($LCTL get_param -n \
22251                 llite.*.read_ahead_async_file_threshold_mb 2>/dev/null)
22252         [ $threshold -eq $valid ] || error \
22253                 "expect threshold $valid got $threshold"
22254         $LCTL set_param \
22255                 llite.*.read_ahead_async_file_threshold_mb=$old_threshold
22256 }
22257 run_test 318 "Verify async readahead tunables"
22258
22259 test_319() {
22260         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return 0
22261
22262         local before=$(date +%s)
22263         local evict
22264         local mdir=$DIR/$tdir
22265         local file=$mdir/xxx
22266
22267         $LFS mkdir -i0 $mdir || error "mkdir $mdir fails"
22268         touch $file
22269
22270 #define OBD_FAIL_LDLM_LOCAL_CANCEL_PAUSE 0x32c
22271         $LCTL set_param fail_val=5 fail_loc=0x8000032c
22272         $LFS mv -m1 $file &
22273
22274         sleep 1
22275         dd if=$file of=/dev/null
22276         wait
22277         evict=$($LCTL get_param mdc.$FSNAME-MDT*.state |
22278           awk -F"[ [,]" '/EVICTED ]$/ { if (mx<$5) {mx=$5;} } END { print mx }')
22279
22280         [ -z "$evict" ] || [[ $evict -le $before ]] || error "eviction happened"
22281 }
22282 run_test 319 "lost lease lock on migrate error"
22283
22284 test_398a() { # LU-4198
22285         $LFS setstripe -c 1 -i 0 $DIR/$tfile
22286         $LCTL set_param ldlm.namespaces.*.lru_size=clear
22287
22288         # request a new lock on client
22289         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
22290
22291         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=direct conv=notrunc
22292         local lock_count=$($LCTL get_param -n \
22293                            ldlm.namespaces.*-OST0000-osc-ffff*.lru_size)
22294         [[ $lock_count -eq 0 ]] || error "lock should be cancelled by direct IO"
22295
22296         $LCTL set_param ldlm.namespaces.*-OST0000-osc-ffff*.lru_size=clear
22297
22298         # no lock cached, should use lockless IO and not enqueue new lock
22299         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=direct conv=notrunc
22300         lock_count=$($LCTL get_param -n \
22301                      ldlm.namespaces.*-OST0000-osc-ffff*.lru_size)
22302         [[ $lock_count -eq 0 ]] || error "no lock should be held by direct IO"
22303 }
22304 run_test 398a "direct IO should cancel lock otherwise lockless"
22305
22306 test_398b() { # LU-4198
22307         which fio || skip_env "no fio installed"
22308         $LFS setstripe -c -1 $DIR/$tfile
22309
22310         local size=12
22311         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$size
22312
22313         local njobs=4
22314         echo "mix direct rw ${size}M to OST0 by fio with $njobs jobs..."
22315         fio --name=rand-rw --rw=randrw --bs=$PAGE_SIZE --direct=1 \
22316                 --numjobs=$njobs --fallocate=none \
22317                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
22318                 --filename=$DIR/$tfile &
22319         bg_pid=$!
22320
22321         echo "mix buffer rw ${size}M to OST0 by fio with $njobs jobs..."
22322         fio --name=rand-rw --rw=randrw --bs=$PAGE_SIZE \
22323                 --numjobs=$njobs --fallocate=none \
22324                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
22325                 --filename=$DIR/$tfile || true
22326         wait $bg_pid
22327
22328         rm -rf $DIR/$tfile
22329 }
22330 run_test 398b "DIO and buffer IO race"
22331
22332 test_398c() { # LU-4198
22333         which fio || skip_env "no fio installed"
22334
22335         saved_debug=$($LCTL get_param -n debug)
22336         $LCTL set_param debug=0
22337
22338         local size=$(lctl get_param -n osc.$FSNAME-OST0000*.kbytesavail | head -1)
22339         ((size /= 1024)) # by megabytes
22340         ((size /= 2)) # write half of the OST at most
22341         [ $size -gt 40 ] && size=40 #reduce test time anyway
22342
22343         $LFS setstripe -c 1 $DIR/$tfile
22344
22345         # it seems like ldiskfs reserves more space than necessary if the
22346         # writing blocks are not mapped, so it extends the file firstly
22347         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$size && sync
22348         cancel_lru_locks osc
22349
22350         # clear and verify rpc_stats later
22351         $LCTL set_param osc.${FSNAME}-OST0000-osc-ffff*.rpc_stats=clear
22352
22353         local njobs=4
22354         echo "writing ${size}M to OST0 by fio with $njobs jobs..."
22355         fio --name=rand-write --rw=randwrite --bs=$PAGE_SIZE --direct=1 \
22356                 --numjobs=$njobs --fallocate=none --ioengine=libaio \
22357                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
22358                 --filename=$DIR/$tfile
22359         [ $? -eq 0 ] || error "fio write error"
22360
22361         [ $($LCTL get_param -n \
22362          ldlm.namespaces.${FSNAME}-OST0000-osc-ffff*.lock_count) -eq 0 ] ||
22363                 error "Locks were requested while doing AIO"
22364
22365         # get the percentage of 1-page I/O
22366         pct=$($LCTL get_param osc.${FSNAME}-OST0000-osc-ffff*.rpc_stats |
22367                 grep -A 1 'pages per rpc' | grep -v 'pages per rpc' |
22368                 awk '{print $7}')
22369         [ $pct -le 50 ] || error "$pct% of I/O are 1-page"
22370
22371         echo "mix rw ${size}M to OST0 by fio with $njobs jobs..."
22372         fio --name=rand-rw --rw=randrw --bs=$PAGE_SIZE --direct=1 \
22373                 --numjobs=$njobs --fallocate=none --ioengine=libaio \
22374                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
22375                 --filename=$DIR/$tfile
22376         [ $? -eq 0 ] || error "fio mixed read write error"
22377
22378         echo "AIO with large block size ${size}M"
22379         fio --name=rand-rw --rw=randrw --bs=${size}M --direct=1 \
22380                 --numjobs=1 --fallocate=none --ioengine=libaio \
22381                 --iodepth=16 --allow_file_create=0 --size=${size}M \
22382                 --filename=$DIR/$tfile
22383         [ $? -eq 0 ] || error "fio large block size failed"
22384
22385         rm -rf $DIR/$tfile
22386         $LCTL set_param debug="$saved_debug"
22387 }
22388 run_test 398c "run fio to test AIO"
22389
22390 test_398d() { #  LU-13846
22391         test -f aiocp || skip_env "no aiocp installed"
22392         local aio_file=$DIR/aio_file
22393
22394         $LFS setstripe -c -1 -S 1M $DIR/$tfile $aio_file
22395
22396         dd if=/dev/urandom of=$DIR/$tfile bs=1M count=64
22397         aiocp -a $PAGE_SIZE -b 64M -s 64M -f O_DIRECT $DIR/$tfile $aio_file
22398
22399         diff $DIR/$tfile $aio_file || "file diff after aiocp"
22400
22401         # make sure we don't crash and fail properly
22402         aiocp -a 512 -b 64M -s 64M -f O_DIRECT $DIR/$tfile $aio_file &&
22403                 error "aio not aligned with PAGE SIZE should fail"
22404
22405         rm -rf $DIR/$tfile $aio_file
22406 }
22407 run_test 398d "run aiocp to verify block size > stripe size"
22408
22409 test_398e() {
22410         dd if=/dev/zero of=$DIR/$tfile bs=1234 count=1
22411         touch $DIR/$tfile.new
22412         dd if=$DIR/$tfile of=$DIR/$tfile.new bs=1M count=1 oflag=direct
22413 }
22414 run_test 398e "O_Direct open cleared by fcntl doesn't cause hang"
22415
22416 test_fake_rw() {
22417         local read_write=$1
22418         if [ "$read_write" = "write" ]; then
22419                 local dd_cmd="dd if=/dev/zero of=$DIR/$tfile"
22420         elif [ "$read_write" = "read" ]; then
22421                 local dd_cmd="dd of=/dev/null if=$DIR/$tfile"
22422         else
22423                 error "argument error"
22424         fi
22425
22426         # turn off debug for performance testing
22427         local saved_debug=$($LCTL get_param -n debug)
22428         $LCTL set_param debug=0
22429
22430         $LFS setstripe -c 1 -i 0 $DIR/$tfile
22431
22432         # get ost1 size - $FSNAME-OST0000
22433         local ost1_avail_size=$($LFS df | awk /${ost1_svc}/'{ print $4 }')
22434         local blocks=$((ost1_avail_size/2/1024)) # half avail space by megabytes
22435         [ $blocks -gt 1000 ] && blocks=1000 # 1G in maximum
22436
22437         if [ "$read_write" = "read" ]; then
22438                 $TRUNCATE $DIR/$tfile $(expr 1048576 \* $blocks)
22439         fi
22440
22441         local start_time=$(date +%s.%N)
22442         $dd_cmd bs=1M count=$blocks oflag=sync ||
22443                 error "real dd $read_write error"
22444         local duration=$(bc <<< "$(date +%s.%N) - $start_time")
22445
22446         if [ "$read_write" = "write" ]; then
22447                 rm -f $DIR/$tfile
22448         fi
22449
22450         # define OBD_FAIL_OST_FAKE_RW           0x238
22451         do_facet ost1 $LCTL set_param fail_loc=0x238
22452
22453         local start_time=$(date +%s.%N)
22454         $dd_cmd bs=1M count=$blocks oflag=sync ||
22455                 error "fake dd $read_write error"
22456         local duration_fake=$(bc <<< "$(date +%s.%N) - $start_time")
22457
22458         if [ "$read_write" = "write" ]; then
22459                 # verify file size
22460                 cancel_lru_locks osc
22461                 $CHECKSTAT -t file -s $((blocks * 1024 * 1024)) $DIR/$tfile ||
22462                         error "$tfile size not $blocks MB"
22463         fi
22464         do_facet ost1 $LCTL set_param fail_loc=0
22465
22466         echo "fake $read_write $duration_fake vs. normal $read_write" \
22467                 "$duration in seconds"
22468         [ $(bc <<< "$duration_fake < $duration") -eq 1 ] ||
22469                 error_not_in_vm "fake write is slower"
22470
22471         $LCTL set_param -n debug="$saved_debug"
22472         rm -f $DIR/$tfile
22473 }
22474 test_399a() { # LU-7655 for OST fake write
22475         remote_ost_nodsh && skip "remote OST with nodsh"
22476
22477         test_fake_rw write
22478 }
22479 run_test 399a "fake write should not be slower than normal write"
22480
22481 test_399b() { # LU-8726 for OST fake read
22482         remote_ost_nodsh && skip "remote OST with nodsh"
22483         if [ "$ost1_FSTYPE" != "ldiskfs" ]; then
22484                 skip_env "ldiskfs only test"
22485         fi
22486
22487         test_fake_rw read
22488 }
22489 run_test 399b "fake read should not be slower than normal read"
22490
22491 test_400a() { # LU-1606, was conf-sanity test_74
22492         if ! which $CC > /dev/null 2>&1; then
22493                 skip_env "$CC is not installed"
22494         fi
22495
22496         local extra_flags=''
22497         local out=$TMP/$tfile
22498         local prefix=/usr/include/lustre
22499         local prog
22500
22501         # Oleg removes c files in his test rig so test if any c files exist
22502         [ -z "$(ls -A $LUSTRE_TESTS_API_DIR)" ] && \
22503                 skip_env "Needed c test files are missing"
22504
22505         if ! [[ -d $prefix ]]; then
22506                 # Assume we're running in tree and fixup the include path.
22507                 extra_flags+=" -I$LUSTRE/../lnet/include/uapi -I$LUSTRE/include/uapi -I$LUSTRE/include"
22508                 extra_flags+=" -L$LUSTRE/utils/.lib"
22509         fi
22510
22511         for prog in $LUSTRE_TESTS_API_DIR/*.c; do
22512                 $CC -Wall -Werror -std=c99 $extra_flags -o $out $prog -llustreapi ||
22513                         error "client api broken"
22514         done
22515         rm -f $out
22516 }
22517 run_test 400a "Lustre client api program can compile and link"
22518
22519 test_400b() { # LU-1606, LU-5011
22520         local header
22521         local out=$TMP/$tfile
22522         local prefix=/usr/include/linux/lustre
22523
22524         # We use a hard coded prefix so that this test will not fail
22525         # when run in tree. There are headers in lustre/include/lustre/
22526         # that are not packaged (like lustre_idl.h) and have more
22527         # complicated include dependencies (like config.h and lnet/types.h).
22528         # Since this test about correct packaging we just skip them when
22529         # they don't exist (see below) rather than try to fixup cppflags.
22530
22531         if ! which $CC > /dev/null 2>&1; then
22532                 skip_env "$CC is not installed"
22533         fi
22534
22535         for header in $prefix/*.h; do
22536                 if ! [[ -f "$header" ]]; then
22537                         continue
22538                 fi
22539
22540                 if [[ "$(basename $header)" == lustre_ioctl.h ]]; then
22541                         continue # lustre_ioctl.h is internal header
22542                 fi
22543
22544                 $CC -Wall -Werror -std=c99 -include $header -c -x c /dev/null -o $out ||
22545                         error "cannot compile '$header'"
22546         done
22547         rm -f $out
22548 }
22549 run_test 400b "packaged headers can be compiled"
22550
22551 test_401a() { #LU-7437
22552         local printf_arg=$(find -printf 2>&1 | grep "unrecognized:")
22553         [ -n "$printf_arg" ] && skip_env "find does not support -printf"
22554
22555         #count the number of parameters by "list_param -R"
22556         local params=$($LCTL list_param -R '*' 2>/dev/null | wc -l)
22557         #count the number of parameters by listing proc files
22558         local proc_regexp="/{proc,sys}/{fs,sys,kernel/debug}/{lustre,lnet}/"
22559         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
22560         echo "proc_dirs='$proc_dirs'"
22561         [ -n "$proc_dirs" ] || error "no proc_dirs on $HOSTNAME"
22562         local procs=$(find -L $proc_dirs -mindepth 1 -printf '%P\n' 2>/dev/null|
22563                       sort -u | wc -l)
22564
22565         [ $params -eq $procs ] ||
22566                 error "found $params parameters vs. $procs proc files"
22567
22568         # test the list_param -D option only returns directories
22569         params=$($LCTL list_param -R -D '*' 2>/dev/null | wc -l)
22570         #count the number of parameters by listing proc directories
22571         procs=$(find -L $proc_dirs -mindepth 1 -type d -printf '%P\n' 2>/dev/null |
22572                 sort -u | wc -l)
22573
22574         [ $params -eq $procs ] ||
22575                 error "found $params parameters vs. $procs proc files"
22576 }
22577 run_test 401a "Verify if 'lctl list_param -R' can list parameters recursively"
22578
22579 test_401b() {
22580         # jobid_var may not allow arbitrary values, so use jobid_name
22581         # if available
22582         if $LCTL list_param jobid_name > /dev/null 2>&1; then
22583                 local testname=jobid_name tmp='testing%p'
22584         else
22585                 local testname=jobid_var tmp=testing
22586         fi
22587
22588         local save=$($LCTL get_param -n $testname)
22589
22590         $LCTL set_param foo=bar $testname=$tmp bar=baz &&
22591                 error "no error returned when setting bad parameters"
22592
22593         local jobid_new=$($LCTL get_param -n foe $testname baz)
22594         [[ "$jobid_new" == "$tmp" ]] || error "jobid tmp $jobid_new != $tmp"
22595
22596         $LCTL set_param -n fog=bam $testname=$save bat=fog
22597         local jobid_old=$($LCTL get_param -n foe $testname bag)
22598         [[ "$jobid_old" == "$save" ]] || error "jobid new $jobid_old != $save"
22599 }
22600 run_test 401b "Verify 'lctl {get,set}_param' continue after error"
22601
22602 test_401c() {
22603         # jobid_var may not allow arbitrary values, so use jobid_name
22604         # if available
22605         if $LCTL list_param jobid_name > /dev/null 2>&1; then
22606                 local testname=jobid_name
22607         else
22608                 local testname=jobid_var
22609         fi
22610
22611         local jobid_var_old=$($LCTL get_param -n $testname)
22612         local jobid_var_new
22613
22614         $LCTL set_param $testname= &&
22615                 error "no error returned for 'set_param a='"
22616
22617         jobid_var_new=$($LCTL get_param -n $testname)
22618         [[ "$jobid_var_old" == "$jobid_var_new" ]] ||
22619                 error "$testname was changed by setting without value"
22620
22621         $LCTL set_param $testname &&
22622                 error "no error returned for 'set_param a'"
22623
22624         jobid_var_new=$($LCTL get_param -n $testname)
22625         [[ "$jobid_var_old" == "$jobid_var_new" ]] ||
22626                 error "$testname was changed by setting without value"
22627 }
22628 run_test 401c "Verify 'lctl set_param' without value fails in either format."
22629
22630 test_401d() {
22631         # jobid_var may not allow arbitrary values, so use jobid_name
22632         # if available
22633         if $LCTL list_param jobid_name > /dev/null 2>&1; then
22634                 local testname=jobid_name new_value='foo=bar%p'
22635         else
22636                 local testname=jobid_var new_valuie=foo=bar
22637         fi
22638
22639         local jobid_var_old=$($LCTL get_param -n $testname)
22640         local jobid_var_new
22641
22642         $LCTL set_param $testname=$new_value ||
22643                 error "'set_param a=b' did not accept a value containing '='"
22644
22645         jobid_var_new=$($LCTL get_param -n $testname)
22646         [[ "$jobid_var_new" == "$new_value" ]] ||
22647                 error "'set_param a=b' failed on a value containing '='"
22648
22649         # Reset the $testname to test the other format
22650         $LCTL set_param $testname=$jobid_var_old
22651         jobid_var_new=$($LCTL get_param -n $testname)
22652         [[ "$jobid_var_new" == "$jobid_var_old" ]] ||
22653                 error "failed to reset $testname"
22654
22655         $LCTL set_param $testname $new_value ||
22656                 error "'set_param a b' did not accept a value containing '='"
22657
22658         jobid_var_new=$($LCTL get_param -n $testname)
22659         [[ "$jobid_var_new" == "$new_value" ]] ||
22660                 error "'set_param a b' failed on a value containing '='"
22661
22662         $LCTL set_param $testname $jobid_var_old
22663         jobid_var_new=$($LCTL get_param -n $testname)
22664         [[ "$jobid_var_new" == "$jobid_var_old" ]] ||
22665                 error "failed to reset $testname"
22666 }
22667 run_test 401d "Verify 'lctl set_param' accepts values containing '='"
22668
22669 test_402() {
22670         [[ $MDS1_VERSION -ge $(version_code 2.7.66) ]] ||
22671         [[ $MDS1_VERSION -ge $(version_code 2.7.18.4) &&
22672                 $MDS1_VERSION -lt $(version_code 2.7.50) ]] ||
22673         [[ $MDS1_VERSION -ge $(version_code 2.7.2) &&
22674                 $MDS1_VERSION -lt $(version_code 2.7.11) ]] ||
22675                 skip "Need MDS version 2.7.2+ or 2.7.18.4+ or 2.7.66+"
22676         remote_mds_nodsh && skip "remote MDS with nodsh"
22677
22678         $LFS setdirstripe -i 0 $DIR/$tdir || error "setdirstripe -i 0 failed"
22679 #define OBD_FAIL_MDS_FLD_LOOKUP 0x15c
22680         do_facet mds1 "lctl set_param fail_loc=0x8000015c"
22681         touch $DIR/$tdir/$tfile && error "touch should fail with ENOENT" ||
22682                 echo "Touch failed - OK"
22683 }
22684 run_test 402 "Return ENOENT to lod_generate_and_set_lovea"
22685
22686 test_403() {
22687         local file1=$DIR/$tfile.1
22688         local file2=$DIR/$tfile.2
22689         local tfile=$TMP/$tfile
22690
22691         rm -f $file1 $file2 $tfile
22692
22693         touch $file1
22694         ln $file1 $file2
22695
22696         # 30 sec OBD_TIMEOUT in ll_getattr()
22697         # right before populating st_nlink
22698         $LCTL set_param fail_loc=0x80001409
22699         stat -c %h $file1 > $tfile &
22700
22701         # create an alias, drop all locks and reclaim the dentry
22702         < $file2
22703         cancel_lru_locks mdc
22704         cancel_lru_locks osc
22705         sysctl -w vm.drop_caches=2
22706
22707         wait
22708
22709         [ $(cat $tfile) -gt 0 ] || error "wrong nlink count: $(cat $tfile)"
22710
22711         rm -f $tfile $file1 $file2
22712 }
22713 run_test 403 "i_nlink should not drop to zero due to aliasing"
22714
22715 test_404() { # LU-6601
22716         [[ $MDS1_VERSION -ge $(version_code 2.8.53) ]] ||
22717                 skip "Need server version newer than 2.8.52"
22718         remote_mds_nodsh && skip "remote MDS with nodsh"
22719
22720         local mosps=$(do_facet $SINGLEMDS $LCTL dl |
22721                 awk '/osp .*-osc-MDT/ { print $4}')
22722
22723         local osp
22724         for osp in $mosps; do
22725                 echo "Deactivate: " $osp
22726                 do_facet $SINGLEMDS $LCTL --device %$osp deactivate
22727                 local stat=$(do_facet $SINGLEMDS $LCTL dl |
22728                         awk -vp=$osp '$4 == p { print $2 }')
22729                 [ $stat = IN ] || {
22730                         do_facet $SINGLEMDS $LCTL dl | grep -w $osp
22731                         error "deactivate error"
22732                 }
22733                 echo "Activate: " $osp
22734                 do_facet $SINGLEMDS $LCTL --device %$osp activate
22735                 local stat=$(do_facet $SINGLEMDS $LCTL dl |
22736                         awk -vp=$osp '$4 == p { print $2 }')
22737                 [ $stat = UP ] || {
22738                         do_facet $SINGLEMDS $LCTL dl | grep -w $osp
22739                         error "activate error"
22740                 }
22741         done
22742 }
22743 run_test 404 "validate manual {de}activated works properly for OSPs"
22744
22745 test_405() {
22746         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
22747         [ $MDS1_VERSION -lt $(version_code 2.6.92) ] ||
22748                 [ $CLIENT_VERSION -lt $(version_code 2.6.99) ] &&
22749                         skip "Layout swap lock is not supported"
22750
22751         check_swap_layouts_support
22752         check_swap_layout_no_dom $DIR
22753
22754         test_mkdir $DIR/$tdir
22755         swap_lock_test -d $DIR/$tdir ||
22756                 error "One layout swap locked test failed"
22757 }
22758 run_test 405 "Various layout swap lock tests"
22759
22760 test_406() {
22761         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22762         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
22763         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
22764         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22765         [ $MDS1_VERSION -lt $(version_code 2.8.50) ] &&
22766                 skip "Need MDS version at least 2.8.50"
22767
22768         local def_stripe_size=$($LFS getstripe -S $MOUNT)
22769         local test_pool=$TESTNAME
22770
22771         pool_add $test_pool || error "pool_add failed"
22772         pool_add_targets $test_pool 0 $(($OSTCOUNT - 1)) 1 ||
22773                 error "pool_add_targets failed"
22774
22775         save_layout_restore_at_exit $MOUNT
22776
22777         # parent set default stripe count only, child will stripe from both
22778         # parent and fs default
22779         $LFS setstripe -c 1 -i 1 -S $((def_stripe_size * 2)) -p $test_pool $MOUNT ||
22780                 error "setstripe $MOUNT failed"
22781         $LFS mkdir -c $MDSCOUNT $DIR/$tdir || error "mkdir $tdir failed"
22782         $LFS setstripe -c $OSTCOUNT $DIR/$tdir || error "setstripe $tdir failed"
22783         for i in $(seq 10); do
22784                 local f=$DIR/$tdir/$tfile.$i
22785                 touch $f || error "touch failed"
22786                 local count=$($LFS getstripe -c $f)
22787                 [ $count -eq $OSTCOUNT ] ||
22788                         error "$f stripe count $count != $OSTCOUNT"
22789                 local offset=$($LFS getstripe -i $f)
22790                 [ $offset -eq 1 ] || error "$f stripe offset $offset != 1"
22791                 local size=$($LFS getstripe -S $f)
22792                 [ $size -eq $((def_stripe_size * 2)) ] ||
22793                         error "$f stripe size $size != $((def_stripe_size * 2))"
22794                 local pool=$($LFS getstripe -p $f)
22795                 [ $pool == $test_pool ] || error "$f pool $pool != $test_pool"
22796         done
22797
22798         # change fs default striping, delete parent default striping, now child
22799         # will stripe from new fs default striping only
22800         $LFS setstripe -c 1 -S $def_stripe_size -i 0 $MOUNT ||
22801                 error "change $MOUNT default stripe failed"
22802         $LFS setstripe -c 0 $DIR/$tdir ||
22803                 error "delete $tdir default stripe failed"
22804         for i in $(seq 11 20); do
22805                 local f=$DIR/$tdir/$tfile.$i
22806                 touch $f || error "touch $f failed"
22807                 local count=$($LFS getstripe -c $f)
22808                 [ $count -eq 1 ] || error "$f stripe count $count != 1"
22809                 local offset=$($LFS getstripe -i $f)
22810                 [ $offset -eq 0 ] || error "$f stripe offset $offset != 0"
22811                 local size=$($LFS getstripe -S $f)
22812                 [ $size -eq $def_stripe_size ] ||
22813                         error "$f stripe size $size != $def_stripe_size"
22814                 local pool=$($LFS getstripe -p $f)
22815                 [ $pool == $test_pool ] || error "$f pool $pool isn't set"
22816         done
22817
22818         unlinkmany $DIR/$tdir/$tfile. 1 20
22819
22820         local f=$DIR/$tdir/$tfile
22821         pool_remove_all_targets $test_pool $f
22822         pool_remove $test_pool $f
22823 }
22824 run_test 406 "DNE support fs default striping"
22825
22826 test_407() {
22827         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22828         [[ $MDS1_VERSION -lt $(version_code 2.8.55) ]] &&
22829                 skip "Need MDS version at least 2.8.55"
22830         remote_mds_nodsh && skip "remote MDS with nodsh"
22831
22832         $LFS mkdir -i 0 -c 1 $DIR/$tdir.0 ||
22833                 error "$LFS mkdir -i 0 -c 1 $tdir.0 failed"
22834         $LFS mkdir -i 1 -c 1 $DIR/$tdir.1 ||
22835                 error "$LFS mkdir -i 1 -c 1 $tdir.1 failed"
22836         touch $DIR/$tdir.0/$tfile.0 || error "touch $tdir.0/$tfile.0 failed"
22837
22838         #define OBD_FAIL_DT_TXN_STOP    0x2019
22839         for idx in $(seq $MDSCOUNT); do
22840                 do_facet mds$idx "lctl set_param fail_loc=0x2019"
22841         done
22842         $LFS mkdir -c 2 $DIR/$tdir && error "$LFS mkdir -c 2 $tdir should fail"
22843         mv $DIR/$tdir.0/$tfile.0 $DIR/$tdir.1/$tfile.1 &&
22844                 error "mv $tdir.0/$tfile.0 $tdir.1/$tfile.1 should fail"
22845         true
22846 }
22847 run_test 407 "transaction fail should cause operation fail"
22848
22849 test_408() {
22850         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1 oflag=direct
22851
22852         #define OBD_FAIL_OSC_BRW_PREP_REQ2        0x40a
22853         lctl set_param fail_loc=0x8000040a
22854         # let ll_prepare_partial_page() fail
22855         dd if=/dev/zero of=$DIR/$tfile bs=2048 count=1 conv=notrunc || true
22856
22857         rm -f $DIR/$tfile
22858
22859         # create at least 100 unused inodes so that
22860         # shrink_icache_memory(0) should not return 0
22861         touch $DIR/$tfile-{0..100}
22862         rm -f $DIR/$tfile-{0..100}
22863         sync
22864
22865         echo 2 > /proc/sys/vm/drop_caches
22866 }
22867 run_test 408 "drop_caches should not hang due to page leaks"
22868
22869 test_409()
22870 {
22871         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
22872
22873         mkdir -p $DIR/$tdir || error "(0) Fail to mkdir"
22874         $LFS mkdir -i 1 -c 2 $DIR/$tdir/foo || error "(1) Fail to mkdir"
22875         touch $DIR/$tdir/guard || error "(2) Fail to create"
22876
22877         local PREFIX=$(str_repeat 'A' 128)
22878         echo "Create 1K hard links start at $(date)"
22879         createmany -l $DIR/$tdir/guard $DIR/$tdir/foo/${PREFIX}_ 1000 ||
22880                 error "(3) Fail to hard link"
22881
22882         echo "Links count should be right although linkEA overflow"
22883         stat $DIR/$tdir/guard || error "(4) Fail to stat"
22884         local linkcount=$(stat --format=%h $DIR/$tdir/guard)
22885         [ $linkcount -eq 1001 ] ||
22886                 error "(5) Unexpected hard links count: $linkcount"
22887
22888         echo "List all links start at $(date)"
22889         ls -l $DIR/$tdir/foo > /dev/null ||
22890                 error "(6) Fail to list $DIR/$tdir/foo"
22891
22892         echo "Unlink hard links start at $(date)"
22893         unlinkmany $DIR/$tdir/foo/${PREFIX}_ 1000 ||
22894                 error "(7) Fail to unlink"
22895         echo "Unlink hard links finished at $(date)"
22896 }
22897 run_test 409 "Large amount of cross-MDTs hard links on the same file"
22898
22899 test_410()
22900 {
22901         [[ $CLIENT_VERSION -lt $(version_code 2.9.59) ]] &&
22902                 skip "Need client version at least 2.9.59"
22903         [ -f $LUSTRE/tests/kernel/kinode.ko ] ||
22904                 skip "Need MODULES build"
22905
22906         # Create a file, and stat it from the kernel
22907         local testfile=$DIR/$tfile
22908         touch $testfile
22909
22910         local run_id=$RANDOM
22911         local my_ino=$(stat --format "%i" $testfile)
22912
22913         # Try to insert the module. This will always fail as the
22914         # module is designed to not be inserted.
22915         insmod $LUSTRE/tests/kernel/kinode.ko run_id=$run_id fname=$testfile \
22916             &> /dev/null
22917
22918         # Anything but success is a test failure
22919         dmesg | grep -q \
22920             "lustre_kinode_$run_id: inode numbers are identical: $my_ino" ||
22921             error "no inode match"
22922 }
22923 run_test 410 "Test inode number returned from kernel thread"
22924
22925 cleanup_test411_cgroup() {
22926         trap 0
22927         rmdir "$1"
22928 }
22929
22930 test_411() {
22931         local cg_basedir=/sys/fs/cgroup/memory
22932         # LU-9966
22933         test -f "$cg_basedir/memory.kmem.limit_in_bytes" ||
22934                 skip "no setup for cgroup"
22935
22936         dd if=/dev/zero of=$DIR/$tfile bs=1M count=100 conv=fsync ||
22937                 error "test file creation failed"
22938         cancel_lru_locks osc
22939
22940         # Create a very small memory cgroup to force a slab allocation error
22941         local cgdir=$cg_basedir/osc_slab_alloc
22942         mkdir $cgdir || error "cgroup mkdir '$cgdir' failed"
22943         trap "cleanup_test411_cgroup $cgdir" EXIT
22944         echo 2M > $cgdir/memory.kmem.limit_in_bytes
22945         echo 1M > $cgdir/memory.limit_in_bytes
22946
22947         # Should not LBUG, just be killed by oom-killer
22948         # dd will return 0 even allocation failure in some environment.
22949         # So don't check return value
22950         sh -c "echo \$$ > $cgdir/tasks && dd if=$DIR/$tfile of=/dev/null"
22951         cleanup_test411_cgroup $cgdir
22952
22953         return 0
22954 }
22955 run_test 411 "Slab allocation error with cgroup does not LBUG"
22956
22957 test_412() {
22958         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22959         if [ $MDS1_VERSION -lt $(version_code 2.10.55) ]; then
22960                 skip "Need server version at least 2.10.55"
22961         fi
22962
22963         $LFS mkdir -i $((MDSCOUNT - 1)),$((MDSCOUNT - 2)) $DIR/$tdir ||
22964                 error "mkdir failed"
22965         $LFS getdirstripe $DIR/$tdir
22966         local stripe_index=$($LFS getdirstripe -i $DIR/$tdir)
22967         [ $stripe_index -eq $((MDSCOUNT - 1)) ] ||
22968                 error "expect $((MDSCOUT - 1)) get $stripe_index"
22969         local stripe_count=$($LFS getdirstripe -T $DIR/$tdir)
22970         [ $stripe_count -eq 2 ] ||
22971                 error "expect 2 get $stripe_count"
22972 }
22973 run_test 412 "mkdir on specific MDTs"
22974
22975 test_qos_mkdir() {
22976         local mkdir_cmd=$1
22977         local stripe_count=$2
22978         local mdts=$(comma_list $(mdts_nodes))
22979
22980         local testdir
22981         local lmv_qos_prio_free
22982         local lmv_qos_threshold_rr
22983         local lmv_qos_maxage
22984         local lod_qos_prio_free
22985         local lod_qos_threshold_rr
22986         local lod_qos_maxage
22987         local count
22988         local i
22989
22990         lmv_qos_prio_free=$($LCTL get_param -n lmv.*.qos_prio_free | head -n1)
22991         lmv_qos_prio_free=${lmv_qos_prio_free%%%}
22992         lmv_qos_threshold_rr=$($LCTL get_param -n lmv.*.qos_threshold_rr |
22993                 head -n1)
22994         lmv_qos_threshold_rr=${lmv_qos_threshold_rr%%%}
22995         lmv_qos_maxage=$($LCTL get_param -n lmv.*.qos_maxage)
22996         stack_trap "$LCTL set_param \
22997                 lmv.*.qos_prio_free=$lmv_qos_prio_free > /dev/null" EXIT
22998         stack_trap "$LCTL set_param \
22999                 lmv.*.qos_threshold_rr=$lmv_qos_threshold_rr > /dev/null" EXIT
23000         stack_trap "$LCTL set_param \
23001                 lmv.*.qos_maxage=$lmv_qos_maxage > /dev/null" EXIT
23002
23003         lod_qos_prio_free=$(do_facet mds1 $LCTL get_param -n \
23004                 lod.$FSNAME-MDT0000-mdtlov.mdt_qos_prio_free | head -n1)
23005         lod_qos_prio_free=${lod_qos_prio_free%%%}
23006         lod_qos_threshold_rr=$(do_facet mds1 $LCTL get_param -n \
23007                 lod.$FSNAME-MDT0000-mdtlov.mdt_qos_threshold_rr | head -n1)
23008         lod_qos_threshold_rr=${lod_qos_threshold_rr%%%}
23009         lod_qos_maxage=$(do_facet mds1 $LCTL get_param -n \
23010                 lod.$FSNAME-MDT0000-mdtlov.qos_maxage | awk '{ print $1 }')
23011         stack_trap "do_nodes $mdts $LCTL set_param \
23012                 lod.*.mdt_qos_prio_free=$lod_qos_prio_free > /dev/null" EXIT
23013         stack_trap "do_nodes $mdts $LCTL set_param \
23014                 lod.*.mdt_qos_threshold_rr=$lod_qos_threshold_rr > /dev/null" \
23015                 EXIT
23016         stack_trap "do_nodes $mdts $LCTL set_param \
23017                 lod.*.mdt_qos_maxage=$lod_qos_maxage > /dev/null" EXIT
23018
23019         echo
23020         echo "Mkdir (stripe_count $stripe_count) roundrobin:"
23021
23022         $LCTL set_param lmv.*.qos_threshold_rr=100 > /dev/null
23023         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_threshold_rr=100 > /dev/null
23024
23025         testdir=$DIR/$tdir-s$stripe_count/rr
23026
23027         for i in $(seq $((100 * MDSCOUNT))); do
23028                 eval $mkdir_cmd $testdir/subdir$i ||
23029                         error "$mkdir_cmd subdir$i failed"
23030         done
23031
23032         for i in $(seq $MDSCOUNT); do
23033                 count=$($LFS getdirstripe -i $testdir/* |
23034                                 grep ^$((i - 1))$ | wc -l)
23035                 echo "$count directories created on MDT$((i - 1))"
23036                 [ $count -eq 100 ] || error "subdirs are not evenly distributed"
23037
23038                 if [ $stripe_count -gt 1 ]; then
23039                         count=$($LFS getdirstripe $testdir/* |
23040                                 grep -P "^\s+$((i - 1))\t" | wc -l)
23041                         echo "$count stripes created on MDT$((i - 1))"
23042                         # deviation should < 5% of average
23043                         [ $count -lt $((95 * stripe_count)) ] ||
23044                         [ $count -gt $((105 * stripe_count)) ] &&
23045                                 error "stripes are not evenly distributed"
23046                 fi
23047         done
23048
23049         $LCTL set_param lmv.*.qos_threshold_rr=$lmv_qos_threshold_rr > /dev/null
23050         do_nodes $mdts $LCTL set_param \
23051                 lod.*.mdt_qos_threshold_rr=$lod_qos_threshold_rr > /dev/null
23052
23053         echo
23054         echo "Check for uneven MDTs: "
23055
23056         local ffree
23057         local bavail
23058         local max
23059         local min
23060         local max_index
23061         local min_index
23062         local tmp
23063
23064         ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.filesfree))
23065         bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.kbytesavail))
23066         bsize=$(lctl get_param -n mdc.*MDT0000*.blocksize)
23067
23068         max=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
23069         min=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
23070         max_index=0
23071         min_index=0
23072         for ((i = 1; i < ${#ffree[@]}; i++)); do
23073                 tmp=$(((${ffree[i]} >> 8) * (${bavail[i]} * bsize >> 16)))
23074                 if [ $tmp -gt $max ]; then
23075                         max=$tmp
23076                         max_index=$i
23077                 fi
23078                 if [ $tmp -lt $min ]; then
23079                         min=$tmp
23080                         min_index=$i
23081                 fi
23082         done
23083
23084         [ ${ffree[min_index]} -eq 0 ] &&
23085                 skip "no free files in MDT$min_index"
23086         [ ${ffree[min_index]} -gt 100000000 ] &&
23087                 skip "too much free files in MDT$min_index"
23088
23089         # Check if we need to generate uneven MDTs
23090         local threshold=50
23091         local diff=$(((max - min) * 100 / min))
23092         local value="$(generate_string 1024)"
23093
23094         while [ $diff -lt $threshold ]; do
23095                 # generate uneven MDTs, create till $threshold% diff
23096                 echo -n "weight diff=$diff% must be > $threshold% ..."
23097                 count=$((${ffree[min_index]} / 10))
23098                 # 50 sec per 10000 files in vm
23099                 [ $count -gt 40000 ] && [ "$SLOW" = "no" ] &&
23100                         skip "$count files to create"
23101                 echo "Fill MDT$min_index with $count files"
23102                 [ -d $DIR/$tdir-MDT$min_index ] ||
23103                         $LFS mkdir -i $min_index $DIR/$tdir-MDT$min_index ||
23104                         error "mkdir $tdir-MDT$min_index failed"
23105                 for i in $(seq $count); do
23106                         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE \
23107                                 $DIR/$tdir-MDT$min_index/f$j_$i > /dev/null ||
23108                                 error "create f$j_$i failed"
23109                         setfattr -n user.413b -v $value \
23110                                 $DIR/$tdir-MDT$min_index/f$j_$i ||
23111                                 error "setfattr f$j_$i failed"
23112                 done
23113
23114                 ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-*.filesfree))
23115                 bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-*.kbytesavail))
23116                 max=$(((${ffree[max_index]} >> 8) * \
23117                         (${bavail[max_index]} * bsize >> 16)))
23118                 min=$(((${ffree[min_index]} >> 8) * \
23119                         (${bavail[min_index]} * bsize >> 16)))
23120                 diff=$(((max - min) * 100 / min))
23121         done
23122
23123         echo "MDT filesfree available: ${ffree[@]}"
23124         echo "MDT blocks available: ${bavail[@]}"
23125         echo "weight diff=$diff%"
23126
23127         echo
23128         echo "Mkdir (stripe_count $stripe_count) with balanced space usage:"
23129
23130         $LCTL set_param lmv.*.qos_prio_free=100 > /dev/null
23131         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_prio_free=100 > /dev/null
23132         # decrease statfs age, so that it can be updated in time
23133         $LCTL set_param lmv.*.qos_maxage=1 > /dev/null
23134         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_maxage=1 > /dev/null
23135
23136         sleep 1
23137
23138         testdir=$DIR/$tdir-s$stripe_count/qos
23139
23140         for i in $(seq $((100 * MDSCOUNT))); do
23141                 eval $mkdir_cmd $testdir/subdir$i ||
23142                         error "$mkdir_cmd subdir$i failed"
23143         done
23144
23145         for i in $(seq $MDSCOUNT); do
23146                 count=$($LFS getdirstripe -i $testdir/* | grep ^$((i - 1))$ |
23147                         wc -l)
23148                 echo "$count directories created on MDT$((i - 1))"
23149
23150                 if [ $stripe_count -gt 1 ]; then
23151                         count=$($LFS getdirstripe $testdir/* |
23152                                 grep -P "^\s+$((i - 1))\t" | wc -l)
23153                         echo "$count stripes created on MDT$((i - 1))"
23154                 fi
23155         done
23156
23157         max=$($LFS getdirstripe -i $testdir/* | grep ^$max_index$ | wc -l)
23158         min=$($LFS getdirstripe -i $testdir/* | grep ^$min_index$ | wc -l)
23159
23160         # D-value should > 10% of averge
23161         [ $((max - min)) -lt 10 ] &&
23162                 error "subdirs shouldn't be evenly distributed"
23163
23164         # ditto
23165         if [ $stripe_count -gt 1 ]; then
23166                 max=$($LFS getdirstripe $testdir/* |
23167                         grep -P "^\s+$max_index\t" | wc -l)
23168                 min=$($LFS getdirstripe $testdir/* |
23169                         grep -P "^\s+$min_index\t" | wc -l)
23170                 [ $((max - min)) -le $((10 * stripe_count)) ] &&
23171                         error "stripes shouldn't be evenly distributed"|| true
23172         fi
23173 }
23174
23175 test_413a() {
23176         [ $MDSCOUNT -lt 2 ] &&
23177                 skip "We need at least 2 MDTs for this test"
23178
23179         [ $MDS1_VERSION -lt $(version_code 2.12.52) ] &&
23180                 skip "Need server version at least 2.12.52"
23181
23182         local stripe_count
23183
23184         for stripe_count in $(seq 1 $((MDSCOUNT - 1))); do
23185                 mkdir $DIR/$tdir-s$stripe_count || error "mkdir failed"
23186                 mkdir $DIR/$tdir-s$stripe_count/rr || error "mkdir failed"
23187                 mkdir $DIR/$tdir-s$stripe_count/qos || error "mkdir failed"
23188                 test_qos_mkdir "$LFS mkdir -c $stripe_count" $stripe_count
23189         done
23190 }
23191 run_test 413a "QoS mkdir with 'lfs mkdir -i -1'"
23192
23193 test_413b() {
23194         [ $MDSCOUNT -lt 2 ] &&
23195                 skip "We need at least 2 MDTs for this test"
23196
23197         [ $MDS1_VERSION -lt $(version_code 2.12.52) ] &&
23198                 skip "Need server version at least 2.12.52"
23199
23200         local stripe_count
23201
23202         for stripe_count in $(seq 1 $((MDSCOUNT - 1))); do
23203                 mkdir $DIR/$tdir-s$stripe_count || error "mkdir failed"
23204                 mkdir $DIR/$tdir-s$stripe_count/rr || error "mkdir failed"
23205                 mkdir $DIR/$tdir-s$stripe_count/qos || error "mkdir failed"
23206                 $LFS setdirstripe -D -c $stripe_count \
23207                         $DIR/$tdir-s$stripe_count/rr ||
23208                         error "setdirstripe failed"
23209                 $LFS setdirstripe -D -c $stripe_count \
23210                         $DIR/$tdir-s$stripe_count/qos ||
23211                         error "setdirstripe failed"
23212                 test_qos_mkdir "mkdir" $stripe_count
23213         done
23214 }
23215 run_test 413b "QoS mkdir under dir whose default LMV starting MDT offset is -1"
23216
23217 test_414() {
23218 #define OBD_FAIL_PTLRPC_BULK_ATTACH      0x521
23219         $LCTL set_param fail_loc=0x80000521
23220         dd if=/dev/zero of=$DIR/$tfile bs=2M count=1 oflag=sync
23221         rm -f $DIR/$tfile
23222 }
23223 run_test 414 "simulate ENOMEM in ptlrpc_register_bulk()"
23224
23225 test_415() {
23226         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23227         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
23228                 skip "Need server version at least 2.11.52"
23229
23230         # LU-11102
23231         local total
23232         local setattr_pid
23233         local start_time
23234         local end_time
23235         local duration
23236
23237         total=500
23238         # this test may be slow on ZFS
23239         [ "$mds1_FSTYPE" == "zfs" ] && total=100
23240
23241         # though this test is designed for striped directory, let's test normal
23242         # directory too since lock is always saved as CoS lock.
23243         test_mkdir $DIR/$tdir || error "mkdir $tdir"
23244         createmany -o $DIR/$tdir/$tfile. $total || error "createmany"
23245
23246         (
23247                 while true; do
23248                         touch $DIR/$tdir
23249                 done
23250         ) &
23251         setattr_pid=$!
23252
23253         start_time=$(date +%s)
23254         for i in $(seq $total); do
23255                 mrename $DIR/$tdir/$tfile.$i $DIR/$tdir/$tfile-new.$i \
23256                         > /dev/null
23257         done
23258         end_time=$(date +%s)
23259         duration=$((end_time - start_time))
23260
23261         kill -9 $setattr_pid
23262
23263         echo "rename $total files took $duration sec"
23264         [ $duration -lt 100 ] || error "rename took $duration sec"
23265 }
23266 run_test 415 "lock revoke is not missing"
23267
23268 test_416() {
23269         [ $MDS1_VERSION -lt $(version_code 2.11.55) ] &&
23270                 skip "Need server version at least 2.11.55"
23271
23272         # define OBD_FAIL_OSD_TXN_START    0x19a
23273         do_facet mds1 lctl set_param fail_loc=0x19a
23274
23275         lfs mkdir -c $MDSCOUNT $DIR/$tdir
23276
23277         true
23278 }
23279 run_test 416 "transaction start failure won't cause system hung"
23280
23281 cleanup_417() {
23282         trap 0
23283         do_nodes $(comma_list $(mdts_nodes)) \
23284                 "$LCTL set_param -n mdt.*MDT*.enable_dir_migration=1"
23285         do_nodes $(comma_list $(mdts_nodes)) \
23286                 "$LCTL set_param -n mdt.*MDT*.enable_remote_dir=1"
23287         do_nodes $(comma_list $(mdts_nodes)) \
23288                 "$LCTL set_param -n mdt.*MDT*.enable_striped_dir=1"
23289 }
23290
23291 test_417() {
23292         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
23293         [[ $MDS1_VERSION -lt $(version_code 2.11.56) ]] &&
23294                 skip "Need MDS version at least 2.11.56"
23295
23296         trap cleanup_417 RETURN EXIT
23297
23298         $LFS mkdir -i 1 $DIR/$tdir.1 || error "create remote dir $tdir.1 failed"
23299         do_nodes $(comma_list $(mdts_nodes)) \
23300                 "$LCTL set_param -n mdt.*MDT*.enable_dir_migration=0"
23301         $LFS migrate -m 0 $DIR/$tdir.1 &&
23302                 error "migrate dir $tdir.1 should fail"
23303
23304         do_nodes $(comma_list $(mdts_nodes)) \
23305                 "$LCTL set_param -n mdt.*MDT*.enable_remote_dir=0"
23306         $LFS mkdir -i 1 $DIR/$tdir.2 &&
23307                 error "create remote dir $tdir.2 should fail"
23308
23309         do_nodes $(comma_list $(mdts_nodes)) \
23310                 "$LCTL set_param -n mdt.*MDT*.enable_striped_dir=0"
23311         $LFS mkdir -c 2 $DIR/$tdir.3 &&
23312                 error "create striped dir $tdir.3 should fail"
23313         true
23314 }
23315 run_test 417 "disable remote dir, striped dir and dir migration"
23316
23317 # Checks that the outputs of df [-i] and lfs df [-i] match
23318 #
23319 # usage: check_lfs_df <blocks | inodes> <mountpoint>
23320 check_lfs_df() {
23321         local dir=$2
23322         local inodes
23323         local df_out
23324         local lfs_df_out
23325         local count
23326         local passed=false
23327
23328         # blocks or inodes
23329         [ "$1" == "blocks" ] && inodes= || inodes="-i"
23330
23331         for count in {1..100}; do
23332                 cancel_lru_locks
23333                 sync; sleep 0.2
23334
23335                 # read the lines of interest
23336                 df_out=($(df -P $inodes $dir | tail -n +2)) ||
23337                         error "df $inodes $dir | tail -n +2 failed"
23338                 lfs_df_out=($($LFS df $inodes $dir | grep summary:)) ||
23339                         error "lfs df $inodes $dir | grep summary: failed"
23340
23341                 # skip first substrings of each output as they are different
23342                 # "<NID>:/<fsname>" for df, "filesystem_summary:" for lfs df
23343                 # compare the two outputs
23344                 passed=true
23345                 for i in {1..5}; do
23346                         [ "${df_out[i]}" != "${lfs_df_out[i]}" ] && passed=false
23347                 done
23348                 $passed && break
23349         done
23350
23351         if ! $passed; then
23352                 df -P $inodes $dir
23353                 echo
23354                 lfs df $inodes $dir
23355                 error "df and lfs df $1 output mismatch: "      \
23356                       "df ${inodes}: ${df_out[*]}, "            \
23357                       "lfs df ${inodes}: ${lfs_df_out[*]}"
23358         fi
23359 }
23360
23361 test_418() {
23362         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23363
23364         local dir=$DIR/$tdir
23365         local numfiles=$((RANDOM % 4096 + 2))
23366         local numblocks=$((RANDOM % 256 + 1))
23367
23368         wait_delete_completed
23369         test_mkdir $dir
23370
23371         # check block output
23372         check_lfs_df blocks $dir
23373         # check inode output
23374         check_lfs_df inodes $dir
23375
23376         # create a single file and retest
23377         echo "Creating a single file and testing"
23378         createmany -o $dir/$tfile- 1 &>/dev/null ||
23379                 error "creating 1 file in $dir failed"
23380         check_lfs_df blocks $dir
23381         check_lfs_df inodes $dir
23382
23383         # create a random number of files
23384         echo "Creating $((numfiles - 1)) files and testing"
23385         createmany -o $dir/$tfile- 1 $((numfiles - 1)) &>/dev/null ||
23386                 error "creating $((numfiles - 1)) files in $dir failed"
23387
23388         # write a random number of blocks to the first test file
23389         echo "Writing $numblocks 4K blocks and testing"
23390         dd if=/dev/urandom of=$dir/${tfile}-0 bs=4K conv=fsync \
23391                 count=$numblocks &>/dev/null ||
23392                 error "dd to $dir/${tfile}-0 failed"
23393
23394         # retest
23395         check_lfs_df blocks $dir
23396         check_lfs_df inodes $dir
23397
23398         unlinkmany $dir/$tfile- $numfiles &>/dev/null ||
23399                 error "unlinking $numfiles files in $dir failed"
23400 }
23401 run_test 418 "df and lfs df outputs match"
23402
23403 test_419()
23404 {
23405         local dir=$DIR/$tdir
23406
23407         mkdir -p $dir
23408         touch $dir/file
23409
23410         cancel_lru_locks mdc
23411
23412         #OBD_FAIL_LLITE_OPEN_BY_NAME    0x1410
23413         $LCTL set_param fail_loc=0x1410
23414         cat $dir/file
23415         $LCTL set_param fail_loc=0
23416         rm -rf $dir
23417 }
23418 run_test 419 "Verify open file by name doesn't crash kernel"
23419
23420 test_420()
23421 {
23422         [[ $MDS1_VERSION -ge $(version_code 2.12.53) ]] ||
23423                 skip "Need MDS version at least 2.12.53"
23424
23425         local SAVE_UMASK=$(umask)
23426         local dir=$DIR/$tdir
23427         local uname=$(getent passwd $RUNAS_ID | cut -d: -f1)
23428
23429         mkdir -p $dir
23430         umask 0000
23431         mkdir -m03777 $dir/testdir
23432         ls -dn $dir/testdir
23433         # Need to remove trailing '.' when SELinux is enabled
23434         local dirperms=$(ls -dn $dir/testdir |
23435                          awk '{ sub(/\.$/, "", $1); print $1}')
23436         [ $dirperms == "drwxrwsrwt" ] ||
23437                 error "incorrect perms on $dir/testdir"
23438
23439         su - $uname -c "PATH=$LUSTRE/tests:\$PATH; \
23440                 openfile -f O_RDONLY:O_CREAT -m 02755 $dir/testdir/testfile"
23441         ls -n $dir/testdir/testfile
23442         local fileperms=$(ls -n $dir/testdir/testfile |
23443                           awk '{ sub(/\.$/, "", $1); print $1}')
23444         [ $fileperms == "-rwxr-xr-x" ] ||
23445                 error "incorrect perms on $dir/testdir/testfile"
23446
23447         umask $SAVE_UMASK
23448 }
23449 run_test 420 "clear SGID bit on non-directories for non-members"
23450
23451 test_421a() {
23452         local cnt
23453         local fid1
23454         local fid2
23455
23456         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
23457                 skip "Need MDS version at least 2.12.54"
23458
23459         test_mkdir $DIR/$tdir
23460         createmany -o $DIR/$tdir/f 3
23461         cnt=$(ls -1 $DIR/$tdir | wc -l)
23462         [ $cnt != 3 ] && error "unexpected #files: $cnt"
23463
23464         fid1=$(lfs path2fid $DIR/$tdir/f1)
23465         fid2=$(lfs path2fid $DIR/$tdir/f2)
23466         $LFS rmfid $DIR $fid1 $fid2 || error "rmfid failed"
23467
23468         stat $DIR/$tdir/f1 && error "f1 still visible on the client"
23469         stat $DIR/$tdir/f2 && error "f2 still visible on the client"
23470
23471         cnt=$(ls -1 $DIR/$tdir | wc -l)
23472         [ $cnt == 1 ] || error "unexpected #files after: $cnt"
23473
23474         rm -f $DIR/$tdir/f3 || error "can't remove f3"
23475         createmany -o $DIR/$tdir/f 3
23476         cnt=$(ls -1 $DIR/$tdir | wc -l)
23477         [ $cnt != 3 ] && error "unexpected #files: $cnt"
23478
23479         fid1=$(lfs path2fid $DIR/$tdir/f1)
23480         fid2=$(lfs path2fid $DIR/$tdir/f2)
23481         echo "remove using fsname $FSNAME"
23482         $LFS rmfid $FSNAME $fid1 $fid2 || error "rmfid with fsname failed"
23483
23484         cnt=$(ls -1 $DIR/$tdir | wc -l)
23485         [ $cnt == 1 ] || error "unexpected #files after: $cnt"
23486 }
23487 run_test 421a "simple rm by fid"
23488
23489 test_421b() {
23490         local cnt
23491         local FID1
23492         local FID2
23493
23494         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
23495                 skip "Need MDS version at least 2.12.54"
23496
23497         test_mkdir $DIR/$tdir
23498         createmany -o $DIR/$tdir/f 3
23499         multiop_bg_pause $DIR/$tdir/f1 o_c || error "multiop failed to start"
23500         MULTIPID=$!
23501
23502         FID1=$(lfs path2fid $DIR/$tdir/f1)
23503         FID2=$(lfs path2fid $DIR/$tdir/f2)
23504         $LFS rmfid $DIR $FID1 $FID2 && error "rmfid didn't fail"
23505
23506         kill -USR1 $MULTIPID
23507         wait
23508
23509         cnt=$(ls $DIR/$tdir | wc -l)
23510         [ $cnt == 2 ] || error "unexpected #files after: $cnt"
23511 }
23512 run_test 421b "rm by fid on open file"
23513
23514 test_421c() {
23515         local cnt
23516         local FIDS
23517
23518         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
23519                 skip "Need MDS version at least 2.12.54"
23520
23521         test_mkdir $DIR/$tdir
23522         createmany -o $DIR/$tdir/f 3
23523         touch $DIR/$tdir/$tfile
23524         createmany -l$DIR/$tdir/$tfile $DIR/$tdir/h 180
23525         cnt=$(ls -1 $DIR/$tdir | wc -l)
23526         [ $cnt != 184 ] && error "unexpected #files: $cnt"
23527
23528         FID1=$(lfs path2fid $DIR/$tdir/$tfile)
23529         $LFS rmfid $DIR $FID1 || error "rmfid failed"
23530
23531         cnt=$(ls $DIR/$tdir | wc -l)
23532         [ $cnt == 3 ] || error "unexpected #files after: $cnt"
23533 }
23534 run_test 421c "rm by fid against hardlinked files"
23535
23536 test_421d() {
23537         local cnt
23538         local FIDS
23539
23540         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
23541                 skip "Need MDS version at least 2.12.54"
23542
23543         test_mkdir $DIR/$tdir
23544         createmany -o $DIR/$tdir/f 4097
23545         cnt=$(ls -1 $DIR/$tdir | wc -l)
23546         [ $cnt != 4097 ] && error "unexpected #files: $cnt"
23547
23548         FIDS=$(lfs path2fid $DIR/$tdir/f* | sed "s/[/][^:]*://g")
23549         $LFS rmfid $DIR $FIDS || error "rmfid failed"
23550
23551         cnt=$(ls $DIR/$tdir | wc -l)
23552         rm -rf $DIR/$tdir
23553         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
23554 }
23555 run_test 421d "rmfid en masse"
23556
23557 test_421e() {
23558         local cnt
23559         local FID
23560
23561         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
23562         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
23563                 skip "Need MDS version at least 2.12.54"
23564
23565         mkdir -p $DIR/$tdir
23566         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
23567         createmany -o $DIR/$tdir/striped_dir/f 512
23568         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
23569         [ $cnt != 512 ] && error "unexpected #files: $cnt"
23570
23571         FIDS=$(lfs path2fid $DIR/$tdir/striped_dir/f* |
23572                 sed "s/[/][^:]*://g")
23573         $LFS rmfid $DIR $FIDS || error "rmfid failed"
23574
23575         cnt=$(ls $DIR/$tdir/striped_dir | wc -l)
23576         rm -rf $DIR/$tdir
23577         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
23578 }
23579 run_test 421e "rmfid in DNE"
23580
23581 test_421f() {
23582         local cnt
23583         local FID
23584
23585         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
23586                 skip "Need MDS version at least 2.12.54"
23587
23588         test_mkdir $DIR/$tdir
23589         touch $DIR/$tdir/f
23590         cnt=$(ls -1 $DIR/$tdir | wc -l)
23591         [ $cnt != 1 ] && error "unexpected #files: $cnt"
23592
23593         FID=$(lfs path2fid $DIR/$tdir/f)
23594         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail (1)"
23595         # rmfid should fail
23596         cnt=$(ls -1 $DIR/$tdir | wc -l)
23597         [ $cnt != 1 ] && error "unexpected #files after (2): $cnt"
23598
23599         chmod a+rw $DIR/$tdir
23600         ls -la $DIR/$tdir
23601         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail (2)"
23602         # rmfid should fail
23603         cnt=$(ls -1 $DIR/$tdir | wc -l)
23604         [ $cnt != 1 ] && error "unexpected #files after (3): $cnt"
23605
23606         rm -f $DIR/$tdir/f
23607         $RUNAS touch $DIR/$tdir/f
23608         FID=$(lfs path2fid $DIR/$tdir/f)
23609         echo "rmfid as root"
23610         $LFS rmfid $DIR $FID || error "rmfid as root failed"
23611         cnt=$(ls -1 $DIR/$tdir | wc -l)
23612         [ $cnt == 0 ] || error "unexpected #files after (4): $cnt"
23613
23614         rm -f $DIR/$tdir/f
23615         $RUNAS touch $DIR/$tdir/f
23616         cnt=$(ls -1 $DIR/$tdir | wc -l)
23617         [ $cnt != 1 ] && error "unexpected #files (4): $cnt"
23618         FID=$(lfs path2fid $DIR/$tdir/f)
23619         # rmfid w/o user_fid2path mount option should fail
23620         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail(3)"
23621         cnt=$(ls -1 $DIR/$tdir | wc -l)
23622         [ $cnt == 1 ] || error "unexpected #files after (5): $cnt"
23623
23624         umount_client $MOUNT || error "failed to umount client"
23625         mount_client $MOUNT "$MOUNT_OPTS,user_fid2path" ||
23626                 error "failed to mount client'"
23627
23628         $RUNAS $LFS rmfid $DIR $FID || error "rmfid failed"
23629         # rmfid should succeed
23630         cnt=$(ls -1 $DIR/$tdir | wc -l)
23631         [ $cnt == 0 ] || error "unexpected #files after (6): $cnt"
23632
23633         # rmfid shouldn't allow to remove files due to dir's permission
23634         chmod a+rwx $DIR/$tdir
23635         touch $DIR/$tdir/f
23636         ls -la $DIR/$tdir
23637         FID=$(lfs path2fid $DIR/$tdir/f)
23638         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail"
23639
23640         umount_client $MOUNT || error "failed to umount client"
23641         mount_client $MOUNT "$MOUNT_OPTS" ||
23642                 error "failed to mount client'"
23643
23644 }
23645 run_test 421f "rmfid checks permissions"
23646
23647 test_421g() {
23648         local cnt
23649         local FIDS
23650
23651         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
23652         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
23653                 skip "Need MDS version at least 2.12.54"
23654
23655         mkdir -p $DIR/$tdir
23656         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
23657         createmany -o $DIR/$tdir/striped_dir/f 512
23658         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
23659         [ $cnt != 512 ] && error "unexpected #files: $cnt"
23660
23661         FIDS=$(lfs path2fid $DIR/$tdir/striped_dir/f* |
23662                 sed "s/[/][^:]*://g")
23663
23664         rm -f $DIR/$tdir/striped_dir/f1*
23665         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
23666         removed=$((512 - cnt))
23667
23668         # few files have been just removed, so we expect
23669         # rmfid to fail on their fids
23670         errors=$($LFS rmfid $DIR $FIDS 2>&1 | wc -l)
23671         [ $removed != $errors ] && error "$errors != $removed"
23672
23673         cnt=$(ls $DIR/$tdir/striped_dir | wc -l)
23674         rm -rf $DIR/$tdir
23675         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
23676 }
23677 run_test 421g "rmfid to return errors properly"
23678
23679 test_422() {
23680         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d1
23681         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d2
23682         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d3
23683         dd if=/dev/zero of=$DIR/$tdir/d1/file1 bs=1k count=1
23684         dd if=/dev/zero of=$DIR/$tdir/d2/file1 bs=1k count=1
23685
23686         local amc=$(at_max_get client)
23687         local amo=$(at_max_get mds1)
23688         local timeout=`lctl get_param -n timeout`
23689
23690         at_max_set 0 client
23691         at_max_set 0 mds1
23692
23693 #define OBD_FAIL_PTLRPC_PAUSE_REQ        0x50a
23694         do_facet mds1 $LCTL set_param fail_loc=0x8000050a \
23695                         fail_val=$(((2*timeout + 10)*1000))
23696         touch $DIR/$tdir/d3/file &
23697         sleep 2
23698 #define OBD_FAIL_TGT_REPLY_DATA_RACE     0x722
23699         do_facet mds1 $LCTL set_param fail_loc=0x80000722 \
23700                         fail_val=$((2*timeout + 5))
23701         mv $DIR/$tdir/d1/file1 $DIR/$tdir/d1/file2 &
23702         local pid=$!
23703         sleep 1
23704         kill -9 $pid
23705         sleep $((2 * timeout))
23706         echo kill $pid
23707         kill -9 $pid
23708         lctl mark touch
23709         touch $DIR/$tdir/d2/file3
23710         touch $DIR/$tdir/d2/file4
23711         touch $DIR/$tdir/d2/file5
23712
23713         wait
23714         at_max_set $amc client
23715         at_max_set $amo mds1
23716
23717         # LU-12838 - verify the ptlrpc thread watchdog is not always throttled
23718         do_facet mds1 "dmesg | grep 'Dumping the stack trace for debugging'" ||
23719                 error "Watchdog is always throttled"
23720 }
23721 run_test 422 "kill a process with RPC in progress"
23722
23723 stat_test() {
23724     df -h $MOUNT &
23725     df -h $MOUNT &
23726     df -h $MOUNT &
23727     df -h $MOUNT &
23728     df -h $MOUNT &
23729     df -h $MOUNT &
23730 }
23731
23732 test_423() {
23733     local _stats
23734     # ensure statfs cache is expired
23735     sleep 2;
23736
23737     _stats=$(stat_test | grep $MOUNT | sort -u | wc -l)
23738     [[ ${_stats} -ne 1 ]] && error "statfs wrong"
23739
23740     return 0
23741 }
23742 run_test 423 "statfs should return a right data"
23743
23744 test_424() {
23745 #define OBD_FAIL_PTLRPC_BULK_REPLY_ATTACH      0x522 | OBD_FAIL_ONCE
23746         $LCTL set_param fail_loc=0x80000522
23747         dd if=/dev/zero of=$DIR/$tfile bs=2M count=1 oflag=sync
23748         rm -f $DIR/$tfile
23749 }
23750 run_test 424 "simulate ENOMEM in ptl_send_rpc bulk reply ME attach"
23751
23752 test_425() {
23753         test_mkdir -c -1 $DIR/$tdir
23754         $LFS setstripe -c -1 $DIR/$tdir
23755
23756         lru_resize_disable "" 100
23757         stack_trap "lru_resize_enable" EXIT
23758
23759         sleep 5
23760
23761         for i in $(seq $((MDSCOUNT * 125))); do
23762                 local t=$DIR/$tdir/$tfile_$i
23763
23764                 dd if=/dev/zero of=$t bs=4K count=1 > /dev/null 2>&1 ||
23765                         error_noexit "Create file $t"
23766         done
23767         stack_trap "rm -rf $DIR/$tdir" EXIT
23768
23769         for oscparam in $($LCTL list_param ldlm.namespaces.*osc-[-0-9a-f]*); do
23770                 local lru_size=$($LCTL get_param -n $oscparam.lru_size)
23771                 local lock_count=$($LCTL get_param -n $oscparam.lock_count)
23772
23773                 [ $lock_count -le $lru_size ] ||
23774                         error "osc lock count $lock_count > lru size $lru_size"
23775         done
23776
23777         for mdcparam in $($LCTL list_param ldlm.namespaces.*mdc-*); do
23778                 local lru_size=$($LCTL get_param -n $mdcparam.lru_size)
23779                 local lock_count=$($LCTL get_param -n $mdcparam.lock_count)
23780
23781                 [ $lock_count -le $lru_size ] ||
23782                         error "mdc lock count $lock_count > lru size $lru_size"
23783         done
23784 }
23785 run_test 425 "lock count should not exceed lru size"
23786
23787 test_426() {
23788         splice-test -r $DIR/$tfile
23789         splice-test -rd $DIR/$tfile
23790         splice-test $DIR/$tfile
23791         splice-test -d $DIR/$tfile
23792 }
23793 run_test 426 "splice test on Lustre"
23794
23795 lseek_test_430() {
23796         local offset
23797         local file=$1
23798
23799         # data at [200K, 400K)
23800         dd if=/dev/urandom of=$file bs=256K count=1 seek=1 ||
23801                 error "256K->512K dd fails"
23802         # data at [2M, 3M)
23803         dd if=/dev/urandom of=$file bs=1M count=1 seek=2 ||
23804                 error "2M->3M dd fails"
23805         # data at [4M, 5M)
23806         dd if=/dev/urandom of=$file bs=1M count=1 seek=4 ||
23807                 error "4M->5M dd fails"
23808         echo "Data at 256K...512K, 2M...3M and 4M...5M"
23809         # start at first component hole #1
23810         printf "Seeking hole from 1000 ... "
23811         offset=$(lseek_test -l 1000 $file)
23812         echo $offset
23813         [[ $offset == 1000 ]] || error "offset $offset != 1000"
23814         printf "Seeking data from 1000 ... "
23815         offset=$(lseek_test -d 1000 $file)
23816         echo $offset
23817         [[ $offset == 262144 ]] || error "offset $offset != 262144"
23818
23819         # start at first component data block
23820         printf "Seeking hole from 300000 ... "
23821         offset=$(lseek_test -l 300000 $file)
23822         echo $offset
23823         [[ $offset == 524288 ]] || error "offset $offset != 524288"
23824         printf "Seeking data from 300000 ... "
23825         offset=$(lseek_test -d 300000 $file)
23826         echo $offset
23827         [[ $offset == 300000 ]] || error "offset $offset != 300000"
23828
23829         # start at the first component but beyond end of object size
23830         printf "Seeking hole from 1000000 ... "
23831         offset=$(lseek_test -l 1000000 $file)
23832         echo $offset
23833         [[ $offset == 1000000 ]] || error "offset $offset != 1000000"
23834         printf "Seeking data from 1000000 ... "
23835         offset=$(lseek_test -d 1000000 $file)
23836         echo $offset
23837         [[ $offset == 2097152 ]] || error "offset $offset != 2097152"
23838
23839         # start at second component stripe 2 (empty file)
23840         printf "Seeking hole from 1500000 ... "
23841         offset=$(lseek_test -l 1500000 $file)
23842         echo $offset
23843         [[ $offset == 1500000 ]] || error "offset $offset != 1500000"
23844         printf "Seeking data from 1500000 ... "
23845         offset=$(lseek_test -d 1500000 $file)
23846         echo $offset
23847         [[ $offset == 2097152 ]] || error "offset $offset != 2097152"
23848
23849         # start at second component stripe 1 (all data)
23850         printf "Seeking hole from 3000000 ... "
23851         offset=$(lseek_test -l 3000000 $file)
23852         echo $offset
23853         [[ $offset == 3145728 ]] || error "offset $offset != 3145728"
23854         printf "Seeking data from 3000000 ... "
23855         offset=$(lseek_test -d 3000000 $file)
23856         echo $offset
23857         [[ $offset == 3000000 ]] || error "offset $offset != 3000000"
23858
23859         dd if=/dev/urandom of=$file bs=640K count=1 seek=1 ||
23860                 error "2nd dd fails"
23861         echo "Add data block at 640K...1280K"
23862
23863         # start at before new data block, in hole
23864         printf "Seeking hole from 600000 ... "
23865         offset=$(lseek_test -l 600000 $file)
23866         echo $offset
23867         [[ $offset == 600000 ]] || error "offset $offset != 600000"
23868         printf "Seeking data from 600000 ... "
23869         offset=$(lseek_test -d 600000 $file)
23870         echo $offset
23871         [[ $offset == 655360 ]] || error "offset $offset != 655360"
23872
23873         # start at the first component new data block
23874         printf "Seeking hole from 1000000 ... "
23875         offset=$(lseek_test -l 1000000 $file)
23876         echo $offset
23877         [[ $offset == 1310720 ]] || error "offset $offset != 1310720"
23878         printf "Seeking data from 1000000 ... "
23879         offset=$(lseek_test -d 1000000 $file)
23880         echo $offset
23881         [[ $offset == 1000000 ]] || error "offset $offset != 1000000"
23882
23883         # start at second component stripe 2, new data
23884         printf "Seeking hole from 1200000 ... "
23885         offset=$(lseek_test -l 1200000 $file)
23886         echo $offset
23887         [[ $offset == 1310720 ]] || error "offset $offset != 1310720"
23888         printf "Seeking data from 1200000 ... "
23889         offset=$(lseek_test -d 1200000 $file)
23890         echo $offset
23891         [[ $offset == 1200000 ]] || error "offset $offset != 1200000"
23892
23893         # start beyond file end
23894         printf "Using offset > filesize ... "
23895         lseek_test -l 4000000 $file && error "lseek should fail"
23896         printf "Using offset > filesize ... "
23897         lseek_test -d 4000000 $file && error "lseek should fail"
23898
23899         printf "Done\n\n"
23900 }
23901
23902 test_430a() {
23903         $LCTL get_param mdc.*.import | grep -q 'connect_flags:.*seek' ||
23904                 skip "MDT does not support SEEK_HOLE"
23905
23906         $LCTL get_param osc.*.import | grep -q 'connect_flags:.*seek' ||
23907                 skip "OST does not support SEEK_HOLE"
23908
23909         local file=$DIR/$tdir/$tfile
23910
23911         mkdir -p $DIR/$tdir
23912
23913         $LFS setstripe -E 1M -L mdt -E eof -c2 $file
23914         # OST stripe #1 will have continuous data at [1M, 3M)
23915         # OST stripe #2 is empty
23916         echo "Component #1: 1M DoM, component #2: EOF, 2 stripes 1M"
23917         lseek_test_430 $file
23918         rm $file
23919         $LFS setstripe -E 1M -c2 -S 64K -E 10M -c2 -S 1M $file
23920         echo "Component #1: 1M, 2 stripes 64K, component #2: EOF, 2 stripes 1M"
23921         lseek_test_430 $file
23922         rm $file
23923         $LFS setstripe -c2 -S 512K $file
23924         echo "Two stripes, stripe size 512K"
23925         lseek_test_430 $file
23926         rm $file
23927         # FLR with stale mirror
23928         $LFS setstripe -N -E 512K -c1 -S 64K -E eof -c2 -S 512K \
23929                        -N -c2 -S 1M $file
23930         echo "Mirrored file:"
23931         echo "Component #1: 512K, stripe 64K, component #2: EOF, 2 stripes 512K"
23932         echo "Plain 2 stripes 1M"
23933         lseek_test_430 $file
23934         rm $file
23935 }
23936 run_test 430a "lseek: SEEK_DATA/SEEK_HOLE basic functionality"
23937
23938 test_430b() {
23939         $LCTL get_param osc.*.import | grep -q 'connect_flags:.*seek' ||
23940                 skip "OST does not support SEEK_HOLE"
23941
23942         local offset
23943         local file=$DIR/$tdir/$tfile
23944
23945         mkdir -p $DIR/$tdir
23946         # Empty layout lseek should fail
23947         $MCREATE $file
23948         # seek from 0
23949         printf "Seeking hole from 0 ... "
23950         lseek_test -l 0 $file && error "lseek should fail"
23951         printf "Seeking data from 0 ... "
23952         lseek_test -d 0 $file && error "lseek should fail"
23953         rm $file
23954
23955         # 1M-hole file
23956         $LFS setstripe -E 1M -c2 -E eof $file
23957         $TRUNCATE $file 1048576
23958         printf "Seeking hole from 1000000 ... "
23959         offset=$(lseek_test -l 1000000 $file)
23960         echo $offset
23961         [[ $offset == 1000000 ]] || error "offset $offset != 1000000"
23962         printf "Seeking data from 1000000 ... "
23963         lseek_test -d 1000000 $file && error "lseek should fail"
23964         rm $file
23965
23966         # full component followed by non-inited one
23967         $LFS setstripe -E 1M -c2 -E eof $file
23968         dd if=/dev/urandom of=$file bs=1M count=1
23969         printf "Seeking hole from 1000000 ... "
23970         offset=$(lseek_test -l 1000000 $file)
23971         echo $offset
23972         [[ $offset == 1048576 ]] || error "offset $offset != 1048576"
23973         printf "Seeking hole from 1048576 ... "
23974         lseek_test -l 1048576 $file && error "lseek should fail"
23975         # init second component and truncate back
23976         echo "123" >> $file
23977         $TRUNCATE $file 1048576
23978         printf "Seeking hole from 1000000 ... "
23979         offset=$(lseek_test -l 1000000 $file)
23980         echo $offset
23981         [[ $offset == 1048576 ]] || error "offset $offset != 1048576"
23982         printf "Seeking hole from 1048576 ... "
23983         lseek_test -l 1048576 $file && error "lseek should fail"
23984         # boundary checks for big values
23985         dd if=/dev/urandom of=$file.10g bs=1 count=1 seek=10G
23986         offset=$(lseek_test -d 0 $file.10g)
23987         [[ $offset == 10737418240 ]] || error "offset $offset != 10737418240"
23988         dd if=/dev/urandom of=$file.100g bs=1 count=1 seek=100G
23989         offset=$(lseek_test -d 0 $file.100g)
23990         [[ $offset == 107374182400 ]] || error "offset $offset != 107374182400"
23991         return 0
23992 }
23993 run_test 430b "lseek: SEEK_DATA/SEEK_HOLE special cases"
23994
23995 test_430c() {
23996         $LCTL get_param osc.*.import | grep -q 'connect_flags:.*seek' ||
23997                 skip "OST does not support SEEK_HOLE"
23998
23999         local file=$DIR/$tdir/$tfile
24000         local start
24001
24002         mkdir -p $DIR/$tdir
24003         dd if=/dev/urandom of=$file bs=1k count=1 seek=5M
24004
24005         # cp version 8.33+ prefers lseek over fiemap
24006         if [[ $(cp --version | head -n1 | sed "s/[^0-9]//g") -ge 833 ]]; then
24007                 start=$SECONDS
24008                 time cp $file /dev/null
24009                 (( SECONDS - start < 5 )) ||
24010                         error "cp: too long runtime $((SECONDS - start))"
24011
24012         fi
24013         # tar version 1.29+ supports SEEK_HOLE/DATA
24014         if [[ $(tar --version | head -n1 | sed "s/[^0-9]//g") -ge 129 ]]; then
24015                 start=$SECONDS
24016                 time tar cS $file - | cat > /dev/null
24017                 (( SECONDS - start < 5 )) ||
24018                         error "tar: too long runtime $((SECONDS - start))"
24019         fi
24020 }
24021 run_test 430c "lseek: external tools check"
24022
24023 prep_801() {
24024         [[ $MDS1_VERSION -lt $(version_code 2.9.55) ]] ||
24025         [[ $OST1_VERSION -lt $(version_code 2.9.55) ]] &&
24026                 skip "Need server version at least 2.9.55"
24027
24028         start_full_debug_logging
24029 }
24030
24031 post_801() {
24032         stop_full_debug_logging
24033 }
24034
24035 barrier_stat() {
24036         if [ $MGS_VERSION -le $(version_code 2.10.0) ]; then
24037                 local st=$(do_facet mgs $LCTL barrier_stat $FSNAME |
24038                            awk '/The barrier for/ { print $7 }')
24039                 echo $st
24040         else
24041                 local st=$(do_facet mgs $LCTL barrier_stat -s $FSNAME)
24042                 echo \'$st\'
24043         fi
24044 }
24045
24046 barrier_expired() {
24047         local expired
24048
24049         if [ $MGS_VERSION -le $(version_code 2.10.0) ]; then
24050                 expired=$(do_facet mgs $LCTL barrier_stat $FSNAME |
24051                           awk '/will be expired/ { print $7 }')
24052         else
24053                 expired=$(do_facet mgs $LCTL barrier_stat -t $FSNAME)
24054         fi
24055
24056         echo $expired
24057 }
24058
24059 test_801a() {
24060         prep_801
24061
24062         echo "Start barrier_freeze at: $(date)"
24063         #define OBD_FAIL_BARRIER_DELAY          0x2202
24064         do_facet mgs $LCTL set_param fail_val=5 fail_loc=0x2202
24065         # Do not reduce barrier time - See LU-11873
24066         do_facet mgs $LCTL barrier_freeze $FSNAME 20 &
24067
24068         sleep 2
24069         local b_status=$(barrier_stat)
24070         echo "Got barrier status at: $(date)"
24071         [ "$b_status" = "'freezing_p1'" ] ||
24072                 error "(1) unexpected barrier status $b_status"
24073
24074         do_facet mgs $LCTL set_param fail_val=0 fail_loc=0
24075         wait
24076         b_status=$(barrier_stat)
24077         [ "$b_status" = "'frozen'" ] ||
24078                 error "(2) unexpected barrier status $b_status"
24079
24080         local expired=$(barrier_expired)
24081         echo "sleep $((expired + 3)) seconds, then the barrier will be expired"
24082         sleep $((expired + 3))
24083
24084         b_status=$(barrier_stat)
24085         [ "$b_status" = "'expired'" ] ||
24086                 error "(3) unexpected barrier status $b_status"
24087
24088         # Do not reduce barrier time - See LU-11873
24089         do_facet mgs $LCTL barrier_freeze $FSNAME 20 ||
24090                 error "(4) fail to freeze barrier"
24091
24092         b_status=$(barrier_stat)
24093         [ "$b_status" = "'frozen'" ] ||
24094                 error "(5) unexpected barrier status $b_status"
24095
24096         echo "Start barrier_thaw at: $(date)"
24097         #define OBD_FAIL_BARRIER_DELAY          0x2202
24098         do_facet mgs $LCTL set_param fail_val=5 fail_loc=0x2202
24099         do_facet mgs $LCTL barrier_thaw $FSNAME &
24100
24101         sleep 2
24102         b_status=$(barrier_stat)
24103         echo "Got barrier status at: $(date)"
24104         [ "$b_status" = "'thawing'" ] ||
24105                 error "(6) unexpected barrier status $b_status"
24106
24107         do_facet mgs $LCTL set_param fail_val=0 fail_loc=0
24108         wait
24109         b_status=$(barrier_stat)
24110         [ "$b_status" = "'thawed'" ] ||
24111                 error "(7) unexpected barrier status $b_status"
24112
24113         #define OBD_FAIL_BARRIER_FAILURE        0x2203
24114         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2203
24115         do_facet mgs $LCTL barrier_freeze $FSNAME
24116
24117         b_status=$(barrier_stat)
24118         [ "$b_status" = "'failed'" ] ||
24119                 error "(8) unexpected barrier status $b_status"
24120
24121         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
24122         do_facet mgs $LCTL barrier_thaw $FSNAME
24123
24124         post_801
24125 }
24126 run_test 801a "write barrier user interfaces and stat machine"
24127
24128 test_801b() {
24129         prep_801
24130
24131         mkdir $DIR/$tdir || error "(1) fail to mkdir"
24132         createmany -d $DIR/$tdir/d 6 || "(2) fail to mkdir"
24133         touch $DIR/$tdir/d2/f10 || error "(3) fail to touch"
24134         touch $DIR/$tdir/d3/f11 || error "(4) fail to touch"
24135         touch $DIR/$tdir/d4/f12 || error "(5) fail to touch"
24136
24137         cancel_lru_locks mdc
24138
24139         # 180 seconds should be long enough
24140         do_facet mgs $LCTL barrier_freeze $FSNAME 180
24141
24142         local b_status=$(barrier_stat)
24143         [ "$b_status" = "'frozen'" ] ||
24144                 error "(6) unexpected barrier status $b_status"
24145
24146         mkdir $DIR/$tdir/d0/d10 &
24147         mkdir_pid=$!
24148
24149         touch $DIR/$tdir/d1/f13 &
24150         touch_pid=$!
24151
24152         ln $DIR/$tdir/d2/f10 $DIR/$tdir/d2/f14 &
24153         ln_pid=$!
24154
24155         mv $DIR/$tdir/d3/f11 $DIR/$tdir/d3/f15 &
24156         mv_pid=$!
24157
24158         rm -f $DIR/$tdir/d4/f12 &
24159         rm_pid=$!
24160
24161         stat $DIR/$tdir/d5 || error "(7) stat should succeed"
24162
24163         # To guarantee taht the 'stat' is not blocked
24164         b_status=$(barrier_stat)
24165         [ "$b_status" = "'frozen'" ] ||
24166                 error "(8) unexpected barrier status $b_status"
24167
24168         # let above commands to run at background
24169         sleep 5
24170
24171         ps -p $mkdir_pid || error "(9) mkdir should be blocked"
24172         ps -p $touch_pid || error "(10) touch should be blocked"
24173         ps -p $ln_pid || error "(11) link should be blocked"
24174         ps -p $mv_pid || error "(12) rename should be blocked"
24175         ps -p $rm_pid || error "(13) unlink should be blocked"
24176
24177         b_status=$(barrier_stat)
24178         [ "$b_status" = "'frozen'" ] ||
24179                 error "(14) unexpected barrier status $b_status"
24180
24181         do_facet mgs $LCTL barrier_thaw $FSNAME
24182         b_status=$(barrier_stat)
24183         [ "$b_status" = "'thawed'" ] ||
24184                 error "(15) unexpected barrier status $b_status"
24185
24186         wait $mkdir_pid || error "(16) mkdir should succeed"
24187         wait $touch_pid || error "(17) touch should succeed"
24188         wait $ln_pid || error "(18) link should succeed"
24189         wait $mv_pid || error "(19) rename should succeed"
24190         wait $rm_pid || error "(20) unlink should succeed"
24191
24192         post_801
24193 }
24194 run_test 801b "modification will be blocked by write barrier"
24195
24196 test_801c() {
24197         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
24198
24199         prep_801
24200
24201         stop mds2 || error "(1) Fail to stop mds2"
24202
24203         do_facet mgs $LCTL barrier_freeze $FSNAME 30
24204
24205         local b_status=$(barrier_stat)
24206         [ "$b_status" = "'expired'" ] || [ "$b_status" = "'failed'" ] || {
24207                 do_facet mgs $LCTL barrier_thaw $FSNAME
24208                 error "(2) unexpected barrier status $b_status"
24209         }
24210
24211         do_facet mgs $LCTL barrier_rescan $FSNAME ||
24212                 error "(3) Fail to rescan barrier bitmap"
24213
24214         # Do not reduce barrier time - See LU-11873
24215         do_facet mgs $LCTL barrier_freeze $FSNAME 20
24216
24217         b_status=$(barrier_stat)
24218         [ "$b_status" = "'frozen'" ] ||
24219                 error "(4) unexpected barrier status $b_status"
24220
24221         do_facet mgs $LCTL barrier_thaw $FSNAME
24222         b_status=$(barrier_stat)
24223         [ "$b_status" = "'thawed'" ] ||
24224                 error "(5) unexpected barrier status $b_status"
24225
24226         local devname=$(mdsdevname 2)
24227
24228         start mds2 $devname $MDS_MOUNT_OPTS || error "(6) Fail to start mds2"
24229
24230         do_facet mgs $LCTL barrier_rescan $FSNAME ||
24231                 error "(7) Fail to rescan barrier bitmap"
24232
24233         post_801
24234 }
24235 run_test 801c "rescan barrier bitmap"
24236
24237 saved_MGS_MOUNT_OPTS=$MGS_MOUNT_OPTS
24238 saved_MDS_MOUNT_OPTS=$MDS_MOUNT_OPTS
24239 saved_OST_MOUNT_OPTS=$OST_MOUNT_OPTS
24240 saved_MOUNT_OPTS=$MOUNT_OPTS
24241
24242 cleanup_802a() {
24243         trap 0
24244
24245         stopall
24246         MGS_MOUNT_OPTS=$saved_MGS_MOUNT_OPTS
24247         MDS_MOUNT_OPTS=$saved_MDS_MOUNT_OPTS
24248         OST_MOUNT_OPTS=$saved_OST_MOUNT_OPTS
24249         MOUNT_OPTS=$saved_MOUNT_OPTS
24250         setupall
24251 }
24252
24253 test_802a() {
24254         [[ $mds1_FSTYPE = zfs ]] || skip "ZFS specific test"
24255         [[ $MDS1_VERSION -lt $(version_code 2.9.55) ]] ||
24256         [[ $OST1_VERSION -lt $(version_code 2.9.55) ]] &&
24257                 skip "Need server version at least 2.9.55"
24258
24259         [[ $ENABLE_QUOTA ]] && skip "Quota enabled for read-only test"
24260
24261         mkdir $DIR/$tdir || error "(1) fail to mkdir"
24262
24263         cp $LUSTRE/tests/test-framework.sh $DIR/$tdir/ ||
24264                 error "(2) Fail to copy"
24265
24266         trap cleanup_802a EXIT
24267
24268         # sync by force before remount as readonly
24269         sync; sync_all_data; sleep 3; sync_all_data
24270
24271         stopall
24272
24273         MGS_MOUNT_OPTS=$(csa_add "$MGS_MOUNT_OPTS" -o rdonly_dev)
24274         MDS_MOUNT_OPTS=$(csa_add "$MDS_MOUNT_OPTS" -o rdonly_dev)
24275         OST_MOUNT_OPTS=$(csa_add "$OST_MOUNT_OPTS" -o rdonly_dev)
24276
24277         echo "Mount the server as read only"
24278         setupall server_only || error "(3) Fail to start servers"
24279
24280         echo "Mount client without ro should fail"
24281         mount_client $MOUNT &&
24282                 error "(4) Mount client without 'ro' should fail"
24283
24284         echo "Mount client with ro should succeed"
24285         MOUNT_OPTS=$(csa_add "$MOUNT_OPTS" -o ro)
24286         mount_client $MOUNT ||
24287                 error "(5) Mount client with 'ro' should succeed"
24288
24289         echo "Modify should be refused"
24290         touch $DIR/$tdir/guard && error "(6) Touch should fail under ro mode"
24291
24292         echo "Read should be allowed"
24293         diff $LUSTRE/tests/test-framework.sh $DIR/$tdir/test-framework.sh ||
24294                 error "(7) Read should succeed under ro mode"
24295
24296         cleanup_802a
24297 }
24298 run_test 802a "simulate readonly device"
24299
24300 test_802b() {
24301         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24302         remote_mds_nodsh && skip "remote MDS with nodsh"
24303
24304         do_facet $SINGLEMDS $LCTL get_param mdt.*.readonly ||
24305                 skip "readonly option not available"
24306
24307         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "(1) fail to mkdir"
24308
24309         cp $LUSTRE/tests/test-framework.sh $DIR/$tdir/ ||
24310                 error "(2) Fail to copy"
24311
24312         # write back all cached data before setting MDT to readonly
24313         cancel_lru_locks
24314         sync_all_data
24315
24316         do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=1
24317         stack_trap "do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=0" EXIT
24318
24319         echo "Modify should be refused"
24320         touch $DIR/$tdir/guard && error "(6) Touch should fail under ro mode"
24321
24322         echo "Read should be allowed"
24323         diff $LUSTRE/tests/test-framework.sh $DIR/$tdir/test-framework.sh ||
24324                 error "(7) Read should succeed under ro mode"
24325
24326         # disable readonly
24327         do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=0
24328 }
24329 run_test 802b "be able to set MDTs to readonly"
24330
24331 test_803a() {
24332         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
24333         [ $MDS1_VERSION -lt $(version_code 2.10.54) ] &&
24334                 skip "MDS needs to be newer than 2.10.54"
24335
24336         mkdir -p $DIR/$tdir
24337         # Create some objects on all MDTs to trigger related logs objects
24338         for idx in $(seq $MDSCOUNT); do
24339                 $LFS mkdir -c $MDSCOUNT -i $((idx % $MDSCOUNT)) \
24340                         $DIR/$tdir/dir${idx} ||
24341                         error "Fail to create $DIR/$tdir/dir${idx}"
24342         done
24343
24344         sync; sleep 3
24345         wait_delete_completed # ensure old test cleanups are finished
24346         echo "before create:"
24347         $LFS df -i $MOUNT
24348         local before_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
24349
24350         for i in {1..10}; do
24351                 $LFS mkdir -c 1 -i 1 $DIR/$tdir/foo$i ||
24352                         error "Fail to create $DIR/$tdir/foo$i"
24353         done
24354
24355         sync; sleep 3
24356         echo "after create:"
24357         $LFS df -i $MOUNT
24358         local after_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
24359
24360         # allow for an llog to be cleaned up during the test
24361         [ $after_used -ge $((before_used + 10 - 1)) ] ||
24362                 error "before ($before_used) + 10 > after ($after_used)"
24363
24364         for i in {1..10}; do
24365                 rm -rf $DIR/$tdir/foo$i ||
24366                         error "Fail to remove $DIR/$tdir/foo$i"
24367         done
24368
24369         sleep 3 # avoid MDT return cached statfs
24370         wait_delete_completed
24371         echo "after unlink:"
24372         $LFS df -i $MOUNT
24373         after_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
24374
24375         # allow for an llog to be created during the test
24376         [ $after_used -le $((before_used + 1)) ] ||
24377                 error "after ($after_used) > before ($before_used) + 1"
24378 }
24379 run_test 803a "verify agent object for remote object"
24380
24381 test_803b() {
24382         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
24383         [ $MDS1_VERSION -lt $(version_code 2.13.56) ] &&
24384                 skip "MDS needs to be newer than 2.13.56"
24385         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24386
24387         for i in $(seq 0 $((MDSCOUNT - 1))); do
24388                 $LFS mkdir -i $i $DIR/$tdir.$i || error "mkdir $tdir.$i"
24389         done
24390
24391         local before=0
24392         local after=0
24393
24394         local tmp
24395
24396         stat $DIR/$tdir.* >/dev/null || error "stat $tdir.*"
24397         for i in $(seq 0 $((MDSCOUNT - 1))); do
24398                 tmp=$(do_facet mds$i $LCTL get_param mdt.*-MDT000$i.md_stats |
24399                         awk '/getattr/ { print $2 }')
24400                 before=$((before + tmp))
24401         done
24402         stat $DIR/$tdir.* >/dev/null || error "stat $tdir.*"
24403         for i in $(seq 0 $((MDSCOUNT - 1))); do
24404                 tmp=$(do_facet mds$i $LCTL get_param mdt.*-MDT000$i.md_stats |
24405                         awk '/getattr/ { print $2 }')
24406                 after=$((after + tmp))
24407         done
24408
24409         [ $before -eq $after ] || error "getattr count $before != $after"
24410 }
24411 run_test 803b "remote object can getattr from cache"
24412
24413 test_804() {
24414         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
24415         [ $MDS1_VERSION -lt $(version_code 2.10.54) ] &&
24416                 skip "MDS needs to be newer than 2.10.54"
24417         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
24418
24419         mkdir -p $DIR/$tdir
24420         $LFS mkdir -c 1 -i 1 $DIR/$tdir/dir0 ||
24421                 error "Fail to create $DIR/$tdir/dir0"
24422
24423         local fid=$($LFS path2fid $DIR/$tdir/dir0)
24424         local dev=$(mdsdevname 2)
24425
24426         do_facet mds2 "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
24427                 grep ${fid} || error "NOT found agent entry for dir0"
24428
24429         $LFS mkdir -c $MDSCOUNT -i 0 $DIR/$tdir/dir1 ||
24430                 error "Fail to create $DIR/$tdir/dir1"
24431
24432         touch $DIR/$tdir/dir1/foo0 ||
24433                 error "Fail to create $DIR/$tdir/dir1/foo0"
24434         fid=$($LFS path2fid $DIR/$tdir/dir1/foo0)
24435         local rc=0
24436
24437         for idx in $(seq $MDSCOUNT); do
24438                 dev=$(mdsdevname $idx)
24439                 do_facet mds${idx} \
24440                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
24441                         grep ${fid} && rc=$idx
24442         done
24443
24444         mv $DIR/$tdir/dir1/foo0 $DIR/$tdir/dir1/foo1 ||
24445                 error "Fail to rename foo0 to foo1"
24446         if [ $rc -eq 0 ]; then
24447                 for idx in $(seq $MDSCOUNT); do
24448                         dev=$(mdsdevname $idx)
24449                         do_facet mds${idx} \
24450                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
24451                         grep ${fid} && rc=$idx
24452                 done
24453         fi
24454
24455         mv $DIR/$tdir/dir1/foo1 $DIR/$tdir/dir1/foo2 ||
24456                 error "Fail to rename foo1 to foo2"
24457         if [ $rc -eq 0 ]; then
24458                 for idx in $(seq $MDSCOUNT); do
24459                         dev=$(mdsdevname $idx)
24460                         do_facet mds${idx} \
24461                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
24462                         grep ${fid} && rc=$idx
24463                 done
24464         fi
24465
24466         [ $rc -ne 0 ] || error "NOT found agent entry for foo"
24467
24468         ln $DIR/$tdir/dir1/foo2 $DIR/$tdir/dir0/guard ||
24469                 error "Fail to link to $DIR/$tdir/dir1/foo2"
24470         mv $DIR/$tdir/dir1/foo2 $DIR/$tdir/dir1/foo0 ||
24471                 error "Fail to rename foo2 to foo0"
24472         unlink $DIR/$tdir/dir1/foo0 ||
24473                 error "Fail to unlink $DIR/$tdir/dir1/foo0"
24474         rm -rf $DIR/$tdir/dir0 ||
24475                 error "Fail to rm $DIR/$tdir/dir0"
24476
24477         for idx in $(seq $MDSCOUNT); do
24478                 dev=$(mdsdevname $idx)
24479                 rc=0
24480
24481                 stop mds${idx}
24482                 run_e2fsck $(facet_active_host mds$idx) $dev -n ||
24483                         rc=$?
24484                 start mds${idx} $dev $MDS_MOUNT_OPTS ||
24485                         error "mount mds$idx failed"
24486                 df $MOUNT > /dev/null 2>&1
24487
24488                 # e2fsck should not return error
24489                 [ $rc -eq 0 ] ||
24490                         error "e2fsck detected error on MDT${idx}: rc=$rc"
24491         done
24492 }
24493 run_test 804 "verify agent entry for remote entry"
24494
24495 cleanup_805() {
24496         do_facet $SINGLEMDS zfs set quota=$old $fsset
24497         unlinkmany $DIR/$tdir/f- 1000000
24498         trap 0
24499 }
24500
24501 test_805() {
24502         local zfs_version=$(do_facet mds1 cat /sys/module/zfs/version)
24503         [ "$mds1_FSTYPE" != "zfs" ] && skip "ZFS specific test"
24504         [ $(version_code $zfs_version) -lt $(version_code 0.7.2) ] &&
24505                 skip "netfree not implemented before 0.7"
24506         [[ $MDS1_VERSION -ge $(version_code 2.10.57) ]] ||
24507                 skip "Need MDS version at least 2.10.57"
24508
24509         local fsset
24510         local freekb
24511         local usedkb
24512         local old
24513         local quota
24514         local pref="osd-zfs.$FSNAME-MDT0000."
24515
24516         # limit available space on MDS dataset to meet nospace issue
24517         # quickly. then ZFS 0.7.2 can use reserved space if asked
24518         # properly (using netfree flag in osd_declare_destroy()
24519         fsset=$(do_facet $SINGLEMDS lctl get_param -n $pref.mntdev)
24520         old=$(do_facet $SINGLEMDS zfs get -H quota $fsset | \
24521                 gawk '{print $3}')
24522         freekb=$(do_facet $SINGLEMDS lctl get_param -n $pref.kbytesfree)
24523         usedkb=$(do_facet $SINGLEMDS lctl get_param -n $pref.kbytestotal)
24524         let "usedkb=usedkb-freekb"
24525         let "freekb=freekb/2"
24526         if let "freekb > 5000"; then
24527                 let "freekb=5000"
24528         fi
24529         do_facet $SINGLEMDS zfs set quota=$(((usedkb+freekb)*1024)) $fsset
24530         trap cleanup_805 EXIT
24531         mkdir $DIR/$tdir
24532         $LFS setstripe -E 1M -c2 -E 4M -c2 -E -1 -c2 $DIR/$tdir ||
24533                 error "Can't set PFL layout"
24534         createmany -m $DIR/$tdir/f- 1000000 && error "ENOSPC wasn't met"
24535         rm -rf $DIR/$tdir || error "not able to remove"
24536         do_facet $SINGLEMDS zfs set quota=$old $fsset
24537         trap 0
24538 }
24539 run_test 805 "ZFS can remove from full fs"
24540
24541 # Size-on-MDS test
24542 check_lsom_data()
24543 {
24544         local file=$1
24545         local size=$($LFS getsom -s $file)
24546         local expect=$(stat -c %s $file)
24547
24548         [[ $size == $expect ]] ||
24549                 error "$file expected size: $expect, got: $size"
24550
24551         local blocks=$($LFS getsom -b $file)
24552         expect=$(stat -c %b $file)
24553         [[ $blocks == $expect ]] ||
24554                 error "$file expected blocks: $expect, got: $blocks"
24555 }
24556
24557 check_lsom_size()
24558 {
24559         local size=$($LFS getsom -s $1)
24560         local expect=$2
24561
24562         [[ $size == $expect ]] ||
24563                 error "$file expected size: $expect, got: $size"
24564 }
24565
24566 test_806() {
24567         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
24568                 skip "Need MDS version at least 2.11.52"
24569
24570         local bs=1048576
24571
24572         touch $DIR/$tfile || error "touch $tfile failed"
24573
24574         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
24575         save_lustre_params client "llite.*.xattr_cache" > $save
24576         lctl set_param llite.*.xattr_cache=0
24577         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
24578
24579         # single-threaded write
24580         echo "Test SOM for single-threaded write"
24581         dd if=/dev/zero of=$DIR/$tfile bs=$bs count=1 ||
24582                 error "write $tfile failed"
24583         check_lsom_size $DIR/$tfile $bs
24584
24585         local num=32
24586         local size=$(($num * $bs))
24587         local offset=0
24588         local i
24589
24590         echo "Test SOM for single client multi-threaded($num) write"
24591         $TRUNCATE $DIR/$tfile 0
24592         for ((i = 0; i < $num; i++)); do
24593                 $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
24594                 local pids[$i]=$!
24595                 offset=$((offset + $bs))
24596         done
24597         for (( i=0; i < $num; i++ )); do
24598                 wait ${pids[$i]}
24599         done
24600         check_lsom_size $DIR/$tfile $size
24601
24602         $TRUNCATE $DIR/$tfile 0
24603         for ((i = 0; i < $num; i++)); do
24604                 offset=$((offset - $bs))
24605                 $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
24606                 local pids[$i]=$!
24607         done
24608         for (( i=0; i < $num; i++ )); do
24609                 wait ${pids[$i]}
24610         done
24611         check_lsom_size $DIR/$tfile $size
24612
24613         # multi-client writes
24614         num=$(get_node_count ${CLIENTS//,/ })
24615         size=$(($num * $bs))
24616         offset=0
24617         i=0
24618
24619         echo "Test SOM for multi-client ($num) writes"
24620         $TRUNCATE $DIR/$tfile 0
24621         for client in ${CLIENTS//,/ }; do
24622                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
24623                 local pids[$i]=$!
24624                 i=$((i + 1))
24625                 offset=$((offset + $bs))
24626         done
24627         for (( i=0; i < $num; i++ )); do
24628                 wait ${pids[$i]}
24629         done
24630         check_lsom_size $DIR/$tfile $offset
24631
24632         i=0
24633         $TRUNCATE $DIR/$tfile 0
24634         for client in ${CLIENTS//,/ }; do
24635                 offset=$((offset - $bs))
24636                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
24637                 local pids[$i]=$!
24638                 i=$((i + 1))
24639         done
24640         for (( i=0; i < $num; i++ )); do
24641                 wait ${pids[$i]}
24642         done
24643         check_lsom_size $DIR/$tfile $size
24644
24645         # verify truncate
24646         echo "Test SOM for truncate"
24647         $TRUNCATE $DIR/$tfile 1048576
24648         check_lsom_size $DIR/$tfile 1048576
24649         $TRUNCATE $DIR/$tfile 1234
24650         check_lsom_size $DIR/$tfile 1234
24651
24652         # verify SOM blocks count
24653         echo "Verify SOM block count"
24654         $TRUNCATE $DIR/$tfile 0
24655         $MULTIOP $DIR/$tfile oO_TRUNC:O_RDWR:w1048576YSc ||
24656                 error "failed to write file $tfile"
24657         check_lsom_data $DIR/$tfile
24658 }
24659 run_test 806 "Verify Lazy Size on MDS"
24660
24661 test_807() {
24662         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
24663         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
24664                 skip "Need MDS version at least 2.11.52"
24665
24666         # Registration step
24667         changelog_register || error "changelog_register failed"
24668         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
24669         changelog_users $SINGLEMDS | grep -q $cl_user ||
24670                 error "User $cl_user not found in changelog_users"
24671
24672         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
24673         save_lustre_params client "llite.*.xattr_cache" > $save
24674         lctl set_param llite.*.xattr_cache=0
24675         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
24676
24677         rm -rf $DIR/$tdir || error "rm $tdir failed"
24678         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
24679         touch $DIR/$tdir/trunc || error "touch $tdir/trunc failed"
24680         $TRUNCATE $DIR/$tdir/trunc 1024 || error "truncate $tdir/trunc failed"
24681         $TRUNCATE $DIR/$tdir/trunc 1048576 ||
24682                 error "truncate $tdir/trunc failed"
24683
24684         local bs=1048576
24685         dd if=/dev/zero of=$DIR/$tdir/single_dd bs=$bs count=1 conv=fsync ||
24686                 error "write $tfile failed"
24687
24688         # multi-client wirtes
24689         local num=$(get_node_count ${CLIENTS//,/ })
24690         local offset=0
24691         local i=0
24692
24693         echo "Test SOM for multi-client ($num) writes"
24694         touch $DIR/$tfile || error "touch $tfile failed"
24695         $TRUNCATE $DIR/$tfile 0
24696         for client in ${CLIENTS//,/ }; do
24697                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
24698                 local pids[$i]=$!
24699                 i=$((i + 1))
24700                 offset=$((offset + $bs))
24701         done
24702         for (( i=0; i < $num; i++ )); do
24703                 wait ${pids[$i]}
24704         done
24705
24706         do_rpc_nodes "$CLIENTS" cancel_lru_locks osc
24707         do_nodes "$CLIENTS" "sync ; sleep 5 ; sync"
24708         $LSOM_SYNC -u $cl_user -m $FSNAME-MDT0000 $MOUNT
24709         check_lsom_data $DIR/$tdir/trunc
24710         check_lsom_data $DIR/$tdir/single_dd
24711         check_lsom_data $DIR/$tfile
24712
24713         rm -rf $DIR/$tdir
24714         # Deregistration step
24715         changelog_deregister || error "changelog_deregister failed"
24716 }
24717 run_test 807 "verify LSOM syncing tool"
24718
24719 check_som_nologged()
24720 {
24721         local lines=$($LFS changelog $FSNAME-MDT0000 |
24722                 grep 'x=trusted.som' | wc -l)
24723         [ $lines -ne 0 ] && error "trusted.som xattr is logged in Changelogs"
24724 }
24725
24726 test_808() {
24727         [ $MDS1_VERSION -lt $(version_code 2.11.55) ] &&
24728                 skip "Need MDS version at least 2.11.55"
24729
24730         # Registration step
24731         changelog_register || error "changelog_register failed"
24732
24733         touch $DIR/$tfile || error "touch $tfile failed"
24734         check_som_nologged
24735
24736         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=1 ||
24737                 error "write $tfile failed"
24738         check_som_nologged
24739
24740         $TRUNCATE $DIR/$tfile 1234
24741         check_som_nologged
24742
24743         $TRUNCATE $DIR/$tfile 1048576
24744         check_som_nologged
24745
24746         # Deregistration step
24747         changelog_deregister || error "changelog_deregister failed"
24748 }
24749 run_test 808 "Check trusted.som xattr not logged in Changelogs"
24750
24751 check_som_nodata()
24752 {
24753         $LFS getsom $1
24754         [[ $? -eq 61 ]] || error "DoM-only file $1 has SOM xattr"
24755 }
24756
24757 test_809() {
24758         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
24759                 skip "Need MDS version at least 2.11.56"
24760
24761         $LFS setstripe -E 1M -L mdt $DIR/$tfile ||
24762                 error "failed to create DoM-only file $DIR/$tfile"
24763         touch $DIR/$tfile || error "touch $tfile failed"
24764         check_som_nodata $DIR/$tfile
24765
24766         dd if=/dev/zero of=$DIR/$tfile bs=2048 count=1 ||
24767                 error "write $tfile failed"
24768         check_som_nodata $DIR/$tfile
24769
24770         $TRUNCATE $DIR/$tfile 1234
24771         check_som_nodata $DIR/$tfile
24772
24773         $TRUNCATE $DIR/$tfile 4097
24774         check_som_nodata $DIR/$file
24775 }
24776 run_test 809 "Verify no SOM xattr store for DoM-only files"
24777
24778 test_810() {
24779         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24780         $GSS && skip_env "could not run with gss"
24781         [[ $OST1_VERSION -gt $(version_code 2.12.58) ]] ||
24782                 skip "OST < 2.12.58 doesn't align checksum"
24783
24784         set_checksums 1
24785         stack_trap "set_checksums $ORIG_CSUM" EXIT
24786         stack_trap "set_checksum_type $ORIG_CSUM_TYPE" EXIT
24787
24788         local csum
24789         local before
24790         local after
24791         for csum in $CKSUM_TYPES; do
24792                 #define OBD_FAIL_OSC_NO_GRANT   0x411
24793                 $LCTL set_param osc.*.checksum_type=$csum fail_loc=0x411
24794                 for i in "10240 0" "10000 0" "4000 1" "500 1"; do
24795                         eval set -- $i
24796                         dd if=/dev/urandom of=$DIR/$tfile bs=$1 count=2 seek=$2
24797                         before=$(md5sum $DIR/$tfile)
24798                         $LCTL set_param ldlm.namespaces.*osc*.lru_size=clear
24799                         after=$(md5sum $DIR/$tfile)
24800                         [ "$before" == "$after" ] ||
24801                                 error "$csum: $before != $after bs=$1 seek=$2"
24802                 done
24803         done
24804 }
24805 run_test 810 "partial page writes on ZFS (LU-11663)"
24806
24807 test_812a() {
24808         [ $OST1_VERSION -lt $(version_code 2.12.51) ] &&
24809                 skip "OST < 2.12.51 doesn't support this fail_loc"
24810
24811         $LFS setstripe -c 1 -i 0 $DIR/$tfile
24812         # ensure ost1 is connected
24813         stat $DIR/$tfile >/dev/null || error "can't stat"
24814         wait_osc_import_state client ost1 FULL
24815         # no locks, no reqs to let the connection idle
24816         cancel_lru_locks osc
24817
24818         # delay OST_DISCONNECT on OST1 to put OSC into intermediate state
24819 #define OBD_FAIL_OST_DISCONNECT_DELAY    0x245
24820         do_facet ost1 "$LCTL set_param fail_loc=0x245 fail_val=8"
24821         wait_osc_import_state client ost1 CONNECTING
24822         do_facet ost1 "$LCTL set_param fail_loc=0 fail_val=0"
24823
24824         stat $DIR/$tfile >/dev/null || error "can't stat file"
24825 }
24826 run_test 812a "do not drop reqs generated when imp is going to idle (LU-11951)"
24827
24828 test_812b() { # LU-12378
24829         [ $OST1_VERSION -lt $(version_code 2.12.51) ] &&
24830                 skip "OST < 2.12.51 doesn't support this fail_loc"
24831
24832         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "setstripe failed"
24833         # ensure ost1 is connected
24834         stat $DIR/$tfile >/dev/null || error "can't stat"
24835         wait_osc_import_state client ost1 FULL
24836         # no locks, no reqs to let the connection idle
24837         cancel_lru_locks osc
24838
24839         # delay OST_DISCONNECT on OST1 to put OSC into intermediate state
24840 #define OBD_FAIL_OST_DISCONNECT_DELAY    0x245
24841         do_facet ost1 "$LCTL set_param fail_loc=0x245 fail_val=8"
24842         wait_osc_import_state client ost1 CONNECTING
24843         do_facet ost1 "$LCTL set_param fail_loc=0 fail_val=0"
24844
24845         $LFS quota -u 0 $DIR/ || error "lfs quota should succeed"
24846         wait_osc_import_state client ost1 IDLE
24847 }
24848 run_test 812b "do not drop no resend request for idle connect"
24849
24850 test_813() {
24851         local file_heat_sav=$($LCTL get_param -n llite.*.file_heat 2>/dev/null)
24852         [ -z "$file_heat_sav" ] && skip "no file heat support"
24853
24854         local readsample
24855         local writesample
24856         local readbyte
24857         local writebyte
24858         local readsample1
24859         local writesample1
24860         local readbyte1
24861         local writebyte1
24862
24863         local period_second=$($LCTL get_param -n llite.*.heat_period_second)
24864         local decay_pct=$($LCTL get_param -n llite.*.heat_decay_percentage)
24865
24866         $LCTL set_param -n llite.*.file_heat=1
24867         echo "Turn on file heat"
24868         echo "Period second: $period_second, Decay percentage: $decay_pct"
24869
24870         echo "QQQQ" > $DIR/$tfile
24871         echo "QQQQ" > $DIR/$tfile
24872         echo "QQQQ" > $DIR/$tfile
24873         cat $DIR/$tfile > /dev/null
24874         cat $DIR/$tfile > /dev/null
24875         cat $DIR/$tfile > /dev/null
24876         cat $DIR/$tfile > /dev/null
24877
24878         local out=$($LFS heat_get $DIR/$tfile)
24879
24880         $LFS heat_get $DIR/$tfile
24881         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
24882         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
24883         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
24884         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
24885
24886         [ $readsample -le 4 ] || error "read sample ($readsample) is wrong"
24887         [ $writesample -le 3 ] || error "write sample ($writesample) is wrong"
24888         [ $readbyte -le 20 ] || error "read bytes ($readbyte) is wrong"
24889         [ $writebyte -le 15 ] || error "write bytes ($writebyte) is wrong"
24890
24891         sleep $((period_second + 3))
24892         echo "Sleep $((period_second + 3)) seconds..."
24893         # The recursion formula to calculate the heat of the file f is as
24894         # follow:
24895         # Hi+1(f) = (1-P)*Hi(f)+ P*Ci
24896         # Where Hi is the heat value in the period between time points i*I and
24897         # (i+1)*I; Ci is the access count in the period; the symbol P refers
24898         # to the weight of Ci.
24899         out=$($LFS heat_get $DIR/$tfile)
24900         $LFS heat_get $DIR/$tfile
24901         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
24902         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
24903         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
24904         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
24905
24906         [ $(bc <<< "$readsample <= 4 * $decay_pct / 100") -eq 1 ] ||
24907                 error "read sample ($readsample) is wrong"
24908         [ $(bc <<< "$writesample <= 3 * $decay_pct / 100") -eq 1 ] ||
24909                 error "write sample ($writesample) is wrong"
24910         [ $(bc <<< "$readbyte <= 20 * $decay_pct / 100") -eq 1 ] ||
24911                 error "read bytes ($readbyte) is wrong"
24912         [ $(bc <<< "$writebyte <= 15 * $decay_pct / 100") -eq 1 ] ||
24913                 error "write bytes ($writebyte) is wrong"
24914
24915         echo "QQQQ" > $DIR/$tfile
24916         echo "QQQQ" > $DIR/$tfile
24917         echo "QQQQ" > $DIR/$tfile
24918         cat $DIR/$tfile > /dev/null
24919         cat $DIR/$tfile > /dev/null
24920         cat $DIR/$tfile > /dev/null
24921         cat $DIR/$tfile > /dev/null
24922
24923         sleep $((period_second + 3))
24924         echo "Sleep $((period_second + 3)) seconds..."
24925
24926         out=$($LFS heat_get $DIR/$tfile)
24927         $LFS heat_get $DIR/$tfile
24928         readsample1=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
24929         writesample1=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
24930         readbyte1=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
24931         writebyte1=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
24932
24933         [ $(bc <<< "$readsample1 <= ($readsample * (100 - $decay_pct) + \
24934                 4 * $decay_pct) / 100") -eq 1 ] ||
24935                 error "read sample ($readsample1) is wrong"
24936         [ $(bc <<< "$writesample1 <= ($writesample * (100 - $decay_pct) + \
24937                 3 * $decay_pct) / 100") -eq 1 ] ||
24938                 error "write sample ($writesample1) is wrong"
24939         [ $(bc <<< "$readbyte1 <= ($readbyte * (100 - $decay_pct) + \
24940                 20 * $decay_pct) / 100") -eq 1 ] ||
24941                 error "read bytes ($readbyte1) is wrong"
24942         [ $(bc <<< "$writebyte1 <= ($writebyte * (100 - $decay_pct) + \
24943                 15 * $decay_pct) / 100") -eq 1 ] ||
24944                 error "write bytes ($writebyte1) is wrong"
24945
24946         echo "Turn off file heat for the file $DIR/$tfile"
24947         $LFS heat_set -o $DIR/$tfile
24948
24949         echo "QQQQ" > $DIR/$tfile
24950         echo "QQQQ" > $DIR/$tfile
24951         echo "QQQQ" > $DIR/$tfile
24952         cat $DIR/$tfile > /dev/null
24953         cat $DIR/$tfile > /dev/null
24954         cat $DIR/$tfile > /dev/null
24955         cat $DIR/$tfile > /dev/null
24956
24957         out=$($LFS heat_get $DIR/$tfile)
24958         $LFS heat_get $DIR/$tfile
24959         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
24960         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
24961         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
24962         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
24963
24964         [ $readsample -eq 0 ] || error "read sample ($readsample) is wrong"
24965         [ $writesample -eq 0 ] || error "write sample ($writesample) is wrong"
24966         [ $readbyte -eq 0 ] || error "read bytes ($readbyte) is wrong"
24967         [ $writebyte -eq 0 ] || error "write bytes ($writebyte) is wrong"
24968
24969         echo "Trun on file heat for the file $DIR/$tfile"
24970         $LFS heat_set -O $DIR/$tfile
24971
24972         echo "QQQQ" > $DIR/$tfile
24973         echo "QQQQ" > $DIR/$tfile
24974         echo "QQQQ" > $DIR/$tfile
24975         cat $DIR/$tfile > /dev/null
24976         cat $DIR/$tfile > /dev/null
24977         cat $DIR/$tfile > /dev/null
24978         cat $DIR/$tfile > /dev/null
24979
24980         out=$($LFS heat_get $DIR/$tfile)
24981         $LFS heat_get $DIR/$tfile
24982         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
24983         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
24984         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
24985         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
24986
24987         [ $readsample -gt 0 ] || error "read sample ($readsample) is wrong"
24988         [ $writesample -gt 0 ] || error "write sample ($writesample) is wrong"
24989         [ $readbyte -gt 0 ] || error "read bytes ($readbyte) is wrong"
24990         [ $writebyte -gt 0 ] || error "write bytes ($writebyte) is wrong"
24991
24992         $LFS heat_set -c $DIR/$tfile
24993         $LCTL set_param -n llite.*.file_heat=0
24994         echo "Turn off file heat support for the Lustre filesystem"
24995
24996         echo "QQQQ" > $DIR/$tfile
24997         echo "QQQQ" > $DIR/$tfile
24998         echo "QQQQ" > $DIR/$tfile
24999         cat $DIR/$tfile > /dev/null
25000         cat $DIR/$tfile > /dev/null
25001         cat $DIR/$tfile > /dev/null
25002         cat $DIR/$tfile > /dev/null
25003
25004         out=$($LFS heat_get $DIR/$tfile)
25005         $LFS heat_get $DIR/$tfile
25006         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
25007         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
25008         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
25009         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
25010
25011         [ $readsample -eq 0 ] || error "read sample ($readsample) is wrong"
25012         [ $writesample -eq 0 ] || error "write sample ($writesample) is wrong"
25013         [ $readbyte -eq 0 ] || error "read bytes ($readbyte) is wrong"
25014         [ $writebyte -eq 0 ] || error "write bytes ($writebyte) is wrong"
25015
25016         $LCTL set_param -n llite.*.file_heat=$file_heat_sav
25017         rm -f $DIR/$tfile
25018 }
25019 run_test 813 "File heat verfication"
25020
25021 test_814()
25022 {
25023         dd of=$DIR/$tfile seek=128 bs=1k < /dev/null
25024         echo -n y >> $DIR/$tfile
25025         cp --sparse=always $DIR/$tfile $DIR/${tfile}.cp || error "copy failed"
25026         diff $DIR/$tfile $DIR/${tfile}.cp || error "files should be same"
25027 }
25028 run_test 814 "sparse cp works as expected (LU-12361)"
25029
25030 test_815()
25031 {
25032         writeme -b 100 $DIR/$tfile || error "write 100 bytes failed"
25033         writeme -b 0 $DIR/$tfile || error "write 0 byte failed"
25034 }
25035 run_test 815 "zero byte tiny write doesn't hang (LU-12382)"
25036
25037 test_816() {
25038         $LFS setstripe -c 1 -i 0 $DIR/$tfile
25039         # ensure ost1 is connected
25040         stat $DIR/$tfile >/dev/null || error "can't stat"
25041         wait_osc_import_state client ost1 FULL
25042         # no locks, no reqs to let the connection idle
25043         cancel_lru_locks osc
25044         lru_resize_disable osc
25045         local before
25046         local now
25047         before=$($LCTL get_param -n \
25048                  ldlm.namespaces.$FSNAME-OST0000-osc-[^M]*.lru_size)
25049
25050         wait_osc_import_state client ost1 IDLE
25051         dd if=/dev/null of=$DIR/$tfile bs=1k count=1 conv=sync
25052         now=$($LCTL get_param -n \
25053               ldlm.namespaces.$FSNAME-OST0000-osc-[^M]*.lru_size)
25054         [ $before == $now ] || error "lru_size changed $before != $now"
25055 }
25056 run_test 816 "do not reset lru_resize on idle reconnect"
25057
25058 cleanup_817() {
25059         umount $tmpdir
25060         exportfs -u localhost:$DIR/nfsexp
25061         rm -rf $DIR/nfsexp
25062 }
25063
25064 test_817() {
25065         systemctl restart nfs-server.service || skip "failed to restart nfsd"
25066
25067         mkdir -p $DIR/nfsexp
25068         exportfs -orw,no_root_squash localhost:$DIR/nfsexp ||
25069                 error "failed to export nfs"
25070
25071         tmpdir=$(mktemp -d /tmp/nfs-XXXXXX)
25072         stack_trap cleanup_817 EXIT
25073
25074         mount -t nfs -orw localhost:$DIR/nfsexp $tmpdir ||
25075                 error "failed to mount nfs to $tmpdir"
25076
25077         cp /bin/true $tmpdir
25078         $DIR/nfsexp/true || error "failed to execute 'true' command"
25079 }
25080 run_test 817 "nfsd won't cache write lock for exec file"
25081
25082 test_818() {
25083         mkdir $DIR/$tdir
25084         $LFS setstripe -c1 -i0 $DIR/$tfile
25085         $LFS setstripe -c1 -i1 $DIR/$tfile
25086         stop $SINGLEMDS
25087         #define OBD_FAIL_OSP_CANT_PROCESS_LLOG          0x2105
25088         do_facet $SINGLEMDS lctl set_param fail_loc=0x80002105
25089         start $SINGLEMDS $(mdsdevname ${SINGLEMDS//mds/}) $MDS_MOUNT_OPTS ||
25090                 error "start $SINGLEMDS failed"
25091         rm -rf $DIR/$tdir
25092 }
25093 run_test 818 "unlink with failed llog"
25094
25095 test_819a() {
25096         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
25097         cancel_lru_locks osc
25098         #define OBD_FAIL_OST_2BIG_NIOBUF                0x248
25099         do_facet $SINGLEMDS lctl set_param fail_loc=0x80000248
25100         dd if=$DIR/$tfile of=/dev/null bs=1M count=1
25101         rm -f $TDIR/$tfile
25102 }
25103 run_test 819a "too big niobuf in read"
25104
25105 test_819b() {
25106         #define OBD_FAIL_OST_2BIG_NIOBUF                0x248
25107         do_facet $SINGLEMDS lctl set_param fail_loc=0x80000248
25108         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
25109         cancel_lru_locks osc
25110         sleep 1
25111         rm -f $TDIR/$tfile
25112 }
25113 run_test 819b "too big niobuf in write"
25114
25115
25116 function test_820_start_ost() {
25117         sleep 5
25118
25119         for num in $(seq $OSTCOUNT); do
25120                 start ost$num $(ostdevname $num) $OST_MOUNT_OPTS
25121         done
25122 }
25123
25124 test_820() {
25125         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
25126
25127         mkdir $DIR/$tdir
25128         umount_client $MOUNT || error "umount failed"
25129         for num in $(seq $OSTCOUNT); do
25130                 stop ost$num
25131         done
25132
25133         # mount client with no active OSTs
25134         # so that the client can't initialize max LOV EA size
25135         # from OSC notifications
25136         mount_client $MOUNT || error "mount failed"
25137         # delay OST starting to keep this 0 max EA size for a while
25138         test_820_start_ost &
25139
25140         # create a directory on MDS2
25141         test_mkdir -i 1 -c1 $DIR/$tdir/mds2 ||
25142                 error "Failed to create directory"
25143         # open intent should update default EA size
25144         # see mdc_update_max_ea_from_body()
25145         # notice this is the very first RPC to MDS2
25146         out=$(cp /etc/services $DIR/$tdir/mds2 2>&1)
25147         ret=$?
25148         echo $out
25149         # With SSK, this situation can lead to -EPERM being returned.
25150         # In that case, simply retry.
25151         if [ $ret -ne 0 ] && $SHARED_KEY; then
25152                 if echo "$out" | grep -q "not permitted"; then
25153                         cp /etc/services $DIR/$tdir/mds2
25154                         ret=$?
25155                 fi
25156         fi
25157         [ $ret -eq 0 ] || error "Failed to copy files to mds$n"
25158 }
25159 run_test 820 "update max EA from open intent"
25160
25161 #
25162 # tests that do cleanup/setup should be run at the end
25163 #
25164
25165 test_900() {
25166         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25167         local ls
25168
25169         #define OBD_FAIL_MGC_PAUSE_PROCESS_LOG   0x903
25170         $LCTL set_param fail_loc=0x903
25171
25172         cancel_lru_locks MGC
25173
25174         FAIL_ON_ERROR=true cleanup
25175         FAIL_ON_ERROR=true setup
25176 }
25177 run_test 900 "umount should not race with any mgc requeue thread"
25178
25179 # LUS-6253/LU-11185
25180 test_901() {
25181         local oldc
25182         local newc
25183         local olds
25184         local news
25185         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25186
25187         # some get_param have a bug to handle dot in param name
25188         cancel_lru_locks MGC
25189         oldc=$($LCTL get_param -n 'ldlm.namespaces.MGC*.lock_count')
25190         olds=$(do_facet mgs $LCTL get_param -n 'ldlm.namespaces.MGS*.lock_count')
25191         umount_client $MOUNT || error "umount failed"
25192         mount_client $MOUNT || error "mount failed"
25193         cancel_lru_locks MGC
25194         newc=$($LCTL get_param -n 'ldlm.namespaces.MGC*.lock_count')
25195         news=$(do_facet mgs $LCTL get_param -n 'ldlm.namespaces.MGS*.lock_count')
25196
25197         [ $oldc -lt $newc ] && error "mgc lock leak ($oldc != $newc)"
25198         [ $olds -lt $news ] && error "mgs lock leak ($olds != $news)"
25199
25200         return 0
25201 }
25202 run_test 901 "don't leak a mgc lock on client umount"
25203
25204 # LU-13377
25205 test_902() {
25206         [ $CLIENT_VERSION -lt $(version_code 2.13.52) ] &&
25207                 skip "client does not have LU-13377 fix"
25208         #define OBD_FAIL_LLITE_SHORT_COMMIT 0x1415
25209         $LCTL set_param fail_loc=0x1415
25210         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
25211         cancel_lru_locks osc
25212         rm -f $DIR/$tfile
25213 }
25214 run_test 902 "test short write doesn't hang lustre"
25215
25216 complete $SECONDS
25217 [ -f $EXT2_DEV ] && rm $EXT2_DEV || true
25218 check_and_cleanup_lustre
25219 if [ "$I_MOUNTED" != "yes" ]; then
25220         lctl set_param debug="$OLDDEBUG" 2> /dev/null || true
25221 fi
25222 exit_status