Whamcloud - gitweb
LU-15421 tests: Add missing error() calls on errors
[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
63         ALWAYS_EXCEPT+=" 45"
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  15   (min)"
81 [ "$SLOW" = "no" ] && EXCEPT_SLOW="27m 60i 64b 68 71 115 135 136 230d 300o"
82
83 if [ "$mds1_FSTYPE" = "zfs" ]; then
84         # bug number for skipped test:
85         ALWAYS_EXCEPT+="              "
86         #                                               13    (min)"
87         [ "$SLOW" = "no" ] && EXCEPT_SLOW="$EXCEPT_SLOW 51b"
88 fi
89
90 if [ "$ost1_FSTYPE" = "zfs" ]; then
91         # bug number for skipped test:  LU-1941  LU-1941  LU-1941  LU-1941
92         ALWAYS_EXCEPT+="                130a 130b 130c 130d 130e 130f 130g"
93 fi
94
95 proc_regexp="/{proc,sys}/{fs,sys,kernel/debug}/{lustre,lnet}/"
96
97 # Get the SLES distro version
98 #
99 # Returns a version string that should only be used in comparing
100 # strings returned by version_code()
101 sles_version_code()
102 {
103         local version=$(grep VERSION_ID /etc/os-release | cut -d'"' -f2)
104
105         # All SuSE Linux versions have one decimal. version_code expects two
106         local sles_version=$version.0
107         version_code $sles_version
108 }
109
110 # Check if we are running on Ubuntu or SLES so we can make decisions on
111 # what tests to run
112 if [ -r /etc/SuSE-release ]; then
113         sles_version=$(sles_version_code)
114         [ $sles_version -lt $(version_code 11.4.0) ] &&
115                 # bug number for skipped test: LU-4341
116                 ALWAYS_EXCEPT="$ALWAYS_EXCEPT  170"
117         [ $sles_version -lt $(version_code 12.0.0) ] &&
118                 # bug number for skipped test: LU-3703
119                 ALWAYS_EXCEPT="$ALWAYS_EXCEPT  234"
120 elif [ -r /etc/os-release ]; then
121         if grep -qi ubuntu /etc/os-release; then
122                 ubuntu_version=$(version_code $(sed -n -e 's/"//g' \
123                                                 -e 's/^VERSION=//p' \
124                                                 /etc/os-release |
125                                                 awk '{ print $1 }'))
126
127                 if [[ $ubuntu_version -gt $(version_code 16.0.0) ]]; then
128                         # bug number for skipped test:
129                         #                LU-10334 LU-10366
130                         ALWAYS_EXCEPT+=" 103a     410"
131                 fi
132         fi
133 fi
134
135 build_test_filter
136 FAIL_ON_ERROR=false
137
138 cleanup() {
139         echo -n "cln.."
140         pgrep ll_sa > /dev/null && { echo "There are ll_sa thread not exit!"; exit 20; }
141         cleanupall ${FORCE} $* || { echo "FAILed to clean up"; exit 20; }
142 }
143 setup() {
144         echo -n "mnt.."
145         load_modules
146         setupall || exit 10
147         echo "done"
148 }
149
150 check_swap_layouts_support()
151 {
152         $LCTL get_param -n llite.*.sbi_flags | grep -q layout ||
153                 skip "Does not support layout lock."
154 }
155
156 check_swap_layout_no_dom()
157 {
158         local FOLDER=$1
159         local SUPP=$(lfs getstripe $FOLDER | grep "pattern:       mdt" | wc -l)
160         [ $SUPP -eq 0 ] || skip "layout swap does not support DOM files so far"
161 }
162
163 check_and_setup_lustre
164 DIR=${DIR:-$MOUNT}
165 assert_DIR
166
167 MAXFREE=${MAXFREE:-$((300000 * $OSTCOUNT))}
168
169 [ -f $DIR/d52a/foo ] && chattr -a $DIR/d52a/foo
170 [ -f $DIR/d52b/foo ] && chattr -i $DIR/d52b/foo
171 rm -rf $DIR/[Rdfs][0-9]*
172
173 # $RUNAS_ID may get set incorrectly somewhere else
174 [ $UID -eq 0 -a $RUNAS_ID -eq 0 ] &&
175         error "\$RUNAS_ID set to 0, but \$UID is also 0!"
176
177 check_runas_id $RUNAS_ID $RUNAS_GID $RUNAS
178
179 if [ "${ONLY}" = "MOUNT" ] ; then
180         echo "Lustre is up, please go on"
181         exit
182 fi
183
184 echo "preparing for tests involving mounts"
185 EXT2_DEV=${EXT2_DEV:-$TMP/SANITY.LOOP}
186 touch $EXT2_DEV
187 mke2fs -j -F $EXT2_DEV 8000 > /dev/null
188 echo # add a newline after mke2fs.
189
190 umask 077
191
192 OLDDEBUG=$(lctl get_param -n debug 2> /dev/null)
193 lctl set_param debug=-1 2> /dev/null || true
194 test_0a() {
195         touch $DIR/$tfile
196         $CHECKSTAT -t file $DIR/$tfile || error "$tfile is not a file"
197         rm $DIR/$tfile
198         $CHECKSTAT -a $DIR/$tfile || error "$tfile was not removed"
199 }
200 run_test 0a "touch; rm ====================="
201
202 test_0b() {
203         chmod 0755 $DIR || error "chmod 0755 $DIR failed"
204         $CHECKSTAT -p 0755 $DIR || error "$DIR permission is not 0755"
205 }
206 run_test 0b "chmod 0755 $DIR ============================="
207
208 test_0c() {
209         $LCTL get_param mdc.*.import | grep "state: FULL" ||
210                 error "import not FULL"
211         $LCTL get_param mdc.*.import | grep "target: $FSNAME-MDT" ||
212                 error "bad target"
213 }
214 run_test 0c "check import proc"
215
216 test_0d() { # LU-3397
217         [ $MGS_VERSION -lt $(version_code 2.10.57) ] &&
218                 skip "proc exports not supported before 2.10.57"
219
220         local mgs_exp="mgs.MGS.exports"
221         local client_uuid=$($LCTL get_param -n mgc.*.uuid)
222         local exp_client_nid
223         local exp_client_version
224         local exp_val
225         local imp_val
226         local temp_imp=$DIR/$tfile.import
227         local temp_exp=$DIR/$tfile.export
228
229         # save mgc import file to $temp_imp
230         $LCTL get_param mgc.*.import | tee $temp_imp
231         # Check if client uuid is found in MGS export
232         for exp_client_nid in $(do_facet mgs $LCTL get_param -N $mgs_exp.*); do
233                 [ $(do_facet mgs $LCTL get_param -n $exp_client_nid.uuid) == \
234                         $client_uuid ] &&
235                         break;
236         done
237         # save mgs export file to $temp_exp
238         do_facet mgs $LCTL get_param $exp_client_nid.export | tee $temp_exp
239
240         # Compare the value of field "connect_flags"
241         imp_val=$(grep "connect_flags" $temp_imp)
242         exp_val=$(grep "connect_flags" $temp_exp)
243         [ "$exp_val" == "$imp_val" ] ||
244                 error "export flags '$exp_val' != import flags '$imp_val'"
245
246         # Compare client versions.  Only compare top-3 fields for compatibility
247         exp_client_version=$(awk '/target_version:/ { print $2 }' $temp_exp)
248         exp_val=$(version_code $(cut -d. -f1,2,3 <<<$exp_client_version))
249         imp_val=$(version_code $(lustre_build_version client | cut -d. -f1,2,3))
250         [ "$exp_val" == "$imp_val" ] ||
251                 error "exp version '$exp_client_version'($exp_val) != " \
252                         "'$(lustre_build_version client)'($imp_val)"
253 }
254 run_test 0d "check export proc ============================="
255
256 test_0e() { # LU-13417
257         (( $MDSCOUNT > 1 )) ||
258                 skip "We need at least 2 MDTs for this test"
259
260         (( $MDS1_VERSION >= $(version_code 2.14.51) )) ||
261                 skip "Need server version at least 2.14.51"
262
263         local default_lmv_count=$($LFS getdirstripe -D -c $MOUNT)
264         local default_lmv_index=$($LFS getdirstripe -D -i $MOUNT)
265
266         [ $default_lmv_count -eq 1 ] ||
267                 error "$MOUNT default stripe count $default_lmv_count"
268
269         [ $default_lmv_index -eq -1 ] ||
270                 error "$MOUNT default stripe index $default_lmv_index"
271
272         mkdir $MOUNT/$tdir.1 || error "mkdir $MOUNT/$tdir.1 failed"
273         mkdir $MOUNT/$tdir.2 || error "mkdir $MOUNT/$tdir.2 failed"
274
275         local mdt_index1=$($LFS getdirstripe -i $MOUNT/$tdir.1)
276         local mdt_index2=$($LFS getdirstripe -i $MOUNT/$tdir.2)
277
278         [ $mdt_index1 -eq $mdt_index2 ] &&
279                 error "directories are on the same MDT $mdt_index1=$mdt_index2"
280
281         rmdir $MOUNT/$tdir.1 $MOUNT/$tdir.2
282 }
283 run_test 0e "Enable DNE MDT balancing for mkdir in the ROOT"
284
285 test_1() {
286         test_mkdir $DIR/$tdir
287         test_mkdir $DIR/$tdir/d2
288         mkdir $DIR/$tdir/d2 && error "we expect EEXIST, but not returned"
289         $CHECKSTAT -t dir $DIR/$tdir/d2 || error "$tdir/d2 is not a dir"
290         rmdir $DIR/$tdir/d2
291         rmdir $DIR/$tdir
292         $CHECKSTAT -a $DIR/$tdir || error "$tdir was not removed"
293 }
294 run_test 1 "mkdir; remkdir; rmdir"
295
296 test_2() {
297         test_mkdir $DIR/$tdir
298         touch $DIR/$tdir/$tfile || error "touch $tdir/$tfile failed"
299         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "$tdir/$tfile not a file"
300         rm -r $DIR/$tdir
301         $CHECKSTAT -a $DIR/$tdir/$tfile || error "$tdir/$file is not removed"
302 }
303 run_test 2 "mkdir; touch; rmdir; check file"
304
305 test_3() {
306         test_mkdir $DIR/$tdir
307         $CHECKSTAT -t dir $DIR/$tdir || error "$tdir is not a directory"
308         touch $DIR/$tdir/$tfile
309         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "$tdir/$tfile not a file"
310         rm -r $DIR/$tdir
311         $CHECKSTAT -a $DIR/$tdir || error "$tdir is not removed"
312 }
313 run_test 3 "mkdir; touch; rmdir; check dir"
314
315 # LU-4471 - failed rmdir on remote directories still removes directory on MDT0
316 test_4() {
317         test_mkdir -i 1 $DIR/$tdir
318
319         touch $DIR/$tdir/$tfile ||
320                 error "Create file under remote directory failed"
321
322         rmdir $DIR/$tdir &&
323                 error "Expect error removing in-use dir $DIR/$tdir"
324
325         test -d $DIR/$tdir || error "Remote directory disappeared"
326
327         rm -rf $DIR/$tdir || error "remove remote dir error"
328 }
329 run_test 4 "mkdir; touch dir/file; rmdir; checkdir (expect error)"
330
331 test_5() {
332         test_mkdir $DIR/$tdir
333         test_mkdir $DIR/$tdir/d2
334         chmod 0707 $DIR/$tdir/d2 || error "chmod 0707 $tdir/d2 failed"
335         $CHECKSTAT -t dir -p 0707 $DIR/$tdir/d2 || error "$tdir/d2 not mode 707"
336         $CHECKSTAT -t dir $DIR/$tdir/d2 || error "$tdir/d2 is not a directory"
337 }
338 run_test 5 "mkdir .../d5 .../d5/d2; chmod .../d5/d2"
339
340 test_6a() {
341         touch $DIR/$tfile || error "touch $DIR/$tfile failed"
342         chmod 0666 $DIR/$tfile || error "chmod 0666 $tfile failed"
343         $CHECKSTAT -t file -p 0666 -u \#$UID $DIR/$tfile ||
344                 error "$tfile does not have perm 0666 or UID $UID"
345         $RUNAS chmod 0444 $DIR/$tfile && error "chmod $tfile worked on UID $UID"
346         $CHECKSTAT -t file -p 0666 -u \#$UID $DIR/$tfile ||
347                 error "$tfile should be 0666 and owned by UID $UID"
348 }
349 run_test 6a "touch f6a; chmod f6a; $RUNAS chmod f6a (should return error) =="
350
351 test_6c() {
352         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID"
353
354         touch $DIR/$tfile
355         chown $RUNAS_ID $DIR/$tfile || error "chown $RUNAS_ID $file failed"
356         $CHECKSTAT -t file -u \#$RUNAS_ID $DIR/$tfile ||
357                 error "$tfile should be owned by UID $RUNAS_ID"
358         $RUNAS chown $UID $DIR/$tfile && error "chown $UID $file succeeded"
359         $CHECKSTAT -t file -u \#$RUNAS_ID $DIR/$tfile ||
360                 error "$tfile should be owned by UID $RUNAS_ID"
361 }
362 run_test 6c "touch f6c; chown f6c; $RUNAS chown f6c (should return error) =="
363
364 test_6e() {
365         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID"
366
367         touch $DIR/$tfile
368         chgrp $RUNAS_ID $DIR/$tfile || error "chgrp $RUNAS_ID $file failed"
369         $CHECKSTAT -t file -u \#$UID -g \#$RUNAS_ID $DIR/$tfile ||
370                 error "$tfile should be owned by GID $UID"
371         $RUNAS chgrp $UID $DIR/$tfile && error "chgrp $UID $file succeeded"
372         $CHECKSTAT -t file -u \#$UID -g \#$RUNAS_ID $DIR/$tfile ||
373                 error "$tfile should be owned by UID $UID and GID $RUNAS_ID"
374 }
375 run_test 6e "touch+chgrp $tfile; $RUNAS chgrp $tfile (should return error)"
376
377 test_6g() {
378         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID"
379
380         test_mkdir $DIR/$tdir
381         chmod 777 $DIR/$tdir || error "chmod 0777 $tdir failed"
382         $RUNAS mkdir $DIR/$tdir/d || error "mkdir $tdir/d failed"
383         chmod g+s $DIR/$tdir/d || error "chmod g+s $tdir/d failed"
384         test_mkdir $DIR/$tdir/d/subdir
385         $CHECKSTAT -g \#$RUNAS_GID $DIR/$tdir/d/subdir ||
386                 error "$tdir/d/subdir should be GID $RUNAS_GID"
387         if [[ $MDSCOUNT -gt 1 ]]; then
388                 # check remote dir sgid inherite
389                 $LFS mkdir -i 0 $DIR/$tdir.local ||
390                         error "mkdir $tdir.local failed"
391                 chmod g+s $DIR/$tdir.local ||
392                         error "chmod $tdir.local failed"
393                 chgrp $RUNAS_GID $DIR/$tdir.local ||
394                         error "chgrp $tdir.local failed"
395                 $LFS mkdir -i 1 $DIR/$tdir.local/$tdir.remote ||
396                         error "mkdir $tdir.remote failed"
397                 $CHECKSTAT -g \#$RUNAS_GID $DIR/$tdir.local/$tdir.remote ||
398                         error "$tdir.remote should be owned by $UID.$RUNAS_ID"
399                 $CHECKSTAT -p 02755 $DIR/$tdir.local/$tdir.remote ||
400                         error "$tdir.remote should be mode 02755"
401         fi
402 }
403 run_test 6g "verify new dir in sgid dir inherits group"
404
405 test_6h() { # bug 7331
406         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID"
407
408         touch $DIR/$tfile || error "touch failed"
409         chown $RUNAS_ID:$RUNAS_GID $DIR/$tfile || error "initial chown failed"
410         $RUNAS -G$RUNAS_GID chown $RUNAS_ID:0 $DIR/$tfile &&
411                 error "chown $RUNAS_ID:0 $tfile worked as GID $RUNAS_GID"
412         $CHECKSTAT -t file -u \#$RUNAS_ID -g \#$RUNAS_GID $DIR/$tfile ||
413                 error "$tdir/$tfile should be UID $RUNAS_UID GID $RUNAS_GID"
414 }
415 run_test 6h "$RUNAS chown RUNAS_ID.0 .../$tfile (should return error)"
416
417 test_7a() {
418         test_mkdir $DIR/$tdir
419         $MCREATE $DIR/$tdir/$tfile
420         chmod 0666 $DIR/$tdir/$tfile
421         $CHECKSTAT -t file -p 0666 $DIR/$tdir/$tfile ||
422                 error "$tdir/$tfile should be mode 0666"
423 }
424 run_test 7a "mkdir .../d7; mcreate .../d7/f; chmod .../d7/f ===="
425
426 test_7b() {
427         if [ ! -d $DIR/$tdir ]; then
428                 test_mkdir $DIR/$tdir
429         fi
430         $MCREATE $DIR/$tdir/$tfile
431         echo -n foo > $DIR/$tdir/$tfile
432         [ "$(cat $DIR/$tdir/$tfile)" = "foo" ] || error "$tdir/$tfile not 'foo'"
433         $CHECKSTAT -t file -s 3 $DIR/$tdir/$tfile || error "$tfile size not 3"
434 }
435 run_test 7b "mkdir .../d7; mcreate d7/f2; echo foo > d7/f2 ====="
436
437 test_8() {
438         test_mkdir $DIR/$tdir
439         touch $DIR/$tdir/$tfile
440         chmod 0666 $DIR/$tdir/$tfile
441         $CHECKSTAT -t file -p 0666 $DIR/$tdir/$tfile ||
442                 error "$tfile mode not 0666"
443 }
444 run_test 8 "mkdir .../d8; touch .../d8/f; chmod .../d8/f ======="
445
446 test_9() {
447         test_mkdir $DIR/$tdir
448         test_mkdir $DIR/$tdir/d2
449         test_mkdir $DIR/$tdir/d2/d3
450         $CHECKSTAT -t dir $DIR/$tdir/d2/d3 || error "$tdir/d2/d3 not a dir"
451 }
452 run_test 9 "mkdir .../d9 .../d9/d2 .../d9/d2/d3 ================"
453
454 test_10() {
455         test_mkdir $DIR/$tdir
456         test_mkdir $DIR/$tdir/d2
457         touch $DIR/$tdir/d2/$tfile
458         $CHECKSTAT -t file $DIR/$tdir/d2/$tfile ||
459                 error "$tdir/d2/$tfile not a file"
460 }
461 run_test 10 "mkdir .../d10 .../d10/d2; touch .../d10/d2/f ======"
462
463 test_11() {
464         test_mkdir $DIR/$tdir
465         test_mkdir $DIR/$tdir/d2
466         chmod 0666 $DIR/$tdir/d2
467         chmod 0705 $DIR/$tdir/d2
468         $CHECKSTAT -t dir -p 0705 $DIR/$tdir/d2 ||
469                 error "$tdir/d2 mode not 0705"
470 }
471 run_test 11 "mkdir .../d11 d11/d2; chmod .../d11/d2 ============"
472
473 test_12() {
474         test_mkdir $DIR/$tdir
475         touch $DIR/$tdir/$tfile
476         chmod 0666 $DIR/$tdir/$tfile
477         chmod 0654 $DIR/$tdir/$tfile
478         $CHECKSTAT -t file -p 0654 $DIR/$tdir/$tfile ||
479                 error "$tdir/d2 mode not 0654"
480 }
481 run_test 12 "touch .../d12/f; chmod .../d12/f .../d12/f ========"
482
483 test_13() {
484         test_mkdir $DIR/$tdir
485         dd if=/dev/zero of=$DIR/$tdir/$tfile count=10
486         >  $DIR/$tdir/$tfile
487         $CHECKSTAT -t file -s 0 $DIR/$tdir/$tfile ||
488                 error "$tdir/$tfile size not 0 after truncate"
489 }
490 run_test 13 "creat .../d13/f; dd .../d13/f; > .../d13/f ========"
491
492 test_14() {
493         test_mkdir $DIR/$tdir
494         touch $DIR/$tdir/$tfile
495         rm $DIR/$tdir/$tfile
496         $CHECKSTAT -a $DIR/$tdir/$tfile || error "$tdir/$tfile not removed"
497 }
498 run_test 14 "touch .../d14/f; rm .../d14/f; rm .../d14/f ======="
499
500 test_15() {
501         test_mkdir $DIR/$tdir
502         touch $DIR/$tdir/$tfile
503         mv $DIR/$tdir/$tfile $DIR/$tdir/${tfile}_2
504         $CHECKSTAT -t file $DIR/$tdir/${tfile}_2 ||
505                 error "$tdir/${tfile_2} not a file after rename"
506         rm $DIR/$tdir/${tfile}_2 || error "unlink failed after rename"
507 }
508 run_test 15 "touch .../d15/f; mv .../d15/f .../d15/f2 =========="
509
510 test_16() {
511         test_mkdir $DIR/$tdir
512         touch $DIR/$tdir/$tfile
513         rm -rf $DIR/$tdir/$tfile
514         $CHECKSTAT -a $DIR/$tdir/$tfile || error "$tdir/$tfile not removed"
515 }
516 run_test 16 "touch .../d16/f; rm -rf .../d16/f"
517
518 test_17a() {
519         test_mkdir $DIR/$tdir
520         touch $DIR/$tdir/$tfile
521         ln -s $DIR/$tdir/$tfile $DIR/$tdir/l-exist
522         ls -l $DIR/$tdir
523         $CHECKSTAT -l $DIR/$tdir/$tfile $DIR/$tdir/l-exist ||
524                 error "$tdir/l-exist not a symlink"
525         $CHECKSTAT -f -t f $DIR/$tdir/l-exist ||
526                 error "$tdir/l-exist not referencing a file"
527         rm -f $DIR/$tdir/l-exist
528         $CHECKSTAT -a $DIR/$tdir/l-exist || error "$tdir/l-exist not removed"
529 }
530 run_test 17a "symlinks: create, remove (real)"
531
532 test_17b() {
533         test_mkdir $DIR/$tdir
534         ln -s no-such-file $DIR/$tdir/l-dangle
535         ls -l $DIR/$tdir
536         $CHECKSTAT -l no-such-file $DIR/$tdir/l-dangle ||
537                 error "$tdir/l-dangle not referencing no-such-file"
538         $CHECKSTAT -fa $DIR/$tdir/l-dangle ||
539                 error "$tdir/l-dangle not referencing non-existent file"
540         rm -f $DIR/$tdir/l-dangle
541         $CHECKSTAT -a $DIR/$tdir/l-dangle || error "$tdir/l-dangle not removed"
542 }
543 run_test 17b "symlinks: create, remove (dangling)"
544
545 test_17c() { # bug 3440 - don't save failed open RPC for replay
546         test_mkdir $DIR/$tdir
547         ln -s foo $DIR/$tdir/$tfile
548         cat $DIR/$tdir/$tfile && error "opened non-existent symlink" || true
549 }
550 run_test 17c "symlinks: open dangling (should return error)"
551
552 test_17d() {
553         test_mkdir $DIR/$tdir
554         ln -s foo $DIR/$tdir/$tfile
555         touch $DIR/$tdir/$tfile || error "creating to new symlink"
556 }
557 run_test 17d "symlinks: create dangling"
558
559 test_17e() {
560         test_mkdir $DIR/$tdir
561         local foo=$DIR/$tdir/$tfile
562         ln -s $foo $foo || error "create symlink failed"
563         ls -l $foo || error "ls -l failed"
564         ls $foo && error "ls not failed" || true
565 }
566 run_test 17e "symlinks: create recursive symlink (should return error)"
567
568 test_17f() {
569         test_mkdir $DIR/$tdir
570         ln -s 1234567890/2234567890/3234567890/4234567890 $DIR/$tdir/111
571         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890 $DIR/$tdir/222
572         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890/7234567890/8234567890 $DIR/$tdir/333
573         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890/7234567890/8234567890/9234567890/a234567890/b234567890 $DIR/$tdir/444
574         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890/7234567890/8234567890/9234567890/a234567890/b234567890/c234567890/d234567890/f234567890 $DIR/$tdir/555
575         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
576         ls -l  $DIR/$tdir
577 }
578 run_test 17f "symlinks: long and very long symlink name"
579
580 # str_repeat(S, N) generate a string that is string S repeated N times
581 str_repeat() {
582         local s=$1
583         local n=$2
584         local ret=''
585         while [ $((n -= 1)) -ge 0 ]; do
586                 ret=$ret$s
587         done
588         echo $ret
589 }
590
591 # Long symlinks and LU-2241
592 test_17g() {
593         test_mkdir $DIR/$tdir
594         local TESTS="59 60 61 4094 4095"
595
596         # Fix for inode size boundary in 2.1.4
597         [ $MDS1_VERSION -lt $(version_code 2.1.4) ] &&
598                 TESTS="4094 4095"
599
600         # Patch not applied to 2.2 or 2.3 branches
601         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] &&
602         [ $MDS1_VERSION -le $(version_code 2.3.55) ] &&
603                 TESTS="4094 4095"
604
605         for i in $TESTS; do
606                 local SYMNAME=$(str_repeat 'x' $i)
607                 ln -s $SYMNAME $DIR/$tdir/f$i || error "failed $i-char symlink"
608                 readlink $DIR/$tdir/f$i || error "failed $i-char readlink"
609         done
610 }
611 run_test 17g "symlinks: really long symlink name and inode boundaries"
612
613 test_17h() { #bug 17378
614         [ $PARALLEL == "yes" ] && skip "skip parallel run"
615         remote_mds_nodsh && skip "remote MDS with nodsh"
616
617         local mdt_idx
618
619         test_mkdir $DIR/$tdir
620         mdt_idx=$($LFS getdirstripe -i $DIR/$tdir)
621         $LFS setstripe -c -1 $DIR/$tdir
622         #define OBD_FAIL_MDS_LOV_PREP_CREATE 0x141
623         do_facet mds$((mdt_idx + 1)) lctl set_param fail_loc=0x80000141
624         touch $DIR/$tdir/$tfile || true
625 }
626 run_test 17h "create objects: lov_free_memmd() doesn't lbug"
627
628 test_17i() { #bug 20018
629         [ $PARALLEL == "yes" ] && skip "skip parallel run"
630         remote_mds_nodsh && skip "remote MDS with nodsh"
631
632         local foo=$DIR/$tdir/$tfile
633         local mdt_idx
634
635         test_mkdir -c1 $DIR/$tdir
636         mdt_idx=$($LFS getdirstripe -i $DIR/$tdir)
637         ln -s $foo $foo || error "create symlink failed"
638 #define OBD_FAIL_MDS_READLINK_EPROTO     0x143
639         do_facet mds$((mdt_idx + 1)) lctl set_param fail_loc=0x80000143
640         ls -l $foo && error "error not detected"
641         return 0
642 }
643 run_test 17i "don't panic on short symlink (should return error)"
644
645 test_17k() { #bug 22301
646         [ $PARALLEL == "yes" ] && skip "skip parallel run"
647         [[ -z "$(which rsync 2>/dev/null)" ]] &&
648                 skip "no rsync command"
649         rsync --help | grep -q xattr ||
650                 skip_env "$(rsync --version | head -n1) does not support xattrs"
651         test_mkdir $DIR/$tdir
652         test_mkdir $DIR/$tdir.new
653         touch $DIR/$tdir/$tfile
654         ln -s $DIR/$tdir/$tfile $DIR/$tdir/$tfile.lnk
655         rsync -av -X $DIR/$tdir/ $DIR/$tdir.new ||
656                 error "rsync failed with xattrs enabled"
657 }
658 run_test 17k "symlinks: rsync with xattrs enabled"
659
660 test_17l() { # LU-279
661         [[ -z "$(which getfattr 2>/dev/null)" ]] &&
662                 skip "no getfattr command"
663
664         test_mkdir $DIR/$tdir
665         touch $DIR/$tdir/$tfile
666         ln -s $DIR/$tdir/$tfile $DIR/$tdir/$tfile.lnk
667         for path in "$DIR/$tdir" "$DIR/$tdir/$tfile" "$DIR/$tdir/$tfile.lnk"; do
668                 # -h to not follow symlinks. -m '' to list all the xattrs.
669                 # grep to remove first line: '# file: $path'.
670                 for xattr in `getfattr -hm '' $path 2>/dev/null | grep -v '^#'`;
671                 do
672                         lgetxattr_size_check $path $xattr ||
673                                 error "lgetxattr_size_check $path $xattr failed"
674                 done
675         done
676 }
677 run_test 17l "Ensure lgetxattr's returned xattr size is consistent"
678
679 # LU-1540
680 test_17m() {
681         [ $PARALLEL == "yes" ] && skip "skip parallel run"
682         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
683         remote_mds_nodsh && skip "remote MDS with nodsh"
684         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] &&
685         [ $MDS1_VERSION -le $(version_code 2.2.93) ] &&
686                 skip "MDS 2.2.0-2.2.93 do not NUL-terminate symlinks"
687
688         local short_sym="0123456789"
689         local wdir=$DIR/$tdir
690         local i
691
692         test_mkdir $wdir
693         long_sym=$short_sym
694         # create a long symlink file
695         for ((i = 0; i < 4; ++i)); do
696                 long_sym=${long_sym}${long_sym}
697         done
698
699         echo "create 512 short and long symlink files under $wdir"
700         for ((i = 0; i < 256; ++i)); do
701                 ln -sf ${long_sym}"a5a5" $wdir/long-$i
702                 ln -sf ${short_sym}"a5a5" $wdir/short-$i
703         done
704
705         echo "erase them"
706         rm -f $wdir/*
707         sync
708         wait_delete_completed
709
710         echo "recreate the 512 symlink files with a shorter string"
711         for ((i = 0; i < 512; ++i)); do
712                 # rewrite the symlink file with a shorter string
713                 ln -sf ${long_sym} $wdir/long-$i || error "long_sym failed"
714                 ln -sf ${short_sym} $wdir/short-$i || error "short_sym failed"
715         done
716
717         local mds_index=$(($($LFS getstripe -m $wdir) + 1))
718         local devname=$(mdsdevname $mds_index)
719
720         echo "stop and checking mds${mds_index}:"
721         # e2fsck should not return error
722         stop mds${mds_index}
723         run_e2fsck $(facet_active_host mds${mds_index}) $devname -n
724         rc=$?
725
726         start mds${mds_index} $devname $MDS_MOUNT_OPTS ||
727                 error "start mds${mds_index} failed"
728         df $MOUNT > /dev/null 2>&1
729         [ $rc -eq 0 ] ||
730                 error "e2fsck detected error for short/long symlink: rc=$rc"
731         rm -f $wdir/*
732 }
733 run_test 17m "run e2fsck against MDT which contains short/long symlink"
734
735 check_fs_consistency_17n() {
736         local mdt_index
737         local rc=0
738
739         # create/unlink in 17n only change 2 MDTs(MDT1/MDT2),
740         # so it only check MDT1/MDT2 instead of all of MDTs.
741         for mdt_index in 1 2; do
742                 local devname=$(mdsdevname $mdt_index)
743                 # e2fsck should not return error
744                 stop mds${mdt_index}
745                 run_e2fsck $(facet_active_host mds$mdt_index) $devname -n ||
746                         rc=$((rc + $?))
747
748                 start mds${mdt_index} $devname $MDS_MOUNT_OPTS ||
749                         error "mount mds$mdt_index failed"
750                 df $MOUNT > /dev/null 2>&1
751         done
752         return $rc
753 }
754
755 test_17n() {
756         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
757         [ $PARALLEL == "yes" ] && skip "skip parallel run"
758         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
759         remote_mds_nodsh && skip "remote MDS with nodsh"
760         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] &&
761         [ $MDS1_VERSION -le $(version_code 2.2.93) ] &&
762                 skip "MDS 2.2.0-2.2.93 do not NUL-terminate symlinks"
763
764         local i
765
766         test_mkdir $DIR/$tdir
767         for ((i=0; i<10; i++)); do
768                 $LFS mkdir -i1 -c2 $DIR/$tdir/remote_dir_${i} ||
769                         error "create remote dir error $i"
770                 createmany -o $DIR/$tdir/remote_dir_${i}/f 10 ||
771                         error "create files under remote dir failed $i"
772         done
773
774         check_fs_consistency_17n ||
775                 error "e2fsck report error after create files under remote dir"
776
777         for ((i = 0; i < 10; i++)); do
778                 rm -rf $DIR/$tdir/remote_dir_${i} ||
779                         error "destroy remote dir error $i"
780         done
781
782         check_fs_consistency_17n ||
783                 error "e2fsck report error after unlink files under remote dir"
784
785         [ $MDS1_VERSION -lt $(version_code 2.4.50) ] &&
786                 skip "lustre < 2.4.50 does not support migrate mv"
787
788         for ((i = 0; i < 10; i++)); do
789                 mkdir -p $DIR/$tdir/remote_dir_${i}
790                 createmany -o $DIR/$tdir/remote_dir_${i}/f 10 ||
791                         error "create files under remote dir failed $i"
792                 $LFS migrate --mdt-index 1 $DIR/$tdir/remote_dir_${i} ||
793                         error "migrate remote dir error $i"
794         done
795         check_fs_consistency_17n || error "e2fsck report error after migration"
796
797         for ((i = 0; i < 10; i++)); do
798                 rm -rf $DIR/$tdir/remote_dir_${i} ||
799                         error "destroy remote dir error $i"
800         done
801
802         check_fs_consistency_17n || error "e2fsck report error after unlink"
803 }
804 run_test 17n "run e2fsck against master/slave MDT which contains remote dir"
805
806 test_17o() {
807         remote_mds_nodsh && skip "remote MDS with nodsh"
808         [ $MDS1_VERSION -lt $(version_code 2.3.64) ] &&
809                 skip "Need MDS version at least 2.3.64"
810
811         local wdir=$DIR/${tdir}o
812         local mdt_index
813         local rc=0
814
815         test_mkdir $wdir
816         touch $wdir/$tfile
817         mdt_index=$($LFS getstripe -m $wdir/$tfile)
818         mdt_index=$((mdt_index + 1))
819
820         cancel_lru_locks mdc
821         #fail mds will wait the failover finish then set
822         #following fail_loc to avoid interfer the recovery process.
823         fail mds${mdt_index}
824
825         #define OBD_FAIL_OSD_LMA_INCOMPAT 0x194
826         do_facet mds${mdt_index} lctl set_param fail_loc=0x194
827         ls -l $wdir/$tfile && rc=1
828         do_facet mds${mdt_index} lctl set_param fail_loc=0
829         [[ $rc -eq 0 ]] || error "stat file should fail"
830 }
831 run_test 17o "stat file with incompat LMA feature"
832
833 test_18() {
834         touch $DIR/$tfile || error "Failed to touch $DIR/$tfile: $?"
835         ls $DIR || error "Failed to ls $DIR: $?"
836 }
837 run_test 18 "touch .../f ; ls ... =============================="
838
839 test_19a() {
840         touch $DIR/$tfile
841         ls -l $DIR
842         rm $DIR/$tfile
843         $CHECKSTAT -a $DIR/$tfile || error "$tfile was not removed"
844 }
845 run_test 19a "touch .../f19 ; ls -l ... ; rm .../f19 ==========="
846
847 test_19b() {
848         ls -l $DIR/$tfile && error "ls -l $tfile failed"|| true
849 }
850 run_test 19b "ls -l .../f19 (should return error) =============="
851
852 test_19c() {
853         [ $RUNAS_ID -eq $UID ] &&
854                 skip_env "RUNAS_ID = UID = $UID -- skipping"
855
856         $RUNAS touch $DIR/$tfile && error "create non-root file failed" || true
857 }
858 run_test 19c "$RUNAS touch .../f19 (should return error) =="
859
860 test_19d() {
861         cat $DIR/f19 && error || true
862 }
863 run_test 19d "cat .../f19 (should return error) =============="
864
865 test_20() {
866         touch $DIR/$tfile
867         rm $DIR/$tfile
868         touch $DIR/$tfile
869         rm $DIR/$tfile
870         touch $DIR/$tfile
871         rm $DIR/$tfile
872         $CHECKSTAT -a $DIR/$tfile || error "$tfile was not removed"
873 }
874 run_test 20 "touch .../f ; ls -l ..."
875
876 test_21() {
877         test_mkdir $DIR/$tdir
878         [ -f $DIR/$tdir/dangle ] && rm -f $DIR/$tdir/dangle
879         ln -s dangle $DIR/$tdir/link
880         echo foo >> $DIR/$tdir/link
881         cat $DIR/$tdir/dangle
882         $CHECKSTAT -t link $DIR/$tdir/link || error "$tdir/link not a link"
883         $CHECKSTAT -f -t file $DIR/$tdir/link ||
884                 error "$tdir/link not linked to a file"
885 }
886 run_test 21 "write to dangling link"
887
888 test_22() {
889         local wdir=$DIR/$tdir
890         test_mkdir $wdir
891         chown $RUNAS_ID:$RUNAS_GID $wdir
892         (cd $wdir || error "cd $wdir failed";
893                 $RUNAS tar cf - /etc/hosts /etc/sysconfig/network |
894                 $RUNAS tar xf -)
895         ls -lR $wdir/etc || error "ls -lR $wdir/etc failed"
896         $CHECKSTAT -t dir $wdir/etc || error "checkstat -t dir failed"
897         $CHECKSTAT -u \#$RUNAS_ID -g \#$RUNAS_GID $wdir/etc ||
898                 error "checkstat -u failed"
899 }
900 run_test 22 "unpack tar archive as non-root user"
901
902 # was test_23
903 test_23a() {
904         test_mkdir $DIR/$tdir
905         local file=$DIR/$tdir/$tfile
906
907         openfile -f O_CREAT:O_EXCL $file || error "$file create failed"
908         openfile -f O_CREAT:O_EXCL $file &&
909                 error "$file recreate succeeded" || true
910 }
911 run_test 23a "O_CREAT|O_EXCL in subdir"
912
913 test_23b() { # bug 18988
914         test_mkdir $DIR/$tdir
915         local file=$DIR/$tdir/$tfile
916
917         rm -f $file
918         echo foo > $file || error "write filed"
919         echo bar >> $file || error "append filed"
920         $CHECKSTAT -s 8 $file || error "wrong size"
921         rm $file
922 }
923 run_test 23b "O_APPEND check"
924
925 # LU-9409, size with O_APPEND and tiny writes
926 test_23c() {
927         local file=$DIR/$tfile
928
929         # single dd
930         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=8 count=800
931         $CHECKSTAT -s 6400 $file || error "wrong size, expected 6400"
932         rm -f $file
933
934         # racing tiny writes
935         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=8 count=800 &
936         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=8 count=800 &
937         wait
938         $CHECKSTAT -s 12800 $file || error "wrong size, expected 12800"
939         rm -f $file
940
941         #racing tiny & normal writes
942         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=4096 count=4 &
943         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=8 count=100 &
944         wait
945         $CHECKSTAT -s 17184 $file || error "wrong size, expected 17184"
946         rm -f $file
947
948         #racing tiny & normal writes 2, ugly numbers
949         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=4099 count=11 &
950         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=17 count=173 &
951         wait
952         $CHECKSTAT -s 48030 $file || error "wrong size, expected 48030"
953         rm -f $file
954 }
955 run_test 23c "O_APPEND size checks for tiny writes"
956
957 # LU-11069 file offset is correct after appending writes
958 test_23d() {
959         local file=$DIR/$tfile
960         local offset
961
962         echo CentaurHauls > $file
963         offset=$($MULTIOP $file oO_WRONLY:O_APPEND:w13Zp)
964         if ((offset != 26)); then
965                 error "wrong offset, expected 26, got '$offset'"
966         fi
967 }
968 run_test 23d "file offset is correct after appending writes"
969
970 # rename sanity
971 test_24a() {
972         echo '-- same directory rename'
973         test_mkdir $DIR/$tdir
974         touch $DIR/$tdir/$tfile.1
975         mv $DIR/$tdir/$tfile.1 $DIR/$tdir/$tfile.2
976         $CHECKSTAT -t file $DIR/$tdir/$tfile.2 || error "$tfile.2 not a file"
977 }
978 run_test 24a "rename file to non-existent target"
979
980 test_24b() {
981         test_mkdir $DIR/$tdir
982         touch $DIR/$tdir/$tfile.{1,2}
983         mv $DIR/$tdir/$tfile.1 $DIR/$tdir/$tfile.2
984         $CHECKSTAT -a $DIR/$tdir/$tfile.1 || error "$tfile.1 exists"
985         $CHECKSTAT -t file $DIR/$tdir/$tfile.2 || error "$tfile.2 not a file"
986 }
987 run_test 24b "rename file to existing target"
988
989 test_24c() {
990         test_mkdir $DIR/$tdir
991         test_mkdir $DIR/$tdir/d$testnum.1
992         mv $DIR/$tdir/d$testnum.1 $DIR/$tdir/d$testnum.2
993         $CHECKSTAT -a $DIR/$tdir/d$testnum.1 || error "d$testnum.1 exists"
994         $CHECKSTAT -t dir $DIR/$tdir/d$testnum.2 || error "d$testnum.2 not dir"
995 }
996 run_test 24c "rename directory to non-existent target"
997
998 test_24d() {
999         test_mkdir -c1 $DIR/$tdir
1000         test_mkdir -c1 $DIR/$tdir/d$testnum.1
1001         test_mkdir -c1 $DIR/$tdir/d$testnum.2
1002         mrename $DIR/$tdir/d$testnum.1 $DIR/$tdir/d$testnum.2
1003         $CHECKSTAT -a $DIR/$tdir/d$testnum.1 || error "d$testnum.1 exists"
1004         $CHECKSTAT -t dir $DIR/$tdir/d$testnum.2 || error "d$testnum.2 not dir"
1005 }
1006 run_test 24d "rename directory to existing target"
1007
1008 test_24e() {
1009         echo '-- cross directory renames --'
1010         test_mkdir $DIR/R5a
1011         test_mkdir $DIR/R5b
1012         touch $DIR/R5a/f
1013         mv $DIR/R5a/f $DIR/R5b/g
1014         $CHECKSTAT -a $DIR/R5a/f || error "$DIR/R5a/f exists"
1015         $CHECKSTAT -t file $DIR/R5b/g || error "$DIR/R5b/g not file type"
1016 }
1017 run_test 24e "touch .../R5a/f; rename .../R5a/f .../R5b/g ======"
1018
1019 test_24f() {
1020         test_mkdir $DIR/R6a
1021         test_mkdir $DIR/R6b
1022         touch $DIR/R6a/f $DIR/R6b/g
1023         mv $DIR/R6a/f $DIR/R6b/g
1024         $CHECKSTAT -a $DIR/R6a/f || error "$DIR/R6a/f exists"
1025         $CHECKSTAT -t file $DIR/R6b/g || error "$DIR/R6b/g not file type"
1026 }
1027 run_test 24f "touch .../R6a/f R6b/g; mv .../R6a/f .../R6b/g ===="
1028
1029 test_24g() {
1030         test_mkdir $DIR/R7a
1031         test_mkdir $DIR/R7b
1032         test_mkdir $DIR/R7a/d
1033         mv $DIR/R7a/d $DIR/R7b/e
1034         $CHECKSTAT -a $DIR/R7a/d || error "$DIR/R7a/d exists"
1035         $CHECKSTAT -t dir $DIR/R7b/e || error "$DIR/R7b/e not dir type"
1036 }
1037 run_test 24g "mkdir .../R7{a,b}/d; mv .../R7a/d .../R7b/e ======"
1038
1039 test_24h() {
1040         test_mkdir -c1 $DIR/R8a
1041         test_mkdir -c1 $DIR/R8b
1042         test_mkdir -c1 $DIR/R8a/d
1043         test_mkdir -c1 $DIR/R8b/e
1044         mrename $DIR/R8a/d $DIR/R8b/e
1045         $CHECKSTAT -a $DIR/R8a/d || error "$DIR/R8a/d exists"
1046         $CHECKSTAT -t dir $DIR/R8b/e || error "$DIR/R8b/e not dir type"
1047 }
1048 run_test 24h "mkdir .../R8{a,b}/{d,e}; rename .../R8a/d .../R8b/e"
1049
1050 test_24i() {
1051         echo "-- rename error cases"
1052         test_mkdir $DIR/R9
1053         test_mkdir $DIR/R9/a
1054         touch $DIR/R9/f
1055         mrename $DIR/R9/f $DIR/R9/a
1056         $CHECKSTAT -t file $DIR/R9/f || error "$DIR/R9/f not file type"
1057         $CHECKSTAT -t dir  $DIR/R9/a || error "$DIR/R9/a not dir type"
1058         $CHECKSTAT -a $DIR/R9/a/f || error "$DIR/R9/a/f exists"
1059 }
1060 run_test 24i "rename file to dir error: touch f ; mkdir a ; rename f a"
1061
1062 test_24j() {
1063         test_mkdir $DIR/R10
1064         mrename $DIR/R10/f $DIR/R10/g
1065         $CHECKSTAT -t dir $DIR/R10 || error "$DIR/R10 not dir type"
1066         $CHECKSTAT -a $DIR/R10/f || error "$DIR/R10/f exists"
1067         $CHECKSTAT -a $DIR/R10/g || error "$DIR/R10/g exists"
1068 }
1069 run_test 24j "source does not exist ============================"
1070
1071 test_24k() {
1072         test_mkdir $DIR/R11a
1073         test_mkdir $DIR/R11a/d
1074         touch $DIR/R11a/f
1075         mv $DIR/R11a/f $DIR/R11a/d
1076         $CHECKSTAT -a $DIR/R11a/f || error "$DIR/R11a/f exists"
1077         $CHECKSTAT -t file $DIR/R11a/d/f || error "$DIR/R11a/d/f not file type"
1078 }
1079 run_test 24k "touch .../R11a/f; mv .../R11a/f .../R11a/d ======="
1080
1081 # bug 2429 - rename foo foo foo creates invalid file
1082 test_24l() {
1083         f="$DIR/f24l"
1084         $MULTIOP $f OcNs || error "rename of ${f} to itself failed"
1085 }
1086 run_test 24l "Renaming a file to itself ========================"
1087
1088 test_24m() {
1089         f="$DIR/f24m"
1090         $MULTIOP $f OcLN ${f}2 ${f}2 || error "link ${f}2 ${f}2 failed"
1091         # on ext3 this does not remove either the source or target files
1092         # though the "expected" operation would be to remove the source
1093         $CHECKSTAT -t file ${f} || error "${f} missing"
1094         $CHECKSTAT -t file ${f}2 || error "${f}2 missing"
1095 }
1096 run_test 24m "Renaming a file to a hard link to itself ========="
1097
1098 test_24n() {
1099     f="$DIR/f24n"
1100     # this stats the old file after it was renamed, so it should fail
1101     touch ${f}
1102     $CHECKSTAT ${f} || error "${f} missing"
1103     mv ${f} ${f}.rename
1104     $CHECKSTAT ${f}.rename || error "${f}.rename missing"
1105     $CHECKSTAT -a ${f} || error "${f} exists"
1106 }
1107 run_test 24n "Statting the old file after renaming (Posix rename 2)"
1108
1109 test_24o() {
1110         test_mkdir $DIR/$tdir
1111         rename_many -s random -v -n 10 $DIR/$tdir
1112 }
1113 run_test 24o "rename of files during htree split"
1114
1115 test_24p() {
1116         test_mkdir $DIR/R12a
1117         test_mkdir $DIR/R12b
1118         DIRINO=`ls -lid $DIR/R12a | awk '{ print $1 }'`
1119         mrename $DIR/R12a $DIR/R12b
1120         $CHECKSTAT -a $DIR/R12a || error "$DIR/R12a exists"
1121         $CHECKSTAT -t dir $DIR/R12b || error "$DIR/R12b not dir type"
1122         DIRINO2=`ls -lid $DIR/R12b | awk '{ print $1 }'`
1123         [ "$DIRINO" = "$DIRINO2" ] || error "R12a $DIRINO != R12b $DIRINO2"
1124 }
1125 run_test 24p "mkdir .../R12{a,b}; rename .../R12a .../R12b"
1126
1127 cleanup_multiop_pause() {
1128         trap 0
1129         kill -USR1 $MULTIPID
1130 }
1131
1132 test_24q() {
1133         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1134
1135         test_mkdir $DIR/R13a
1136         test_mkdir $DIR/R13b
1137         local DIRINO=$(ls -lid $DIR/R13a | awk '{ print $1 }')
1138         multiop_bg_pause $DIR/R13b D_c || error "multiop failed to start"
1139         MULTIPID=$!
1140
1141         trap cleanup_multiop_pause EXIT
1142         mrename $DIR/R13a $DIR/R13b
1143         $CHECKSTAT -a $DIR/R13a || error "R13a still exists"
1144         $CHECKSTAT -t dir $DIR/R13b || error "R13b does not exist"
1145         local DIRINO2=$(ls -lid $DIR/R13b | awk '{ print $1 }')
1146         [ "$DIRINO" = "$DIRINO2" ] || error "R13a $DIRINO != R13b $DIRINO2"
1147         cleanup_multiop_pause
1148         wait $MULTIPID || error "multiop close failed"
1149 }
1150 run_test 24q "mkdir .../R13{a,b}; open R13b rename R13a R13b ==="
1151
1152 test_24r() { #bug 3789
1153         test_mkdir $DIR/R14a
1154         test_mkdir $DIR/R14a/b
1155         mrename $DIR/R14a $DIR/R14a/b && error "rename to subdir worked!"
1156         $CHECKSTAT -t dir $DIR/R14a || error "$DIR/R14a missing"
1157         $CHECKSTAT -t dir $DIR/R14a/b || error "$DIR/R14a/b missing"
1158 }
1159 run_test 24r "mkdir .../R14a/b; rename .../R14a .../R14a/b ====="
1160
1161 test_24s() {
1162         test_mkdir $DIR/R15a
1163         test_mkdir $DIR/R15a/b
1164         test_mkdir $DIR/R15a/b/c
1165         mrename $DIR/R15a $DIR/R15a/b/c && error "rename to sub-subdir worked!"
1166         $CHECKSTAT -t dir $DIR/R15a || error "$DIR/R15a missing"
1167         $CHECKSTAT -t dir $DIR/R15a/b/c || error "$DIR/R15a/b/c missing"
1168 }
1169 run_test 24s "mkdir .../R15a/b/c; rename .../R15a .../R15a/b/c ="
1170 test_24t() {
1171         test_mkdir $DIR/R16a
1172         test_mkdir $DIR/R16a/b
1173         test_mkdir $DIR/R16a/b/c
1174         mrename $DIR/R16a/b/c $DIR/R16a && error "rename to sub-subdir worked!"
1175         $CHECKSTAT -t dir $DIR/R16a || error "$DIR/R16a missing"
1176         $CHECKSTAT -t dir $DIR/R16a/b/c || error "$DIR/R16a/b/c missing"
1177 }
1178 run_test 24t "mkdir .../R16a/b/c; rename .../R16a/b/c .../R16a ="
1179
1180 test_24u() { # bug12192
1181         $MULTIOP $DIR/$tfile C2w$((2048 * 1024))c || error "multiop failed"
1182         $CHECKSTAT -s $((2048 * 1024)) $DIR/$tfile || error "wrong file size"
1183 }
1184 run_test 24u "create stripe file"
1185
1186 simple_cleanup_common() {
1187         local createmany=$1
1188         local rc=0
1189
1190         [[ -z "$DIR" || -z "$tdir" || ! -d "$DIR/$tdir" ]] && return 0
1191
1192         local start=$SECONDS
1193
1194         [[ -n "$createmany" ]] && unlinkmany $DIR/$tdir/$tfile $createmany
1195         rm -rf $DIR/$tdir || error "cleanup $DIR/$tdir failed"
1196         rc=$?
1197         wait_delete_completed
1198         echo "cleanup time $((SECONDS - start))"
1199         return $rc
1200 }
1201
1202 max_pages_per_rpc() {
1203         local mdtname="$(printf "MDT%04x" ${1:-0})"
1204         $LCTL get_param -n mdc.*$mdtname*.max_pages_per_rpc
1205 }
1206
1207 test_24v() {
1208         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1209
1210         local nrfiles=${COUNT:-100000}
1211         local fname="$DIR/$tdir/$tfile"
1212
1213         # Performance issue on ZFS see LU-4072 (c.f. LU-2887)
1214         [ "$mds1_FSTYPE" = "zfs" ] && nrfiles=${COUNT:-10000}
1215
1216         test_mkdir "$(dirname $fname)"
1217         # assume MDT0000 has the fewest inodes
1218         local stripes=$($LFS getdirstripe -c $(dirname $fname))
1219         local free_inodes=$(($(mdt_free_inodes 0) * ${stripes/#0/1}))
1220         [[ $free_inodes -lt $nrfiles ]] && nrfiles=$free_inodes
1221
1222         stack_trap "simple_cleanup_common $nrfiles"
1223
1224         createmany -m "$fname" $nrfiles
1225
1226         cancel_lru_locks mdc
1227         lctl set_param mdc.*.stats clear
1228
1229         # was previously test_24D: LU-6101
1230         # readdir() returns correct number of entries after cursor reload
1231         local num_ls=$(ls $DIR/$tdir | wc -l)
1232         local num_uniq=$(ls $DIR/$tdir | sort -u | wc -l)
1233         local num_all=$(ls -a $DIR/$tdir | wc -l)
1234         if [ $num_ls -ne $nrfiles ] || [ $num_uniq -ne $nrfiles ] ||
1235                 [ $num_all -ne $((nrfiles + 2)) ]; then
1236                         error "Expected $nrfiles files, got $num_ls " \
1237                                 "($num_uniq unique $num_all .&..)"
1238         fi
1239         # LU-5 large readdir
1240         # dirent_size = 32 bytes for sizeof(struct lu_dirent) +
1241         #               N bytes for name (len($nrfiles) rounded to 8 bytes) +
1242         #               8 bytes for luda_type (4 bytes rounded to 8 bytes)
1243         # take into account of overhead in lu_dirpage header and end mark in
1244         # each page, plus one in rpc_num calculation.
1245         local dirent_size=$((32 + (${#tfile} | 7) + 1 + 8))
1246         local page_entries=$(((PAGE_SIZE - 24) / dirent_size))
1247         local mdt_idx=$($LFS getdirstripe -i $(dirname $fname))
1248         local rpc_pages=$(max_pages_per_rpc $mdt_idx)
1249         local rpc_max=$((nrfiles / (page_entries * rpc_pages) + stripes))
1250         local mds_readpage=$(calc_stats mdc.*.stats mds_readpage)
1251         echo "readpages: $mds_readpage rpc_max: $rpc_max-2/+1"
1252         (( $mds_readpage >= $rpc_max - 2 && $mds_readpage <= $rpc_max + 1)) ||
1253                 error "large readdir doesn't take effect: " \
1254                       "$mds_readpage should be about $rpc_max"
1255 }
1256 run_test 24v "list large directory (test hash collision, b=17560)"
1257
1258 test_24w() { # bug21506
1259         SZ1=234852
1260         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=4096 || return 1
1261         dd if=/dev/zero bs=$SZ1 count=1 >> $DIR/$tfile || return 2
1262         dd if=$DIR/$tfile of=$DIR/${tfile}_left bs=1M skip=4097 || return 3
1263         SZ2=`ls -l $DIR/${tfile}_left | awk '{print $5}'`
1264         [[ "$SZ1" -eq "$SZ2" ]] ||
1265                 error "Error reading at the end of the file $tfile"
1266 }
1267 run_test 24w "Reading a file larger than 4Gb"
1268
1269 test_24x() {
1270         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
1271         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1272         [[ $MDS1_VERSION -lt $(version_code 2.7.56) ]] &&
1273                 skip "Need MDS version at least 2.7.56"
1274
1275         local MDTIDX=1
1276         local remote_dir=$DIR/$tdir/remote_dir
1277
1278         test_mkdir $DIR/$tdir
1279         $LFS mkdir -i $MDTIDX $remote_dir ||
1280                 error "create remote directory failed"
1281
1282         test_mkdir $DIR/$tdir/src_dir
1283         touch $DIR/$tdir/src_file
1284         test_mkdir $remote_dir/tgt_dir
1285         touch $remote_dir/tgt_file
1286
1287         mrename $DIR/$tdir/src_dir $remote_dir/tgt_dir ||
1288                 error "rename dir cross MDT failed!"
1289
1290         mrename $DIR/$tdir/src_file $remote_dir/tgt_file ||
1291                 error "rename file cross MDT failed!"
1292
1293         touch $DIR/$tdir/ln_file
1294         ln $DIR/$tdir/ln_file $remote_dir/ln_name ||
1295                 error "ln file cross MDT failed"
1296
1297         rm -rf $DIR/$tdir || error "Can not delete directories"
1298 }
1299 run_test 24x "cross MDT rename/link"
1300
1301 test_24y() {
1302         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
1303         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1304
1305         local remote_dir=$DIR/$tdir/remote_dir
1306         local mdtidx=1
1307
1308         test_mkdir $DIR/$tdir
1309         $LFS mkdir -i $mdtidx $remote_dir ||
1310                 error "create remote directory failed"
1311
1312         test_mkdir $remote_dir/src_dir
1313         touch $remote_dir/src_file
1314         test_mkdir $remote_dir/tgt_dir
1315         touch $remote_dir/tgt_file
1316
1317         mrename $remote_dir/src_dir $remote_dir/tgt_dir ||
1318                 error "rename subdir in the same remote dir failed!"
1319
1320         mrename $remote_dir/src_file $remote_dir/tgt_file ||
1321                 error "rename files in the same remote dir failed!"
1322
1323         ln $remote_dir/tgt_file $remote_dir/tgt_file1 ||
1324                 error "link files in the same remote dir failed!"
1325
1326         rm -rf $DIR/$tdir || error "Can not delete directories"
1327 }
1328 run_test 24y "rename/link on the same dir should succeed"
1329
1330 test_24z() {
1331         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
1332         [[ $MDS1_VERSION -lt $(version_code 2.12.51) ]] &&
1333                 skip "Need MDS version at least 2.12.51"
1334
1335         local index
1336
1337         for index in 0 1; do
1338                 $LFS mkdir -i $index $DIR/$tdir.$index || error "mkdir failed"
1339                 touch $DIR/$tdir.0/$tfile.$index || error "touch failed"
1340         done
1341
1342         mv $DIR/$tdir.0/$tfile.0 $DIR/$tdir.1 || error "mv $tfile.0 failed"
1343
1344         index=$($LFS getstripe -m $DIR/$tdir.1/$tfile.0)
1345         [ $index -eq 0 ] || error "$tfile.0 is on MDT$index"
1346
1347         local mdts=$(comma_list $(mdts_nodes))
1348
1349         do_nodes $mdts $LCTL set_param mdt.*.enable_remote_rename=0
1350         stack_trap "do_nodes $mdts $LCTL \
1351                 set_param mdt.*.enable_remote_rename=1" EXIT
1352
1353         mv $DIR/$tdir.0/$tfile.1 $DIR/$tdir.1 || error "mv $tfile.1 failed"
1354
1355         index=$($LFS getstripe -m $DIR/$tdir.1/$tfile.1)
1356         [ $index -eq 1 ] || error "$tfile.1 is on MDT$index"
1357 }
1358 run_test 24z "cross-MDT rename is done as cp"
1359
1360 test_24A() { # LU-3182
1361         local NFILES=5000
1362
1363         test_mkdir $DIR/$tdir
1364         stack_trap "simple_cleanup_common $NFILES"
1365         createmany -m $DIR/$tdir/$tfile $NFILES
1366         local t=$(ls $DIR/$tdir | wc -l)
1367         local u=$(ls $DIR/$tdir | sort -u | wc -l)
1368         local v=$(ls -ai $DIR/$tdir | sort -u | wc -l)
1369
1370         (( $t == $NFILES && $u == $NFILES && $v == NFILES + 2 )) ||
1371                 error "Expected $NFILES files, got $t ($u unique $v .&..)"
1372 }
1373 run_test 24A "readdir() returns correct number of entries."
1374
1375 test_24B() { # LU-4805
1376         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
1377
1378         local count
1379
1380         test_mkdir $DIR/$tdir
1381         $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir ||
1382                 error "create striped dir failed"
1383
1384         count=$(ls -ai $DIR/$tdir/striped_dir | wc -l)
1385         [ $count -eq 2 ] || error "Expected 2, got $count"
1386
1387         touch $DIR/$tdir/striped_dir/a
1388
1389         count=$(ls -ai $DIR/$tdir/striped_dir | wc -l)
1390         [ $count -eq 3 ] || error "Expected 3, got $count"
1391
1392         touch $DIR/$tdir/striped_dir/.f
1393
1394         count=$(ls -ai $DIR/$tdir/striped_dir | wc -l)
1395         [ $count -eq 4 ] || error "Expected 4, got $count"
1396
1397         rm -rf $DIR/$tdir || error "Can not delete directories"
1398 }
1399 run_test 24B "readdir for striped dir return correct number of entries"
1400
1401 test_24C() {
1402         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
1403
1404         mkdir $DIR/$tdir
1405         mkdir $DIR/$tdir/d0
1406         mkdir $DIR/$tdir/d1
1407
1408         $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/d0/striped_dir ||
1409                 error "create striped dir failed"
1410
1411         cd $DIR/$tdir/d0/striped_dir
1412
1413         local d0_ino=$(ls -i -l -a $DIR/$tdir | grep "d0" | awk '{print $1}')
1414         local d1_ino=$(ls -i -l -a $DIR/$tdir | grep "d1" | awk '{print $1}')
1415         local parent_ino=$(ls -i -l -a | grep "\.\." | awk '{print $1}')
1416
1417         [ "$d0_ino" = "$parent_ino" ] ||
1418                 error ".. wrong, expect $d0_ino, get $parent_ino"
1419
1420         mv $DIR/$tdir/d0/striped_dir $DIR/$tdir/d1/ ||
1421                 error "mv striped dir failed"
1422
1423         parent_ino=$(ls -i -l -a | grep "\.\." | awk '{print $1}')
1424
1425         [ "$d1_ino" = "$parent_ino" ] ||
1426                 error ".. wrong after mv, expect $d1_ino, get $parent_ino"
1427 }
1428 run_test 24C "check .. in striped dir"
1429
1430 test_24E() {
1431         [[ $MDSCOUNT -lt 4 ]] && skip_env "needs >= 4 MDTs"
1432         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1433
1434         mkdir -p $DIR/$tdir
1435         mkdir $DIR/$tdir/src_dir
1436         $LFS mkdir -i 1 $DIR/$tdir/src_dir/src_child ||
1437                 error "create remote source failed"
1438
1439         touch $DIR/$tdir/src_dir/src_child/a
1440
1441         $LFS mkdir -i 2 $DIR/$tdir/tgt_dir ||
1442                 error "create remote target dir failed"
1443
1444         $LFS mkdir -i 3 $DIR/$tdir/tgt_dir/tgt_child ||
1445                 error "create remote target child failed"
1446
1447         mrename $DIR/$tdir/src_dir/src_child $DIR/$tdir/tgt_dir/tgt_child ||
1448                 error "rename dir cross MDT failed!"
1449
1450         find $DIR/$tdir
1451
1452         $CHECKSTAT -t dir $DIR/$tdir/src_dir/src_child &&
1453                 error "src_child still exists after rename"
1454
1455         $CHECKSTAT -t file $DIR/$tdir/tgt_dir/tgt_child/a ||
1456                 error "missing file(a) after rename"
1457
1458         rm -rf $DIR/$tdir || error "Can not delete directories"
1459 }
1460 run_test 24E "cross MDT rename/link"
1461
1462 test_24F () {
1463         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return 0
1464
1465         local repeats=1000
1466         [ "$SLOW" = "no" ] && repeats=100
1467
1468         mkdir -p $DIR/$tdir
1469
1470         echo "$repeats repeats"
1471         for ((i = 0; i < repeats; i++)); do
1472                 $LFS mkdir -i0 -c2 $DIR/$tdir/test || error "mkdir fails"
1473                 touch $DIR/$tdir/test/a || error "touch fails"
1474                 mkdir $DIR/$tdir/test/b || error "mkdir fails"
1475                 rm -rf $DIR/$tdir/test || error "rmdir fails"
1476         done
1477
1478         true
1479 }
1480 run_test 24F "hash order vs readdir (LU-11330)"
1481
1482 test_24G () {
1483         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
1484
1485         local ino1
1486         local ino2
1487
1488         $LFS mkdir -i 0 $DIR/$tdir-0 || error "mkdir $tdir-0"
1489         $LFS mkdir -i 1 $DIR/$tdir-1 || error "mkdir $tdir-1"
1490         touch $DIR/$tdir-0/f1 || error "touch f1"
1491         ln -s $DIR/$tdir-0/f1 $DIR/$tdir-0/s1 || error "ln s1"
1492         ino1=$(stat -c%i $DIR/$tdir-0/s1)
1493         mv $DIR/$tdir-0/s1 $DIR/$tdir-1 || error "mv s1"
1494         ino2=$(stat -c%i $DIR/$tdir-1/s1)
1495         [ $ino1 -ne $ino2 ] || error "s1 should be migrated"
1496 }
1497 run_test 24G "migrate symlink in rename"
1498
1499 test_25a() {
1500         echo '== symlink sanity ============================================='
1501
1502         test_mkdir $DIR/d25
1503         ln -s d25 $DIR/s25
1504         touch $DIR/s25/foo ||
1505                 error "File creation in symlinked directory failed"
1506 }
1507 run_test 25a "create file in symlinked directory ==============="
1508
1509 test_25b() {
1510         [ ! -d $DIR/d25 ] && test_25a
1511         $CHECKSTAT -t file $DIR/s25/foo || error "$DIR/s25/foo not file type"
1512 }
1513 run_test 25b "lookup file in symlinked directory ==============="
1514
1515 test_26a() {
1516         test_mkdir $DIR/d26
1517         test_mkdir $DIR/d26/d26-2
1518         ln -s d26/d26-2 $DIR/s26
1519         touch $DIR/s26/foo || error "File creation failed"
1520 }
1521 run_test 26a "multiple component symlink ======================="
1522
1523 test_26b() {
1524         test_mkdir -p $DIR/$tdir/d26-2
1525         ln -s $tdir/d26-2/foo $DIR/s26-2
1526         touch $DIR/s26-2 || error "File creation failed"
1527 }
1528 run_test 26b "multiple component symlink at end of lookup ======"
1529
1530 test_26c() {
1531         test_mkdir $DIR/d26.2
1532         touch $DIR/d26.2/foo
1533         ln -s d26.2 $DIR/s26.2-1
1534         ln -s s26.2-1 $DIR/s26.2-2
1535         ln -s s26.2-2 $DIR/s26.2-3
1536         chmod 0666 $DIR/s26.2-3/foo
1537 }
1538 run_test 26c "chain of symlinks"
1539
1540 # recursive symlinks (bug 439)
1541 test_26d() {
1542         ln -s d26-3/foo $DIR/d26-3
1543 }
1544 run_test 26d "create multiple component recursive symlink"
1545
1546 test_26e() {
1547         [ ! -h $DIR/d26-3 ] && test_26d
1548         rm $DIR/d26-3
1549 }
1550 run_test 26e "unlink multiple component recursive symlink"
1551
1552 # recursive symlinks (bug 7022)
1553 test_26f() {
1554         test_mkdir $DIR/$tdir
1555         test_mkdir $DIR/$tdir/$tfile
1556         cd $DIR/$tdir/$tfile           || error "cd $DIR/$tdir/$tfile failed"
1557         test_mkdir -p lndir/bar1
1558         test_mkdir $DIR/$tdir/$tfile/$tfile
1559         cd $tfile                || error "cd $tfile failed"
1560         ln -s .. dotdot          || error "ln dotdot failed"
1561         ln -s dotdot/lndir lndir || error "ln lndir failed"
1562         cd $DIR/$tdir                 || error "cd $DIR/$tdir failed"
1563         output=`ls $tfile/$tfile/lndir/bar1`
1564         [ "$output" = bar1 ] && error "unexpected output"
1565         rm -r $tfile             || error "rm $tfile failed"
1566         $CHECKSTAT -a $DIR/$tfile || error "$tfile not gone"
1567 }
1568 run_test 26f "rm -r of a directory which has recursive symlink"
1569
1570 test_27a() {
1571         test_mkdir $DIR/$tdir
1572         $LFS getstripe $DIR/$tdir
1573         $LFS setstripe -c 1 $DIR/$tdir/$tfile || error "setstripe failed"
1574         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "checkstat failed"
1575         cp /etc/hosts $DIR/$tdir/$tfile || error "Can't copy to one stripe file"
1576 }
1577 run_test 27a "one stripe file"
1578
1579 test_27b() {
1580         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1581
1582         test_mkdir $DIR/$tdir
1583         $LFS setstripe -c 2 $DIR/$tdir/$tfile || error "setstripe failed"
1584         $LFS getstripe -c $DIR/$tdir/$tfile
1585         [ $($LFS getstripe -c $DIR/$tdir/$tfile) -eq 2 ] ||
1586                 error "two-stripe file doesn't have two stripes"
1587
1588         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
1589 }
1590 run_test 27b "create and write to two stripe file"
1591
1592 # 27c family tests specific striping, setstripe -o
1593 test_27ca() {
1594         [[ $OSTCOUNT -lt 2 ]] && skip_env "skipping 2-stripe test"
1595         test_mkdir -p $DIR/$tdir
1596         local osts="1"
1597
1598         $LFS setstripe -o $osts $DIR/$tdir/$tfile  || error "setstripe failed"
1599         $LFS getstripe -i $DIR/$tdir/$tfile
1600         [ $($LFS getstripe -i $DIR/$tdir/$tfile ) -eq $osts ] ||
1601                 error "stripe not on specified OST"
1602
1603         dd if=/dev/zero of=$DIR/$tdir/$tfile  bs=1M count=4 || error "dd failed"
1604 }
1605 run_test 27ca "one stripe on specified OST"
1606
1607 test_27cb() {
1608         [[ $OSTCOUNT -lt 2 ]] && skip_env "skipping 2-stripe test"
1609         test_mkdir -p $DIR/$tdir
1610         local osts="1,0"
1611         $LFS setstripe -o $osts $DIR/$tdir/$tfile || error "setstripe failed"
1612         local getstripe=$($LFS getstripe $DIR/$tdir/$tfile)
1613         echo "$getstripe"
1614
1615         # Strip getstripe output to a space separated list of OSTs
1616         local getstripe_osts=$(echo "$getstripe" | sed -e '1,/obdidx/d' |\
1617                 awk '{print $1}' | tr '\n' ' ' | sed -e 's/[[:space:]]*$//')
1618         [ "$getstripe_osts" = "${osts//,/ }" ] ||
1619                 error "stripes not on specified OSTs"
1620
1621         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 || error "dd failed"
1622 }
1623 run_test 27cb "two stripes on specified OSTs"
1624
1625 test_27cc() {
1626         [[ $OSTCOUNT -lt 2 ]] && skip_env "skipping 2-stripe test"
1627         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
1628                 skip "server does not support overstriping"
1629
1630         test_mkdir -p $DIR/$tdir
1631         local osts="0,0"
1632         $LFS setstripe -o $osts $DIR/$tdir/$tfile || error "setstripe failed"
1633         local getstripe=$($LFS getstripe $DIR/$tdir/$tfile)
1634         echo "$getstripe"
1635
1636         # Strip getstripe output to a space separated list of OSTs
1637         local getstripe_osts=$(echo "$getstripe" | sed -e '1,/obdidx/d' |\
1638                 awk '{print $1}' | tr '\n' ' ' | sed -e 's/[[:space:]]*$//')
1639         [ "$getstripe_osts" = "${osts//,/ }" ] ||
1640                 error "stripes not on specified OSTs"
1641
1642         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 || error "dd failed"
1643 }
1644 run_test 27cc "two stripes on the same OST"
1645
1646 test_27cd() {
1647         [[ $OSTCOUNT -lt 2 ]] && skip_env "skipping 2-stripe test"
1648         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
1649                 skip "server does not support overstriping"
1650         test_mkdir -p $DIR/$tdir
1651         local osts="0,1,1,0"
1652         $LFS setstripe -o $osts $DIR/$tdir/$tfile || error "setstripe failed"
1653         local getstripe=$($LFS getstripe $DIR/$tdir/$tfile)
1654         echo "$getstripe"
1655
1656         # Strip getstripe output to a space separated list of OSTs
1657         local getstripe_osts=$(echo "$getstripe" | sed -e '1,/obdidx/d' |\
1658                 awk '{print $1}' | tr '\n' ' ' | sed -e 's/[[:space:]]*$//')
1659         [ "$getstripe_osts" = "${osts//,/ }" ] ||
1660                 error "stripes not on specified OSTs"
1661
1662         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 || error "dd failed"
1663 }
1664 run_test 27cd "four stripes on two OSTs"
1665
1666 test_27ce() {
1667         [[ $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
1668                 skip_env "too many osts, skipping"
1669         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
1670                 skip "server does not support overstriping"
1671         # We do one more stripe than we have OSTs
1672         [ $OSTCOUNT -lt 159 ] || large_xattr_enabled ||
1673                 skip_env "ea_inode feature disabled"
1674
1675         test_mkdir -p $DIR/$tdir
1676         local osts=""
1677         for i in $(seq 0 $OSTCOUNT);
1678         do
1679                 osts=$osts"0"
1680                 if [ $i -ne $OSTCOUNT ]; then
1681                         osts=$osts","
1682                 fi
1683         done
1684         $LFS setstripe -o $osts $DIR/$tdir/$tfile || error "setstripe failed"
1685         local getstripe=$($LFS getstripe $DIR/$tdir/$tfile)
1686         echo "$getstripe"
1687
1688         # Strip getstripe output to a space separated list of OSTs
1689         local getstripe_osts=$(echo "$getstripe" | sed -e '1,/obdidx/d' |\
1690                 awk '{print $1}' | tr '\n' ' ' | sed -e 's/[[:space:]]*$//')
1691         [ "$getstripe_osts" = "${osts//,/ }" ] ||
1692                 error "stripes not on specified OSTs"
1693
1694         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 || error "dd failed"
1695 }
1696 run_test 27ce "more stripes than OSTs with -o"
1697
1698 test_27cf() {
1699         local osp_proc="osp.$FSNAME-OST0000-osc-MDT000*.active"
1700         local pid=0
1701
1702         test_mkdir -p $DIR/$tdir || error "failed to mkdir $DIR/$tdir"
1703         do_facet $SINGLEMDS "$LCTL set_param -n $osp_proc=0"
1704         stack_trap "do_facet $SINGLEMDS $LCTL set_param -n $osp_proc=1" EXIT
1705         wait_update_facet $SINGLEMDS "$LCTL get_param -n $osp_proc | grep 1" ||
1706                 error "failed to set $osp_proc=0"
1707
1708         $LFS setstripe -o 0 $DIR/$tdir/$tfile &
1709         pid=$!
1710         sleep 1
1711         do_facet $SINGLEMDS "$LCTL set_param -n $osp_proc=1"
1712         wait_update_facet $SINGLEMDS "$LCTL get_param -n $osp_proc | grep 0" ||
1713                 error "failed to set $osp_proc=1"
1714         wait $pid
1715         [[ $pid -ne 0 ]] ||
1716                 error "should return error due to $osp_proc=0"
1717 }
1718 run_test 27cf "'setstripe -o' on inactive OSTs should return error"
1719
1720 test_27d() {
1721         test_mkdir $DIR/$tdir
1722         $LFS setstripe -c 0 -i -1 -S 0 $DIR/$tdir/$tfile ||
1723                 error "setstripe failed"
1724         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "checkstat failed"
1725         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
1726 }
1727 run_test 27d "create file with default settings"
1728
1729 test_27e() {
1730         # LU-5839 adds check for existed layout before setting it
1731         [[ $MDS1_VERSION -lt $(version_code 2.7.56) ]] &&
1732                 skip "Need MDS version at least 2.7.56"
1733
1734         test_mkdir $DIR/$tdir
1735         $LFS setstripe -c 2 $DIR/$tdir/$tfile || error "setstripe failed"
1736         $LFS setstripe -c 2 $DIR/$tdir/$tfile && error "setstripe worked twice"
1737         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "checkstat failed"
1738 }
1739 run_test 27e "setstripe existing file (should return error)"
1740
1741 test_27f() {
1742         test_mkdir $DIR/$tdir
1743         $LFS setstripe -S 100 -i 0 -c 1 $DIR/$tdir/$tfile &&
1744                 error "$LFS setstripe $DIR/$tdir/$tfile failed"
1745         $CHECKSTAT -t file $DIR/$tdir/$tfile &&
1746                 error "$CHECKSTAT -t file $DIR/$tdir/$tfile should fail"
1747         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
1748         $LFS getstripe $DIR/$tdir/$tfile || error "$LFS getstripe failed"
1749 }
1750 run_test 27f "setstripe with bad stripe size (should return error)"
1751
1752 test_27g() {
1753         test_mkdir $DIR/$tdir
1754         $MCREATE $DIR/$tdir/$tfile || error "mcreate failed"
1755         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "no stripe info" ||
1756                 error "$DIR/$tdir/$tfile has object"
1757 }
1758 run_test 27g "$LFS getstripe with no objects"
1759
1760 test_27ga() {
1761         test_mkdir $DIR/$tdir
1762         touch $DIR/$tdir/$tfile || error "touch failed"
1763         ln -s bogus $DIR/$tdir/$tfile.2 || error "ln failed"
1764         $LFS getstripe -m $DIR/$tdir/$tfile $DIR/$tdir/$tfile.2
1765         local rc=$?
1766         (( rc == 2 )) || error "getstripe did not return ENOENT"
1767 }
1768 run_test 27ga "$LFS getstripe with missing file (should return error)"
1769
1770 test_27i() {
1771         test_mkdir $DIR/$tdir
1772         touch $DIR/$tdir/$tfile || error "touch failed"
1773         [[ $($LFS getstripe -c $DIR/$tdir/$tfile) -gt 0 ]] ||
1774                 error "missing objects"
1775 }
1776 run_test 27i "$LFS getstripe with some objects"
1777
1778 test_27j() {
1779         test_mkdir $DIR/$tdir
1780         $LFS setstripe -i $OSTCOUNT $DIR/$tdir/$tfile &&
1781                 error "setstripe failed" || true
1782 }
1783 run_test 27j "setstripe with bad stripe offset (should return error)"
1784
1785 test_27k() { # bug 2844
1786         test_mkdir $DIR/$tdir
1787         local file=$DIR/$tdir/$tfile
1788         local ll_max_blksize=$((4 * 1024 * 1024))
1789         $LFS setstripe -S 67108864 $file || error "setstripe failed"
1790         local blksize=$(stat $file | awk '/IO Block:/ { print $7 }')
1791         [ $blksize -le $ll_max_blksize ] || error "1:$blksize > $ll_max_blksize"
1792         dd if=/dev/zero of=$file bs=4k count=1
1793         blksize=$(stat $file | awk '/IO Block:/ { print $7 }')
1794         [ $blksize -le $ll_max_blksize ] || error "2:$blksize > $ll_max_blksize"
1795 }
1796 run_test 27k "limit i_blksize for broken user apps"
1797
1798 test_27l() {
1799         mcreate $DIR/$tfile || error "creating file"
1800         $RUNAS $LFS setstripe -c 1 $DIR/$tfile &&
1801                 error "setstripe should have failed" || true
1802 }
1803 run_test 27l "check setstripe permissions (should return error)"
1804
1805 test_27m() {
1806         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1807
1808         [ -n "$RCLIENTS" -o -n "$MOUNT_2" ] &&
1809                 skip_env "multiple clients -- skipping"
1810
1811         ORIGFREE=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
1812                    head -n1)
1813         if [[ $ORIGFREE -gt $MAXFREE ]]; then
1814                 skip "$ORIGFREE > $MAXFREE skipping out-of-space test on OST0"
1815         fi
1816         stack_trap simple_cleanup_common
1817         test_mkdir $DIR/$tdir
1818         $LFS setstripe -i 0 -c 1 $DIR/$tdir/$tfile.1
1819         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=1024 count=$MAXFREE &&
1820                 error "dd should fill OST0"
1821         i=2
1822         while $LFS setstripe -i 0 -c 1 $DIR/$tdir/$tfile.$i; do
1823                 i=$((i + 1))
1824                 [ $i -gt 256 ] && break
1825         done
1826         i=$((i + 1))
1827         touch $DIR/$tdir/$tfile.$i
1828         [ $($LFS getstripe $DIR/$tdir/$tfile.$i | grep -A 10 obdidx |
1829             awk '{print $1}'| grep -w "0") ] &&
1830                 error "OST0 was full but new created file still use it"
1831         i=$((i + 1))
1832         touch $DIR/$tdir/$tfile.$i
1833         [ $($LFS getstripe $DIR/$tdir/$tfile.$i | grep -A 10 obdidx |
1834             awk '{print $1}'| grep -w "0") ] &&
1835                 error "OST0 was full but new created file still use it" || true
1836 }
1837 run_test 27m "create file while OST0 was full"
1838
1839 # OSCs keep a NOSPC flag that will be reset after ~5s (qos_maxage)
1840 # if the OST isn't full anymore.
1841 reset_enospc() {
1842         local ostidx=${1:-""}
1843         local delay
1844         local ready
1845         local get_prealloc
1846
1847         local list=$(comma_list $(osts_nodes))
1848         [ "$ostidx" ] && list=$(facet_host ost$((ostidx + 1)))
1849
1850         do_nodes $list lctl set_param fail_loc=0
1851         wait_delete_completed   # initiate all OST_DESTROYs from MDS to OST
1852         delay=$(do_facet $SINGLEMDS lctl get_param -n lov.*.qos_maxage |
1853                 awk '{print $1 * 2;exit;}')
1854         get_prealloc="$LCTL get_param -n osc.*MDT*.prealloc_status |
1855                         grep -v \"^0$\""
1856         wait_update_facet $SINGLEMDS "$get_prealloc" "" $delay
1857 }
1858
1859 test_27n() {
1860         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1861         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1862         remote_mds_nodsh && skip "remote MDS with nodsh"
1863         remote_ost_nodsh && skip "remote OST with nodsh"
1864
1865         reset_enospc
1866         rm -f $DIR/$tdir/$tfile
1867         exhaust_precreations 0 0x80000215
1868         $LFS setstripe -c -1 $DIR/$tdir || error "setstripe failed"
1869         touch $DIR/$tdir/$tfile || error "touch failed"
1870         $LFS getstripe $DIR/$tdir/$tfile
1871         reset_enospc
1872 }
1873 run_test 27n "create file with some full OSTs"
1874
1875 test_27o() {
1876         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1877         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1878         remote_mds_nodsh && skip "remote MDS with nodsh"
1879         remote_ost_nodsh && skip "remote OST with nodsh"
1880
1881         reset_enospc
1882         rm -f $DIR/$tdir/$tfile
1883         exhaust_all_precreations 0x215
1884
1885         touch $DIR/$tdir/$tfile && error "able to create $DIR/$tdir/$tfile"
1886
1887         reset_enospc
1888         rm -rf $DIR/$tdir/*
1889 }
1890 run_test 27o "create file with all full OSTs (should error)"
1891
1892 function create_and_checktime() {
1893         local fname=$1
1894         local loops=$2
1895         local i
1896
1897         for ((i=0; i < $loops; i++)); do
1898                 local start=$SECONDS
1899                 multiop $fname-$i Oc
1900                 ((SECONDS-start < TIMEOUT)) ||
1901                         error "creation took " $((SECONDS-$start)) && return 1
1902         done
1903 }
1904
1905 test_27oo() {
1906         local mdts=$(comma_list $(mdts_nodes))
1907
1908         [ $MDS1_VERSION -lt $(version_code 2.13.57) ] &&
1909                 skip "Need MDS version at least 2.13.57"
1910
1911         local f0=$DIR/${tfile}-0
1912         local f1=$DIR/${tfile}-1
1913
1914         wait_delete_completed
1915
1916         # refill precreated objects
1917         $LFS setstripe -i0 -c1 $f0
1918
1919         saved=$(do_facet mds1 $LCTL get_param -n lov.*0000*.qos_threshold_rr)
1920         # force QoS allocation policy
1921         do_nodes $mdts $LCTL set_param lov.*.qos_threshold_rr=0%
1922         stack_trap "do_nodes $mdts $LCTL set_param \
1923                 lov.*.qos_threshold_rr=$saved" EXIT
1924         sleep_maxage
1925
1926         # one OST is unavailable, but still have few objects preallocated
1927         stop ost1
1928         stack_trap "start ost1 $(ostdevname 1) $OST_MOUNT_OPTS; \
1929                 rm -rf $f1 $DIR/$tdir*" EXIT
1930
1931         for ((i=0; i < 7; i++)); do
1932                 mkdir $DIR/$tdir$i || error "can't create dir"
1933                 $LFS setstripe -c$((OSTCOUNT-1)) $DIR/$tdir$i ||
1934                         error "can't set striping"
1935         done
1936         for ((i=0; i < 7; i++)); do
1937                 create_and_checktime $DIR/$tdir$i/$tfile 100 &
1938         done
1939         wait
1940 }
1941 run_test 27oo "don't let few threads to reserve too many objects"
1942
1943 test_27p() {
1944         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1945         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1946         remote_mds_nodsh && skip "remote MDS with nodsh"
1947         remote_ost_nodsh && skip "remote OST with nodsh"
1948
1949         reset_enospc
1950         rm -f $DIR/$tdir/$tfile
1951         test_mkdir $DIR/$tdir
1952
1953         $MCREATE $DIR/$tdir/$tfile || error "mcreate failed"
1954         $TRUNCATE $DIR/$tdir/$tfile 80000000 || error "truncate failed"
1955         $CHECKSTAT -s 80000000 $DIR/$tdir/$tfile || error "checkstat failed"
1956
1957         exhaust_precreations 0 0x80000215
1958         echo foo >> $DIR/$tdir/$tfile || error "append failed"
1959         $CHECKSTAT -s 80000004 $DIR/$tdir/$tfile || error "checkstat failed"
1960         $LFS getstripe $DIR/$tdir/$tfile
1961
1962         reset_enospc
1963 }
1964 run_test 27p "append to a truncated file with some full OSTs"
1965
1966 test_27q() {
1967         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1968         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1969         remote_mds_nodsh && skip "remote MDS with nodsh"
1970         remote_ost_nodsh && skip "remote OST with nodsh"
1971
1972         reset_enospc
1973         rm -f $DIR/$tdir/$tfile
1974
1975         mkdir_on_mdt0 $DIR/$tdir
1976         $MCREATE $DIR/$tdir/$tfile || error "mcreate $DIR/$tdir/$tfile failed"
1977         $TRUNCATE $DIR/$tdir/$tfile 80000000 ||
1978                 error "truncate $DIR/$tdir/$tfile failed"
1979         $CHECKSTAT -s 80000000 $DIR/$tdir/$tfile || error "checkstat failed"
1980
1981         exhaust_all_precreations 0x215
1982
1983         echo foo >> $DIR/$tdir/$tfile && error "append succeeded"
1984         $CHECKSTAT -s 80000000 $DIR/$tdir/$tfile || error "checkstat 2 failed"
1985
1986         reset_enospc
1987 }
1988 run_test 27q "append to truncated file with all OSTs full (should error)"
1989
1990 test_27r() {
1991         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1992         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1993         remote_mds_nodsh && skip "remote MDS with nodsh"
1994         remote_ost_nodsh && skip "remote OST with nodsh"
1995
1996         reset_enospc
1997         rm -f $DIR/$tdir/$tfile
1998         exhaust_precreations 0 0x80000215
1999
2000         $LFS setstripe -i 0 -c 2 $DIR/$tdir/$tfile || error "setstripe failed"
2001
2002         reset_enospc
2003 }
2004 run_test 27r "stripe file with some full OSTs (shouldn't LBUG) ="
2005
2006 test_27s() { # bug 10725
2007         test_mkdir $DIR/$tdir
2008         local stripe_size=$((4096 * 1024 * 1024))       # 2^32
2009         local stripe_count=0
2010         [ $OSTCOUNT -eq 1 ] || stripe_count=2
2011         $LFS setstripe -S $stripe_size -c $stripe_count $DIR/$tdir &&
2012                 error "stripe width >= 2^32 succeeded" || true
2013
2014 }
2015 run_test 27s "lsm_xfersize overflow (should error) (bug 10725)"
2016
2017 test_27t() { # bug 10864
2018         WDIR=$(pwd)
2019         WLFS=$(which lfs)
2020         cd $DIR
2021         touch $tfile
2022         $WLFS getstripe $tfile
2023         cd $WDIR
2024 }
2025 run_test 27t "check that utils parse path correctly"
2026
2027 test_27u() { # bug 4900
2028         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2029         remote_mds_nodsh && skip "remote MDS with nodsh"
2030
2031         local index
2032         local list=$(comma_list $(mdts_nodes))
2033
2034 #define OBD_FAIL_MDS_OSC_PRECREATE      0x139
2035         do_nodes $list $LCTL set_param fail_loc=0x139
2036         test_mkdir -p $DIR/$tdir
2037         stack_trap "simple_cleanup_common 1000"
2038         createmany -o $DIR/$tdir/$tfile 1000
2039         do_nodes $list $LCTL set_param fail_loc=0
2040
2041         TLOG=$TMP/$tfile.getstripe
2042         $LFS getstripe $DIR/$tdir > $TLOG
2043         OBJS=$(awk -vobj=0 '($1 == 0) { obj += 1 } END { print obj; }' $TLOG)
2044         [[ $OBJS -gt 0 ]] &&
2045                 error "$OBJS objects created on OST-0. See $TLOG" ||
2046                 rm -f $TLOG
2047 }
2048 run_test 27u "skip object creation on OSC w/o objects"
2049
2050 test_27v() { # bug 4900
2051         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2052         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2053         remote_mds_nodsh && skip "remote MDS with nodsh"
2054         remote_ost_nodsh && skip "remote OST with nodsh"
2055
2056         exhaust_all_precreations 0x215
2057         reset_enospc
2058
2059         $LFS setstripe -c 1 $DIR/$tdir         # 1 stripe / file
2060
2061         touch $DIR/$tdir/$tfile
2062         #define OBD_FAIL_TGT_DELAY_PRECREATE     0x705
2063         # all except ost1
2064         for (( i=1; i < OSTCOUNT; i++ )); do
2065                 do_facet ost$i lctl set_param fail_loc=0x705
2066         done
2067         local START=`date +%s`
2068         createmany -o $DIR/$tdir/$tfile 32
2069
2070         local FINISH=`date +%s`
2071         local TIMEOUT=`lctl get_param -n timeout`
2072         local PROCESS=$((FINISH - START))
2073         [ $PROCESS -ge $((TIMEOUT / 2)) ] && \
2074                error "$FINISH - $START >= $TIMEOUT / 2"
2075         sleep $((TIMEOUT / 2 - PROCESS))
2076         reset_enospc
2077 }
2078 run_test 27v "skip object creation on slow OST"
2079
2080 test_27w() { # bug 10997
2081         test_mkdir $DIR/$tdir
2082         $LFS setstripe -S 65536 $DIR/$tdir/f0 || error "setstripe failed"
2083         [ $($LFS getstripe -S $DIR/$tdir/f0) -ne 65536 ] &&
2084                 error "stripe size $size != 65536" || true
2085         [ $($LFS getstripe -d $DIR/$tdir | grep -c "stripe_count") -eq 0 ] &&
2086                 error "$LFS getstripe -d $DIR/$tdir no 'stripe_count'" || true
2087 }
2088 run_test 27w "check $LFS setstripe -S and getstrip -d options"
2089
2090 test_27wa() {
2091         [[ $OSTCOUNT -lt 2 ]] &&
2092                 skip_env "skipping multiple stripe count/offset test"
2093
2094         test_mkdir $DIR/$tdir
2095         for i in $(seq 1 $OSTCOUNT); do
2096                 offset=$((i - 1))
2097                 $LFS setstripe -c $i -i $offset $DIR/$tdir/f$i ||
2098                         error "setstripe -c $i -i $offset failed"
2099                 count=$($LFS getstripe -c $DIR/$tdir/f$i)
2100                 index=$($LFS getstripe -i $DIR/$tdir/f$i)
2101                 [ $count -ne $i ] && error "stripe count $count != $i" || true
2102                 [ $index -ne $offset ] &&
2103                         error "stripe offset $index != $offset" || true
2104         done
2105 }
2106 run_test 27wa "check $LFS setstripe -c -i options"
2107
2108 test_27x() {
2109         remote_ost_nodsh && skip "remote OST with nodsh"
2110         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2111         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2112
2113         OFFSET=$(($OSTCOUNT - 1))
2114         OSTIDX=0
2115         local OST=$(ostname_from_index $OSTIDX)
2116
2117         test_mkdir $DIR/$tdir
2118         $LFS setstripe -c 1 $DIR/$tdir  # 1 stripe per file
2119         do_facet ost$((OSTIDX + 1)) lctl set_param -n obdfilter.$OST.degraded 1
2120         sleep_maxage
2121         createmany -o $DIR/$tdir/$tfile $OSTCOUNT
2122         for i in $(seq 0 $OFFSET); do
2123                 [ $($LFS getstripe $DIR/$tdir/$tfile$i | grep -A 10 obdidx |
2124                         awk '{print $1}' | grep -w "$OSTIDX") ] &&
2125                 error "OST0 was degraded but new created file still use it"
2126         done
2127         do_facet ost$((OSTIDX + 1)) lctl set_param -n obdfilter.$OST.degraded 0
2128 }
2129 run_test 27x "create files while OST0 is degraded"
2130
2131 test_27y() {
2132         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2133         remote_mds_nodsh && skip "remote MDS with nodsh"
2134         remote_ost_nodsh && skip "remote OST with nodsh"
2135         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2136
2137         local mdtosc=$(get_mdtosc_proc_path $SINGLEMDS $FSNAME-OST0000)
2138         local last_id=$(do_facet $SINGLEMDS lctl get_param -n \
2139                 osp.$mdtosc.prealloc_last_id)
2140         local next_id=$(do_facet $SINGLEMDS lctl get_param -n \
2141                 osp.$mdtosc.prealloc_next_id)
2142         local fcount=$((last_id - next_id))
2143         [[ $fcount -eq 0 ]] && skip "not enough space on OST0"
2144         [[ $fcount -gt $OSTCOUNT ]] && fcount=$OSTCOUNT
2145
2146         local MDS_OSCS=$(do_facet $SINGLEMDS lctl dl |
2147                          awk '/[oO][sS][cC].*md[ts]/ { print $4 }')
2148         local OST_DEACTIVE_IDX=-1
2149         local OSC
2150         local OSTIDX
2151         local OST
2152
2153         for OSC in $MDS_OSCS; do
2154                 OST=$(osc_to_ost $OSC)
2155                 OSTIDX=$(index_from_ostuuid $OST)
2156                 if [ $OST_DEACTIVE_IDX == -1 ]; then
2157                         OST_DEACTIVE_IDX=$OSTIDX
2158                 fi
2159                 if [ $OSTIDX != $OST_DEACTIVE_IDX ]; then
2160                         echo $OSC "is Deactivated:"
2161                         do_facet $SINGLEMDS lctl --device  %$OSC deactivate
2162                 fi
2163         done
2164
2165         OSTIDX=$(index_from_ostuuid $OST)
2166         test_mkdir $DIR/$tdir
2167         $LFS setstripe -c 1 $DIR/$tdir      # 1 stripe / file
2168
2169         for OSC in $MDS_OSCS; do
2170                 OST=$(osc_to_ost $OSC)
2171                 OSTIDX=$(index_from_ostuuid $OST)
2172                 if [ $OSTIDX == $OST_DEACTIVE_IDX ]; then
2173                         echo $OST "is degraded:"
2174                         do_facet ost$((OSTIDX+1)) lctl set_param -n \
2175                                                 obdfilter.$OST.degraded=1
2176                 fi
2177         done
2178
2179         sleep_maxage
2180         createmany -o $DIR/$tdir/$tfile $fcount
2181
2182         for OSC in $MDS_OSCS; do
2183                 OST=$(osc_to_ost $OSC)
2184                 OSTIDX=$(index_from_ostuuid $OST)
2185                 if [ $OSTIDX == $OST_DEACTIVE_IDX ]; then
2186                         echo $OST "is recovered from degraded:"
2187                         do_facet ost$((OSTIDX+1)) lctl set_param -n \
2188                                                 obdfilter.$OST.degraded=0
2189                 else
2190                         do_facet $SINGLEMDS lctl --device %$OSC activate
2191                 fi
2192         done
2193
2194         # all osp devices get activated, hence -1 stripe count restored
2195         local stripe_count=0
2196
2197         # sleep 2*lod_qos_maxage seconds waiting for lod qos to notice osp
2198         # devices get activated.
2199         sleep_maxage
2200         $LFS setstripe -c -1 $DIR/$tfile
2201         stripe_count=$($LFS getstripe -c $DIR/$tfile)
2202         rm -f $DIR/$tfile
2203         [ $stripe_count -ne $OSTCOUNT ] &&
2204                 error "Of $OSTCOUNT OSTs, only $stripe_count is available"
2205         return 0
2206 }
2207 run_test 27y "create files while OST0 is degraded and the rest inactive"
2208
2209 check_seq_oid()
2210 {
2211         log "check file $1"
2212
2213         lmm_count=$($LFS getstripe -c $1)
2214         lmm_seq=$($LFS getstripe -v $1 | awk '/lmm_seq/ { print $2 }')
2215         lmm_oid=$($LFS getstripe -v $1 | awk '/lmm_object_id/ { print $2 }')
2216
2217         local old_ifs="$IFS"
2218         IFS=$'[:]'
2219         fid=($($LFS path2fid $1))
2220         IFS="$old_ifs"
2221
2222         log "FID seq ${fid[1]}, oid ${fid[2]} ver ${fid[3]}"
2223         log "LOV seq $lmm_seq, oid $lmm_oid, count: $lmm_count"
2224
2225         # compare lmm_seq and lu_fid->f_seq
2226         [ $lmm_seq = ${fid[1]} ] || { error "SEQ mismatch"; return 1; }
2227         # compare lmm_object_id and lu_fid->oid
2228         [ $lmm_oid = ${fid[2]} ] || { error "OID mismatch"; return 2; }
2229
2230         # check the trusted.fid attribute of the OST objects of the file
2231         local have_obdidx=false
2232         local stripe_nr=0
2233         $LFS getstripe $1 | while read obdidx oid hex seq; do
2234                 # skip lines up to and including "obdidx"
2235                 [ -z "$obdidx" ] && break
2236                 [ "$obdidx" = "obdidx" ] && have_obdidx=true && continue
2237                 $have_obdidx || continue
2238
2239                 local ost=$((obdidx + 1))
2240                 local dev=$(ostdevname $ost)
2241                 local oid_hex
2242
2243                 log "want: stripe:$stripe_nr ost:$obdidx oid:$oid/$hex seq:$seq"
2244
2245                 seq=$(echo $seq | sed -e "s/^0x//g")
2246                 if [ $seq == 0 ] || [ $(facet_fstype ost$ost) == zfs ]; then
2247                         oid_hex=$(echo $oid)
2248                 else
2249                         oid_hex=$(echo $hex | sed -e "s/^0x//g")
2250                 fi
2251                 local obj_file="O/$seq/d$((oid %32))/$oid_hex"
2252
2253                 local ff=""
2254                 #
2255                 # Don't unmount/remount the OSTs if we don't need to do that.
2256                 # LU-2577 changes filter_fid to be smaller, so debugfs needs
2257                 # update too, until that use mount/ll_decode_filter_fid/mount.
2258                 # Re-enable when debugfs will understand new filter_fid.
2259                 #
2260                 if [ $(facet_fstype ost$ost) == ldiskfs ]; then
2261                         ff=$(do_facet ost$ost "$DEBUGFS -c -R 'stat $obj_file' \
2262                                 $dev 2>/dev/null" | grep "parent=")
2263                 fi
2264                 if [ -z "$ff" ]; then
2265                         stop ost$ost
2266                         mount_fstype ost$ost
2267                         ff=$(do_facet ost$ost $LL_DECODE_FILTER_FID \
2268                                 $(facet_mntpt ost$ost)/$obj_file)
2269                         unmount_fstype ost$ost
2270                         start ost$ost $dev $OST_MOUNT_OPTS
2271                         clients_up
2272                 fi
2273
2274                 [ -z "$ff" ] && error "$obj_file: no filter_fid info"
2275
2276                 echo "$ff" | sed -e 's#.*objid=#got: objid=#'
2277
2278                 # /mnt/O/0/d23/23: objid=23 seq=0 parent=[0x200000400:0x1e:0x1]
2279                 # fid: objid=23 seq=0 parent=[0x200000400:0x1e:0x0] stripe=1
2280                 #
2281                 # fid: parent=[0x200000400:0x1e:0x0] stripe=1 stripe_count=2 \
2282                 #       stripe_size=1048576 component_id=1 component_start=0 \
2283                 #       component_end=33554432
2284                 local ff_parent=$(sed -e 's/.*parent=.//' <<<$ff)
2285                 local ff_pseq=$(cut -d: -f1 <<<$ff_parent)
2286                 local ff_poid=$(cut -d: -f2 <<<$ff_parent)
2287                 local ff_pstripe
2288                 if grep -q 'stripe=' <<<$ff; then
2289                         ff_pstripe=$(sed -e 's/.*stripe=//' -e 's/ .*//' <<<$ff)
2290                 else
2291                         # $LL_DECODE_FILTER_FID does not print "stripe="; look
2292                         # into f_ver in this case.  See comment on ff_parent.
2293                         ff_pstripe=$(cut -d: -f3 <<<$ff_parent | sed -e 's/]//')
2294                 fi
2295
2296                 # compare lmm_seq and filter_fid->ff_parent.f_seq
2297                 [ $ff_pseq = $lmm_seq ] ||
2298                         error "FF parent SEQ $ff_pseq != $lmm_seq"
2299                 # compare lmm_object_id and filter_fid->ff_parent.f_oid
2300                 [ $ff_poid = $lmm_oid ] ||
2301                         error "FF parent OID $ff_poid != $lmm_oid"
2302                 (($ff_pstripe == $stripe_nr)) ||
2303                         error "FF stripe $ff_pstripe != $stripe_nr"
2304
2305                 stripe_nr=$((stripe_nr + 1))
2306                 [ $CLIENT_VERSION -lt $(version_code 2.9.55) ] &&
2307                         continue
2308                 if grep -q 'stripe_count=' <<<$ff; then
2309                         local ff_scnt=$(sed -e 's/.*stripe_count=//' \
2310                                             -e 's/ .*//' <<<$ff)
2311                         [ $lmm_count = $ff_scnt ] ||
2312                                 error "FF stripe count $lmm_count != $ff_scnt"
2313                 fi
2314         done
2315 }
2316
2317 test_27z() {
2318         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2319         remote_ost_nodsh && skip "remote OST with nodsh"
2320
2321         test_mkdir $DIR/$tdir
2322         $LFS setstripe -c 1 -i 0 -S 64k $DIR/$tdir/$tfile-1 ||
2323                 { error "setstripe -c -1 failed"; return 1; }
2324         # We need to send a write to every object to get parent FID info set.
2325         # This _should_ also work for setattr, but does not currently.
2326         # touch $DIR/$tdir/$tfile-1 ||
2327         dd if=/dev/zero of=$DIR/$tdir/$tfile-1 bs=1M count=1 ||
2328                 { error "dd $tfile-1 failed"; return 2; }
2329         $LFS setstripe -c -1 -i $((OSTCOUNT - 1)) -S 1M $DIR/$tdir/$tfile-2 ||
2330                 { error "setstripe -c -1 failed"; return 3; }
2331         dd if=/dev/zero of=$DIR/$tdir/$tfile-2 bs=1M count=$OSTCOUNT ||
2332                 { error "dd $tfile-2 failed"; return 4; }
2333
2334         # make sure write RPCs have been sent to OSTs
2335         sync; sleep 5; sync
2336
2337         check_seq_oid $DIR/$tdir/$tfile-1 || return 5
2338         check_seq_oid $DIR/$tdir/$tfile-2 || return 6
2339 }
2340 run_test 27z "check SEQ/OID on the MDT and OST filesystems"
2341
2342 test_27A() { # b=19102
2343         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2344
2345         save_layout_restore_at_exit $MOUNT
2346         $LFS setstripe -c 0 -i -1 -S 0 $MOUNT
2347         wait_update $HOSTNAME "$LFS getstripe -c $MOUNT | sed 's/  *//g'" "1" 20 ||
2348                 error "stripe count $($LFS getstripe -c $MOUNT) != 1"
2349         local default_size=$($LFS getstripe -S $MOUNT)
2350         local default_offset=$($LFS getstripe -i $MOUNT)
2351         local dsize=$(do_facet $SINGLEMDS \
2352                 "$LCTL get_param -n lod.$(facet_svc $SINGLEMDS)*.stripesize")
2353         [ $default_size -eq $dsize ] ||
2354                 error "stripe size $default_size != $dsize"
2355         [ $default_offset -eq -1 ] ||
2356                 error "stripe offset $default_offset != -1"
2357 }
2358 run_test 27A "check filesystem-wide default LOV EA values"
2359
2360 test_27B() { # LU-2523
2361         test_mkdir $DIR/$tdir
2362         rm -f $DIR/$tdir/f0 $DIR/$tdir/f1
2363         touch $DIR/$tdir/f0
2364         # open f1 with O_LOV_DELAY_CREATE
2365         # rename f0 onto f1
2366         # call setstripe ioctl on open file descriptor for f1
2367         # close
2368         multiop $DIR/$tdir/f1 oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:nB1c \
2369                 $DIR/$tdir/f0
2370
2371         rm -f $DIR/$tdir/f1
2372         # open f1 with O_LOV_DELAY_CREATE
2373         # unlink f1
2374         # call setstripe ioctl on open file descriptor for f1
2375         # close
2376         multiop $DIR/$tdir/f1 oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:uB1c
2377
2378         # Allow multiop to fail in imitation of NFS's busted semantics.
2379         true
2380 }
2381 run_test 27B "call setstripe on open unlinked file/rename victim"
2382
2383 # 27C family tests full striping and overstriping
2384 test_27Ca() { #LU-2871
2385         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2386
2387         declare -a ost_idx
2388         local index
2389         local found
2390         local i
2391         local j
2392
2393         test_mkdir $DIR/$tdir
2394         cd $DIR/$tdir
2395         for i in $(seq 0 $((OSTCOUNT - 1))); do
2396                 # set stripe across all OSTs starting from OST$i
2397                 $LFS setstripe -i $i -c -1 $tfile$i
2398                 # get striping information
2399                 ost_idx=($($LFS getstripe $tfile$i |
2400                          tail -n $((OSTCOUNT + 1)) | awk '{print $1}'))
2401                 echo ${ost_idx[@]}
2402
2403                 # check the layout
2404                 [ ${#ost_idx[@]} -eq $OSTCOUNT ] ||
2405                         error "${#ost_idx[@]} != $OSTCOUNT"
2406
2407                 for index in $(seq 0 $((OSTCOUNT - 1))); do
2408                         found=0
2409                         for j in $(echo ${ost_idx[@]}); do
2410                                 if [ $index -eq $j ]; then
2411                                         found=1
2412                                         break
2413                                 fi
2414                         done
2415                         [ $found = 1 ] ||
2416                                 error "Can not find $index in ${ost_idx[@]}"
2417                 done
2418         done
2419 }
2420 run_test 27Ca "check full striping across all OSTs"
2421
2422 test_27Cb() {
2423         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2424                 skip "server does not support overstriping"
2425         [[ $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
2426                 skip_env "too many osts, skipping"
2427
2428         test_mkdir -p $DIR/$tdir
2429         local setcount=$(($OSTCOUNT * 2))
2430         [ $setcount -lt 160 ] || large_xattr_enabled ||
2431                 skip_env "ea_inode feature disabled"
2432
2433         $LFS setstripe -C $setcount $DIR/$tdir/$tfile ||
2434                 error "setstripe failed"
2435
2436         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2437         [ $count -eq $setcount ] ||
2438                 error "stripe count $count, should be $setcount"
2439
2440         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" ||
2441                 error "overstriped should be set in pattern"
2442
2443         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2444                 error "dd failed"
2445 }
2446 run_test 27Cb "more stripes than OSTs with -C"
2447
2448 test_27Cc() {
2449         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2450                 skip "server does not support overstriping"
2451         [[ $OSTCOUNT -lt 2 ]] && skip_env "need > 1 OST"
2452
2453         test_mkdir -p $DIR/$tdir
2454         local setcount=$(($OSTCOUNT - 1))
2455
2456         [ $setcount -lt 160 ] || large_xattr_enabled ||
2457                 skip_env "ea_inode feature disabled"
2458
2459         $LFS setstripe -C $setcount $DIR/$tdir/$tfile ||
2460                 error "setstripe failed"
2461
2462         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2463         [ $count -eq $setcount ] ||
2464                 error "stripe count $count, should be $setcount"
2465
2466         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" &&
2467                 error "overstriped should not be set in pattern"
2468
2469         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2470                 error "dd failed"
2471 }
2472 run_test 27Cc "fewer stripes than OSTs does not set overstriping"
2473
2474 test_27Cd() {
2475         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2476                 skip "server does not support overstriping"
2477         [[ $OSTCOUNT -lt 2 ]] && skip_env "need > 1 OST"
2478         large_xattr_enabled || skip_env "ea_inode feature disabled"
2479
2480         test_mkdir -p $DIR/$tdir
2481         local setcount=$LOV_MAX_STRIPE_COUNT
2482
2483         $LFS setstripe -C $setcount $DIR/$tdir/$tfile ||
2484                 error "setstripe failed"
2485
2486         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2487         [ $count -eq $setcount ] ||
2488                 error "stripe count $count, should be $setcount"
2489
2490         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" ||
2491                 error "overstriped should be set in pattern"
2492
2493         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2494                 error "dd failed"
2495
2496         rm -f $DIR/$tdir/$tfile || error "Delete $tfile failed"
2497 }
2498 run_test 27Cd "test maximum stripe count"
2499
2500 test_27Ce() {
2501         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2502                 skip "server does not support overstriping"
2503         test_mkdir -p $DIR/$tdir
2504
2505         pool_add $TESTNAME || error "Pool creation failed"
2506         pool_add_targets $TESTNAME 0 || error "pool_add_targets failed"
2507
2508         local setcount=8
2509
2510         $LFS setstripe  -C $setcount -p "$TESTNAME" $DIR/$tdir/$tfile ||
2511                 error "setstripe failed"
2512
2513         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2514         [ $count -eq $setcount ] ||
2515                 error "stripe count $count, should be $setcount"
2516
2517         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" ||
2518                 error "overstriped should be set in pattern"
2519
2520         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2521                 error "dd failed"
2522
2523         rm -f $DIR/$tdir/$tfile || error "Delete $tfile failed"
2524 }
2525 run_test 27Ce "test pool with overstriping"
2526
2527 test_27Cf() {
2528         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2529                 skip "server does not support overstriping"
2530         [[ $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
2531                 skip_env "too many osts, skipping"
2532
2533         test_mkdir -p $DIR/$tdir
2534
2535         local setcount=$(($OSTCOUNT * 2))
2536         [ $setcount -lt 160 ] || large_xattr_enabled ||
2537                 skip_env "ea_inode feature disabled"
2538
2539         $LFS setstripe  -C $setcount $DIR/$tdir/ ||
2540                 error "setstripe failed"
2541
2542         echo 1 > $DIR/$tdir/$tfile
2543
2544         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2545         [ $count -eq $setcount ] ||
2546                 error "stripe count $count, should be $setcount"
2547
2548         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" ||
2549                 error "overstriped should be set in pattern"
2550
2551         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2552                 error "dd failed"
2553
2554         rm -f $DIR/$tdir/$tfile || error "Delete $tfile failed"
2555 }
2556 run_test 27Cf "test default inheritance with overstriping"
2557
2558 test_27D() {
2559         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
2560         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
2561         remote_mds_nodsh && skip "remote MDS with nodsh"
2562
2563         local POOL=${POOL:-testpool}
2564         local first_ost=0
2565         local last_ost=$(($OSTCOUNT - 1))
2566         local ost_step=1
2567         local ost_list=$(seq $first_ost $ost_step $last_ost)
2568         local ost_range="$first_ost $last_ost $ost_step"
2569
2570         test_mkdir $DIR/$tdir
2571         pool_add $POOL || error "pool_add failed"
2572         pool_add_targets $POOL $ost_range || error "pool_add_targets failed"
2573
2574         local skip27D
2575         [ $MDS1_VERSION -lt $(version_code 2.8.55) ] &&
2576                 skip27D+="-s 29"
2577         [ $MDS1_VERSION -lt $(version_code 2.9.55) ] ||
2578                 [ $CLIENT_VERSION -lt $(version_code 2.9.55) ] &&
2579                         skip27D+=" -s 30,31"
2580         [[ ! $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ||
2581           $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
2582                 skip27D+=" -s 32,33"
2583         [[ $MDS_VERSION -lt $(version_code $SEL_VER) ]] &&
2584                 skip27D+=" -s 34"
2585         llapi_layout_test -d$DIR/$tdir -p$POOL -o$OSTCOUNT $skip27D ||
2586                 error "llapi_layout_test failed"
2587
2588         destroy_test_pools || error "destroy test pools failed"
2589 }
2590 run_test 27D "validate llapi_layout API"
2591
2592 # Verify that default_easize is increased from its initial value after
2593 # accessing a widely striped file.
2594 test_27E() {
2595         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
2596         [ $CLIENT_VERSION -lt $(version_code 2.5.57) ] &&
2597                 skip "client does not have LU-3338 fix"
2598
2599         # 72 bytes is the minimum space required to store striping
2600         # information for a file striped across one OST:
2601         # (sizeof(struct lov_user_md_v3) +
2602         #  sizeof(struct lov_user_ost_data_v1))
2603         local min_easize=72
2604         $LCTL set_param -n llite.*.default_easize $min_easize ||
2605                 error "lctl set_param failed"
2606         local easize=$($LCTL get_param -n llite.*.default_easize)
2607
2608         [ $easize -eq $min_easize ] ||
2609                 error "failed to set default_easize"
2610
2611         $LFS setstripe -c $OSTCOUNT $DIR/$tfile ||
2612                 error "setstripe failed"
2613         # In order to ensure stat() call actually talks to MDS we need to
2614         # do something drastic to this file to shake off all lock, e.g.
2615         # rename it (kills lookup lock forcing cache cleaning)
2616         mv $DIR/$tfile $DIR/${tfile}-1
2617         ls -l $DIR/${tfile}-1
2618         rm $DIR/${tfile}-1
2619
2620         easize=$($LCTL get_param -n llite.*.default_easize)
2621
2622         [ $easize -gt $min_easize ] ||
2623                 error "default_easize not updated"
2624 }
2625 run_test 27E "check that default extended attribute size properly increases"
2626
2627 test_27F() { # LU-5346/LU-7975
2628         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2629         [[ $OSTCOUNT -lt 2 ]] && skip "needs >= 2 OSTs"
2630         [[ $MDS1_VERSION -lt $(version_code 2.8.51) ]] &&
2631                 skip "Need MDS version at least 2.8.51"
2632         remote_ost_nodsh && skip "remote OST with nodsh"
2633
2634         test_mkdir $DIR/$tdir
2635         rm -f $DIR/$tdir/f0
2636         $LFS setstripe -c 2 $DIR/$tdir
2637
2638         # stop all OSTs to reproduce situation for LU-7975 ticket
2639         for num in $(seq $OSTCOUNT); do
2640                 stop ost$num
2641         done
2642
2643         # open/create f0 with O_LOV_DELAY_CREATE
2644         # truncate f0 to a non-0 size
2645         # close
2646         multiop $DIR/$tdir/f0 oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:T1050000c
2647
2648         $CHECKSTAT -s 1050000 $DIR/$tdir/f0 || error "checkstat failed"
2649         # open/write it again to force delayed layout creation
2650         cat /etc/hosts > $DIR/$tdir/f0 &
2651         catpid=$!
2652
2653         # restart OSTs
2654         for num in $(seq $OSTCOUNT); do
2655                 start ost$num $(ostdevname $num) $OST_MOUNT_OPTS ||
2656                         error "ost$num failed to start"
2657         done
2658
2659         wait $catpid || error "cat failed"
2660
2661         cmp /etc/hosts $DIR/$tdir/f0 || error "cmp failed"
2662         [[ $($LFS getstripe -c $DIR/$tdir/f0) == 2 ]] ||
2663                 error "wrong stripecount"
2664
2665 }
2666 run_test 27F "Client resend delayed layout creation with non-zero size"
2667
2668 test_27G() { #LU-10629
2669         [ $MDS1_VERSION -lt $(version_code 2.11.51) ] &&
2670                 skip "Need MDS version at least 2.11.51"
2671         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
2672         remote_mds_nodsh && skip "remote MDS with nodsh"
2673         local POOL=${POOL:-testpool}
2674         local ostrange="0 0 1"
2675
2676         test_mkdir $DIR/$tdir
2677         touch $DIR/$tdir/$tfile.nopool
2678         pool_add $POOL || error "pool_add failed"
2679         pool_add_targets $POOL $ostrange || error "pool_add_targets failed"
2680         $LFS setstripe -p $POOL $DIR/$tdir
2681
2682         local pool=$($LFS getstripe -p $DIR/$tdir)
2683
2684         [ "$pool" = "$POOL" ] || error "Striping failed got '$pool' not '$POOL'"
2685         touch $DIR/$tdir/$tfile.default
2686         $LFS setstripe -E 1M --pool $POOL -c 1 -E eof -c 1 $DIR/$tdir/$tfile.pfl
2687         $LFS find $DIR/$tdir -type f --pool $POOL
2688         local found=$($LFS find $DIR/$tdir -type f --pool $POOL | wc -l)
2689         [[ "$found" == "2" ]] ||
2690                 error "found $found != 2 files in '$DIR/$tdir' in '$POOL'"
2691
2692         $LFS setstripe -d $DIR/$tdir
2693
2694         pool=$($LFS getstripe -p -d $DIR/$tdir)
2695
2696         [[ "$pool" != "$POOL" ]] || error "$DIR/$tdir is still '$pool'"
2697 }
2698 run_test 27G "Clear OST pool from stripe"
2699
2700 test_27H() {
2701         [[ $MDS1_VERSION -le $(version_code 2.11.54) ]] &&
2702                 skip "Need MDS version newer than 2.11.54"
2703         [[ $OSTCOUNT -lt 3 ]] && skip_env "needs >= 3 OSTs"
2704         test_mkdir $DIR/$tdir
2705         $LFS setstripe -o 0 -o 2 $DIR/$tdir || error "setstripe failed"
2706         touch $DIR/$tdir/$tfile
2707         $LFS getstripe -c $DIR/$tdir/$tfile
2708         [ $($LFS getstripe -c $DIR/$tdir/$tfile) -eq 2 ] ||
2709                 error "two-stripe file doesn't have two stripes"
2710
2711         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
2712         $LFS getstripe -y $DIR/$tdir/$tfile
2713         (( $($LFS getstripe -y $DIR/$tdir/$tfile |
2714              egrep -c "l_ost_idx: [02]$") == "2" )) ||
2715                 error "expected l_ost_idx: [02]$ not matched"
2716
2717         # make sure ost list has been cleared
2718         local stripesize=$($LFS getstripe -S $DIR/$tdir)
2719         $LFS setstripe -S $((stripesize * 4)) -i 1 \
2720                 -c $((OSTCOUNT - 1)) $DIR/$tdir || error "setstripe"
2721         touch $DIR/$tdir/f3
2722         $LVERIFY $DIR/$tdir $DIR/$tdir/f3 || error "lverify failed"
2723 }
2724 run_test 27H "Set specific OSTs stripe"
2725
2726 test_27I() {
2727         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2728         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2729         [[ $MDS1_VERSION -gt $(version_code 2.12.52) ]] ||
2730                 skip "Need MDS version newer than 2.12.52"
2731         local pool=$TESTNAME
2732         local ostrange="1 1 1"
2733
2734         save_layout_restore_at_exit $MOUNT
2735         $LFS setstripe -c 2 -i 0 $MOUNT
2736         pool_add $pool || error "pool_add failed"
2737         pool_add_targets $pool $ostrange ||
2738                 error "pool_add_targets failed"
2739         test_mkdir $DIR/$tdir
2740         $LFS setstripe -p $pool $DIR/$tdir
2741         $MULTIOP $DIR/$tdir/$tfile Oc || error "multiop failed"
2742         $LFS getstripe $DIR/$tdir/$tfile
2743 }
2744 run_test 27I "check that root dir striping does not break parent dir one"
2745
2746 test_27J() {
2747         [[ $MDS1_VERSION -le $(version_code 2.12.51) ]] &&
2748                 skip "Need MDS version newer than 2.12.51"
2749
2750         test_mkdir $DIR/$tdir
2751         local uuid1=$(cat /proc/sys/kernel/random/uuid)
2752         local uuid2=$(cat /proc/sys/kernel/random/uuid)
2753
2754         # create foreign file (raw way)
2755         ! $LFS setstripe --flags 0xda08 $DIR/$tdir/$tfile ||
2756                 error "creating $tfile w/ hex flags w/o --foreign should fail"
2757
2758         ! $LFS setstripe --foreign --flags foo \
2759                 --xattr ${uuid1}@${uuid2} $DIR/$tdir/$tfile ||
2760                         error "creating $tfile with '--flags foo' should fail"
2761
2762         ! $LFS setstripe --foreign --flags 0xffffffff \
2763                 --xattr ${uuid1}@${uuid2} $DIR/$tdir/$tfile ||
2764                         error "creating $tfile w/ 0xffffffff flags should fail"
2765
2766         create_foreign_file -f $DIR/$tdir/$tfile -x "${uuid1}@${uuid2}" \
2767                 -t 1 -F 0xda08 || error "create_foreign_file failed"
2768
2769         # verify foreign file (raw way)
2770         parse_foreign_file -f $DIR/$tdir/$tfile |
2771                 grep "lov_foreign_magic: 0x0BD70BD0" ||
2772                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign magic"
2773         parse_foreign_file -f $DIR/$tdir/$tfile | grep "lov_xattr_size: 89" ||
2774                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign size"
2775         parse_foreign_file -f $DIR/$tdir/$tfile |
2776                 grep "lov_foreign_size: 73" ||
2777                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign size"
2778         parse_foreign_file -f $DIR/$tdir/$tfile |
2779                 grep "lov_foreign_type: 1" ||
2780                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign type"
2781         parse_foreign_file -f $DIR/$tdir/$tfile |
2782                 grep "lov_foreign_flags: 0x0000DA08" ||
2783                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign flags"
2784         local lov=$(parse_foreign_file -f $DIR/$tdir/$tfile |
2785                 grep "lov_foreign_value: 0x" |
2786                 sed -e 's/lov_foreign_value: 0x//')
2787         local lov2=$(echo -n "${uuid1}@${uuid2}" | od -A n -t x1 -w160)
2788         [[ $lov = ${lov2// /} ]] ||
2789                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign value"
2790
2791         # create foreign file (lfs + API)
2792         $LFS setstripe --foreign=none --flags 0xda08 \
2793                 -x "${uuid1}@${uuid2}" $DIR/$tdir/${tfile}2 ||
2794                 error "$DIR/$tdir/${tfile}2: create failed"
2795
2796         $LFS getstripe -v $DIR/$tdir/${tfile}2 |
2797                 grep "lfm_magic:.*0x0BD70BD0" ||
2798                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign magic"
2799         # lfm_length is LOV EA size - sizeof(lfm_magic) - sizeof(lfm_length)
2800         $LFS getstripe -v $DIR/$tdir/${tfile}2 | grep "lfm_length:.*73" ||
2801                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign size"
2802         $LFS getstripe -v $DIR/$tdir/${tfile}2 | grep "lfm_type:.*none" ||
2803                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign type"
2804         $LFS getstripe -v $DIR/$tdir/${tfile}2 |
2805                 grep "lfm_flags:.*0x0000DA08" ||
2806                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign flags"
2807         $LFS getstripe $DIR/$tdir/${tfile}2 |
2808                 grep "lfm_value:.*${uuid1}@${uuid2}" ||
2809                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign value"
2810
2811         # modify striping should fail
2812         $LFS setstripe -c 2 $DIR/$tdir/$tfile &&
2813                 error "$DIR/$tdir/$tfile: setstripe should fail"
2814         $LFS setstripe -c 2 $DIR/$tdir/${tfile}2 &&
2815                 error "$DIR/$tdir/${tfile}2: setstripe should fail"
2816
2817         # R/W should fail
2818         cat $DIR/$tdir/$tfile && error "$DIR/$tdir/$tfile: read should fail"
2819         cat $DIR/$tdir/${tfile}2 &&
2820                 error "$DIR/$tdir/${tfile}2: read should fail"
2821         cat /etc/passwd > $DIR/$tdir/$tfile &&
2822                 error "$DIR/$tdir/$tfile: write should fail"
2823         cat /etc/passwd > $DIR/$tdir/${tfile}2 &&
2824                 error "$DIR/$tdir/${tfile}2: write should fail"
2825
2826         # chmod should work
2827         chmod 222 $DIR/$tdir/$tfile ||
2828                 error "$DIR/$tdir/$tfile: chmod failed"
2829         chmod 222 $DIR/$tdir/${tfile}2 ||
2830                 error "$DIR/$tdir/${tfile}2: chmod failed"
2831
2832         # chown should work
2833         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/$tfile ||
2834                 error "$DIR/$tdir/$tfile: chown failed"
2835         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/${tfile}2 ||
2836                 error "$DIR/$tdir/${tfile}2: chown failed"
2837
2838         # rename should work
2839         mv $DIR/$tdir/$tfile $DIR/$tdir/${tfile}.new ||
2840                 error "$DIR/$tdir/$tfile: rename of foreign file has failed"
2841         mv $DIR/$tdir/${tfile}2 $DIR/$tdir/${tfile}2.new ||
2842                 error "$DIR/$tdir/${tfile}2: rename of foreign file has failed"
2843
2844         #remove foreign file
2845         rm $DIR/$tdir/${tfile}.new ||
2846                 error "$DIR/$tdir/${tfile}.new: remove of foreign file has failed"
2847         rm $DIR/$tdir/${tfile}2.new ||
2848                 error "$DIR/$tdir/${tfile}2.new: remove of foreign file has failed"
2849 }
2850 run_test 27J "basic ops on file with foreign LOV"
2851
2852 test_27K() {
2853         [[ $MDS1_VERSION -le $(version_code 2.12.49) ]] &&
2854                 skip "Need MDS version newer than 2.12.49"
2855
2856         test_mkdir $DIR/$tdir
2857         local uuid1=$(cat /proc/sys/kernel/random/uuid)
2858         local uuid2=$(cat /proc/sys/kernel/random/uuid)
2859
2860         # create foreign dir (raw way)
2861         ! $LFS setdirstripe --flags 0xda08 $DIR/$tdir/$tdir ||
2862                 error "creating $tdir w/ hex flags w/o --foreign should fail"
2863
2864         ! $LFS setdirstripe --foreign --flags foo \
2865                 --xattr ${uuid1}@${uuid2} $DIR/$tdir/$tdir ||
2866                         error "creating $tdir with '--flags foo' should fail"
2867
2868         ! $LFS setdirstripe --foreign --flags 0xffffffff \
2869                 --xattr ${uuid1}@${uuid2} $DIR/$tdir/$tdir ||
2870                         error "creating $tdir w/ 0xffffffff flags should fail"
2871
2872         create_foreign_dir -d $DIR/$tdir/$tdir -x "${uuid1}@${uuid2}" -t 1 ||
2873                 error "create_foreign_dir FAILED"
2874
2875         # verify foreign dir (raw way)
2876         parse_foreign_dir -d $DIR/$tdir/$tdir |
2877                 grep "lmv_foreign_magic:.*0xcd50cd0" ||
2878                 error "$DIR/$tdir/$tfile: invalid LMV EA magic"
2879         parse_foreign_dir -d $DIR/$tdir/$tdir | grep "lmv_xattr_size:.*89$" ||
2880                 error "$DIR/$tdir/$tdir: invalid LMV EA size"
2881         parse_foreign_dir -d $DIR/$tdir/$tdir | grep "lmv_foreign_type: 1$" ||
2882                 error "$DIR/$tdir/$tdir: invalid LMV EA type"
2883         parse_foreign_dir -d $DIR/$tdir/$tdir |
2884                 grep "lmv_foreign_flags: 55813$" ||
2885                 error "$DIR/$tdir/$tdir: invalid LMV EA flags"
2886         local lmv=$(parse_foreign_dir -d $DIR/$tdir/$tdir |
2887                 grep "lmv_foreign_value: 0x" |
2888                 sed 's/lmv_foreign_value: 0x//')
2889         local lmv2=$(echo -n "${uuid1}@${uuid2}" | od -A n -t x1 -w160 |
2890                 sed 's/ //g')
2891         [[ $lmv == $lmv2 ]] || error "$DIR/$tdir/$tdir: invalid LMV EA value"
2892
2893         # create foreign dir (lfs + API)
2894         $LFS mkdir --foreign=none --xattr="${uuid1}@${uuid2}" --flags=0xda05 \
2895                 $DIR/$tdir/${tdir}2 ||
2896                 error "$DIR/$tdir/${tdir}2: create failed"
2897
2898         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 |
2899                 grep "lfm_magic:.*0x0CD50CD0" ||
2900                 error "$DIR/$tdir/${tdir}2: invalid LMV EA magic"
2901         # lfm_length is LMV EA size - sizeof(lfm_magic) - sizeof(lfm_length)
2902         # - sizeof(lfm_type) - sizeof(lfm_flags)
2903         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 | grep "lfm_length:.*73" ||
2904                 error "$DIR/$tdir/${tdir}2: invalid LMV EA size"
2905         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 | grep "lfm_type:.*none" ||
2906                 error "$DIR/$tdir/${tdir}2: invalid LMV EA type"
2907         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 |
2908                 grep "lfm_flags:.*0x0000DA05" ||
2909                 error "$DIR/$tdir/${tdir}2: invalid LMV EA flags"
2910         $LFS getdirstripe $DIR/$tdir/${tdir}2 |
2911                 grep "lfm_value.*${uuid1}@${uuid2}" ||
2912                 error "$DIR/$tdir/${tdir}2: invalid LMV EA value"
2913
2914         # file create in dir should fail
2915         touch $DIR/$tdir/$tdir/$tfile && error "$DIR/$tdir: file create should fail"
2916         touch $DIR/$tdir/${tdir}2/$tfile &&
2917                 error "$DIR/${tdir}2: file create should fail"
2918
2919         # chmod should work
2920         chmod 777 $DIR/$tdir/$tdir ||
2921                 error "$DIR/$tdir: chmod failed"
2922         chmod 777 $DIR/$tdir/${tdir}2 ||
2923                 error "$DIR/${tdir}2: chmod failed"
2924
2925         # chown should work
2926         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/$tdir ||
2927                 error "$DIR/$tdir: chown failed"
2928         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/${tdir}2 ||
2929                 error "$DIR/${tdir}2: chown failed"
2930
2931         # rename should work
2932         mv $DIR/$tdir/$tdir $DIR/$tdir/${tdir}.new ||
2933                 error "$DIR/$tdir/$tdir: rename of foreign dir has failed"
2934         mv $DIR/$tdir/${tdir}2 $DIR/$tdir/${tdir}2.new ||
2935                 error "$DIR/$tdir/${tdir}2: rename of foreign dir has failed"
2936
2937         #remove foreign dir
2938         rmdir $DIR/$tdir/${tdir}.new ||
2939                 error "$DIR/$tdir/${tdir}.new: remove of foreign dir has failed"
2940         rmdir $DIR/$tdir/${tdir}2.new ||
2941                 error "$DIR/$tdir/${tdir}2.new: remove of foreign dir has failed"
2942 }
2943 run_test 27K "basic ops on dir with foreign LMV"
2944
2945 test_27L() {
2946         remote_mds_nodsh && skip "remote MDS with nodsh"
2947
2948         local POOL=${POOL:-$TESTNAME}
2949
2950         pool_add $POOL || error "pool_add failed"
2951
2952         lfs pool_list $MOUNT | grep -Fx "${FSNAME}.${POOL}" ||
2953                  error "pool_list does not contain ${FSNAME}.${POOL}:" \
2954                        "$(lfs pool_list $MOUNT | grep -F "${POOL}")"
2955 }
2956 run_test 27L "lfs pool_list gives correct pool name"
2957
2958 test_27M() {
2959         [[ $(lustre_version_code $SINGLEMDS) -lt $(version_code 2.12.57) ]] &&
2960                 skip "Need MDS version >= than 2.12.57"
2961         remote_mds_nodsh && skip "remote MDS with nodsh"
2962         [[ $OSTCOUNT -lt 2 ]] && skip_env "need > 1 OST"
2963
2964         test_mkdir $DIR/$tdir
2965
2966         # Set default striping on directory
2967         local setcount=4
2968         local stripe_opt
2969
2970         # if we run against a 2.12 server which lacks overstring support
2971         # then the connect_flag will not report overstriping, even if client
2972         # is 2.14+
2973         if [[ $($LCTL get_param mdc.*.connect_flags) =~ overstriping ]]; then
2974                 stripe_opt="-C $setcount"
2975         elif (( $OSTCOUNT >= $setcount )); then
2976                 stripe_opt="-c $setcount"
2977         else
2978                 skip "server does not support overstriping"
2979         fi
2980         $LFS setstripe $stripe_opt $DIR/$tdir
2981
2982         echo 1 > $DIR/$tdir/${tfile}.1
2983         local count=$($LFS getstripe -c $DIR/$tdir/${tfile}.1)
2984         [ $count -eq $setcount ] ||
2985                 error "(1) stripe count $count, should be $setcount"
2986
2987         # Capture existing append_stripe_count setting for restore
2988         local orig_count=$(do_facet mds1 $LCTL get_param -n mdd.$FSNAME-MDT0000.append_stripe_count)
2989         local mdts=$(comma_list $(mdts_nodes))
2990         stack_trap "do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=$orig_count" EXIT
2991
2992         local appendcount=$orig_count
2993         echo 1 >> $DIR/$tdir/${tfile}.2_append
2994         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.2_append)
2995         [ $count -eq $appendcount ] ||
2996                 error "(2)stripe count $count, should be $appendcount for append"
2997
2998         # Disable O_APPEND striping, verify it works
2999         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=0
3000
3001         # Should now get the default striping, which is 4
3002         setcount=4
3003         echo 1 >> $DIR/$tdir/${tfile}.3_append
3004         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.3_append)
3005         [ $count -eq $setcount ] ||
3006                 error "(3) stripe count $count, should be $setcount"
3007
3008         # Try changing the stripe count for append files
3009         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=2
3010
3011         # Append striping is now 2 (directory default is still 4)
3012         appendcount=2
3013         echo 1 >> $DIR/$tdir/${tfile}.4_append
3014         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.4_append)
3015         [ $count -eq $appendcount ] ||
3016                 error "(4) stripe count $count, should be $appendcount for append"
3017
3018         # Test append stripe count of -1
3019         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=-1
3020         appendcount=$OSTCOUNT
3021         echo 1 >> $DIR/$tdir/${tfile}.5
3022         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.5)
3023         [ $count -eq $appendcount ] ||
3024                 error "(5) stripe count $count, should be $appendcount for append"
3025
3026         # Set append striping back to default of 1
3027         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=1
3028
3029         # Try a new default striping, PFL + DOM
3030         $LFS setstripe -L mdt -E 1M -E -1 -c 2 $DIR/$tdir
3031
3032         # Create normal DOM file, DOM returns stripe count == 0
3033         setcount=0
3034         touch $DIR/$tdir/${tfile}.6
3035         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.6)
3036         [ $count -eq $setcount ] ||
3037                 error "(6) stripe count $count, should be $setcount"
3038
3039         # Show
3040         appendcount=1
3041         echo 1 >> $DIR/$tdir/${tfile}.7_append
3042         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.7_append)
3043         [ $count -eq $appendcount ] ||
3044                 error "(7) stripe count $count, should be $appendcount for append"
3045
3046         # Clean up DOM layout
3047         $LFS setstripe -d $DIR/$tdir
3048
3049         save_layout_restore_at_exit $MOUNT
3050         # Now test that append striping works when layout is from root
3051         $LFS setstripe -c 2 $MOUNT
3052         # Make a special directory for this
3053         mkdir $DIR/${tdir}/${tdir}.2
3054
3055         # Verify for normal file
3056         setcount=2
3057         echo 1 > $DIR/${tdir}/${tdir}.2/${tfile}.8
3058         count=$($LFS getstripe -c $DIR/$tdir/${tdir}.2/${tfile}.8)
3059         [ $count -eq $setcount ] ||
3060                 error "(8) stripe count $count, should be $setcount"
3061
3062         appendcount=1
3063         echo 1 >> $DIR/${tdir}/${tdir}.2/${tfile}.9_append
3064         count=$($LFS getstripe -c $DIR/${tdir}/${tdir}.2/${tfile}.9_append)
3065         [ $count -eq $appendcount ] ||
3066                 error "(9) stripe count $count, should be $appendcount for append"
3067
3068         # Now test O_APPEND striping with pools
3069         do_nodes $mdts $LCTL set_param mdd.*.append_pool="$TESTNAME"
3070         stack_trap "do_nodes $mdts $LCTL set_param mdd.*.append_pool='none'" EXIT
3071
3072         # Create the pool
3073         pool_add $TESTNAME || error "pool creation failed"
3074         pool_add_targets $TESTNAME 0 1 || error "Pool add targets failed"
3075
3076         echo 1 >> $DIR/$tdir/${tfile}.10_append
3077
3078         pool=$($LFS getstripe -p $DIR/$tdir/${tfile}.10_append)
3079         [ "$pool" = "$TESTNAME" ] || error "(10) incorrect pool: $pool"
3080
3081         # Check that count is still correct
3082         appendcount=1
3083         echo 1 >> $DIR/$tdir/${tfile}.11_append
3084         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.11_append)
3085         [ $count -eq $appendcount ] ||
3086                 error "(11) stripe count $count, should be $appendcount for append"
3087
3088         # Disable O_APPEND stripe count, verify pool works separately
3089         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=0
3090
3091         echo 1 >> $DIR/$tdir/${tfile}.12_append
3092
3093         pool=$($LFS getstripe -p $DIR/$tdir/${tfile}.12_append)
3094         [ "$pool" = "$TESTNAME" ] || error "(12) incorrect pool: $pool"
3095
3096         # Remove pool setting, verify it's not applied
3097         do_nodes $mdts $LCTL set_param mdd.*.append_pool='none'
3098
3099         echo 1 >> $DIR/$tdir/${tfile}.13_append
3100
3101         pool=$($LFS getstripe -p $DIR/$tdir/${tfile}.13_append)
3102         [ "$pool" = "" ] || error "(13) pool found: $pool"
3103 }
3104 run_test 27M "test O_APPEND striping"
3105
3106 test_27N() {
3107         combined_mgs_mds && skip "needs separate MGS/MDT"
3108
3109         pool_add $TESTNAME || error "pool_add failed"
3110         do_facet mgs "$LCTL pool_list $FSNAME" |
3111                 grep -Fx "${FSNAME}.${TESTNAME}" ||
3112                 error "lctl pool_list on MGS failed"
3113 }
3114 run_test 27N "lctl pool_list on separate MGS gives correct pool name"
3115
3116 clean_foreign_symlink() {
3117         trap 0
3118         lctl set_param llite/$FSNAME-*/foreign_symlink_enable=0
3119         for i in $DIR/$tdir/* ; do
3120                 $LFS unlink_foreign $i || true
3121         done
3122 }
3123
3124 test_27O() {
3125         [[ $(lustre_version_code $SINGLEMDS) -le $(version_code 2.12.51) ]] &&
3126                 skip "Need MDS version newer than 2.12.51"
3127
3128         test_mkdir $DIR/$tdir
3129         local uuid1=$(cat /proc/sys/kernel/random/uuid)
3130         local uuid2=$(cat /proc/sys/kernel/random/uuid)
3131
3132         trap clean_foreign_symlink EXIT
3133
3134         # enable foreign_symlink behaviour
3135         $LCTL set_param llite/$FSNAME-*/foreign_symlink_enable=1
3136
3137         # foreign symlink LOV format is a partial path by default
3138
3139         # create foreign file (lfs + API)
3140         $LFS setstripe --foreign=symlink --flags 0xda05 \
3141                 -x "${uuid1}/${uuid2}" --mode 0600 $DIR/$tdir/${tfile} ||
3142                 error "$DIR/$tdir/${tfile}: create failed"
3143
3144         $LFS getstripe -v $DIR/$tdir/${tfile} |
3145                 grep "lfm_magic:.*0x0BD70BD0" ||
3146                 error "$DIR/$tdir/${tfile}: invalid LOV EA foreign magic"
3147         $LFS getstripe -v $DIR/$tdir/${tfile} | grep "lfm_type:.*symlink" ||
3148                 error "$DIR/$tdir/${tfile}: invalid LOV EA foreign type"
3149         $LFS getstripe -v $DIR/$tdir/${tfile} |
3150                 grep "lfm_flags:.*0x0000DA05" ||
3151                 error "$DIR/$tdir/${tfile}: invalid LOV EA foreign flags"
3152         $LFS getstripe $DIR/$tdir/${tfile} |
3153                 grep "lfm_value:.*${uuid1}/${uuid2}" ||
3154                 error "$DIR/$tdir/${tfile}: invalid LOV EA foreign value"
3155
3156         # modify striping should fail
3157         $LFS setstripe -c 2 $DIR/$tdir/$tfile &&
3158                 error "$DIR/$tdir/$tfile: setstripe should fail"
3159
3160         # R/W should fail ("/{foreign_symlink_prefix}/${uuid1}/" missing)
3161         cat $DIR/$tdir/$tfile && error "$DIR/$tdir/$tfile: read should fail"
3162         cat /etc/passwd > $DIR/$tdir/$tfile &&
3163                 error "$DIR/$tdir/$tfile: write should fail"
3164
3165         # rename should succeed
3166         mv $DIR/$tdir/$tfile $DIR/$tdir/${tfile}.new ||
3167                 error "$DIR/$tdir/$tfile: rename has failed"
3168
3169         #remove foreign_symlink file should fail
3170         rm $DIR/$tdir/${tfile}.new &&
3171                 error "$DIR/$tdir/${tfile}.new: remove of foreign_symlink file should fail"
3172
3173         #test fake symlink
3174         mkdir /tmp/${uuid1} ||
3175                 error "/tmp/${uuid1}: mkdir has failed"
3176         echo FOOFOO > /tmp/${uuid1}/${uuid2} ||
3177                 error "/tmp/${uuid1}/${uuid2}: echo has failed"
3178         $LCTL set_param llite/$FSNAME-*/foreign_symlink_prefix=/tmp/
3179         $CHECKSTAT -t link -l /tmp/${uuid1}/${uuid2} $DIR/$tdir/${tfile}.new ||
3180                 error "$DIR/$tdir/${tfile}.new: not seen as a symlink"
3181         #read should succeed now
3182         cat $DIR/$tdir/${tfile}.new | grep FOOFOO ||
3183                 error "$DIR/$tdir/${tfile}.new: symlink resolution has failed"
3184         #write should succeed now
3185         cat /etc/passwd > $DIR/$tdir/${tfile}.new ||
3186                 error "$DIR/$tdir/${tfile}.new: write should succeed"
3187         diff /etc/passwd $DIR/$tdir/${tfile}.new ||
3188                 error "$DIR/$tdir/${tfile}.new: diff has failed"
3189         diff /etc/passwd /tmp/${uuid1}/${uuid2} ||
3190                 error "/tmp/${uuid1}/${uuid2}: diff has failed"
3191
3192         #check that getstripe still works
3193         $LFS getstripe $DIR/$tdir/${tfile}.new ||
3194                 error "$DIR/$tdir/${tfile}.new: getstripe should still work with foreign_symlink enabled"
3195
3196         # chmod should still succeed
3197         chmod 644 $DIR/$tdir/${tfile}.new ||
3198                 error "$DIR/$tdir/${tfile}.new: chmod has failed"
3199
3200         # chown should still succeed
3201         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/${tfile}.new ||
3202                 error "$DIR/$tdir/${tfile}.new: chown has failed"
3203
3204         # rename should still succeed
3205         mv $DIR/$tdir/${tfile}.new $DIR/$tdir/${tfile} ||
3206                 error "$DIR/$tdir/${tfile}.new: rename has failed"
3207
3208         #remove foreign_symlink file should still fail
3209         rm $DIR/$tdir/${tfile} &&
3210                 error "$DIR/$tdir/${tfile}: remove of foreign_symlink file should fail"
3211
3212         #use special ioctl() to unlink foreign_symlink file
3213         $LFS unlink_foreign $DIR/$tdir/${tfile} ||
3214                 error "$DIR/$tdir/$tfile: unlink/ioctl failed"
3215
3216 }
3217 run_test 27O "basic ops on foreign file of symlink type"
3218
3219 test_27P() {
3220         [[ $(lustre_version_code $SINGLEMDS) -le $(version_code 2.12.49) ]] &&
3221                 skip "Need MDS version newer than 2.12.49"
3222
3223         test_mkdir $DIR/$tdir
3224         local uuid1=$(cat /proc/sys/kernel/random/uuid)
3225         local uuid2=$(cat /proc/sys/kernel/random/uuid)
3226
3227         trap clean_foreign_symlink EXIT
3228
3229         # enable foreign_symlink behaviour
3230         $LCTL set_param llite/$FSNAME-*/foreign_symlink_enable=1
3231
3232         # foreign symlink LMV format is a partial path by default
3233
3234         # create foreign dir (lfs + API)
3235         $LFS mkdir --foreign=symlink --xattr="${uuid1}/${uuid2}" \
3236                 --flags=0xda05 --mode 0750 $DIR/$tdir/${tdir} ||
3237                 error "$DIR/$tdir/${tdir}: create failed"
3238
3239         $LFS getdirstripe -v $DIR/$tdir/${tdir} |
3240                 grep "lfm_magic:.*0x0CD50CD0" ||
3241                 error "$DIR/$tdir/${tdir}: invalid LMV EA magic"
3242         $LFS getdirstripe -v $DIR/$tdir/${tdir} | grep "lfm_type:.*symlink" ||
3243                 error "$DIR/$tdir/${tdir}: invalid LMV EA type"
3244         $LFS getdirstripe -v $DIR/$tdir/${tdir} |
3245                 grep "lfm_flags:.*0x0000DA05" ||
3246                 error "$DIR/$tdir/${tdir}: invalid LMV EA flags"
3247         $LFS getdirstripe $DIR/$tdir/${tdir} |
3248                 grep "lfm_value.*${uuid1}/${uuid2}" ||
3249                 error "$DIR/$tdir/${tdir}: invalid LMV EA value"
3250
3251         # file create in dir should fail
3252         # ("/{foreign_symlink_prefix}/${uuid1}/${uuid2}/" missing)
3253         touch $DIR/$tdir/$tdir/$tfile && error "$DIR/$tdir: file create should fail"
3254
3255         # rename should succeed
3256         mv $DIR/$tdir/$tdir $DIR/$tdir/${tdir}.new ||
3257                 error "$DIR/$tdir/$tdir: rename of foreign_symlink dir has failed"
3258
3259         #remove foreign_symlink dir should fail
3260         rmdir $DIR/$tdir/${tdir}.new &&
3261                 error "$DIR/$tdir/${tdir}.new: remove of foreign_symlink dir should fail"
3262
3263         #test fake symlink
3264         mkdir -p /tmp/${uuid1}/${uuid2} ||
3265                 error "/tmp/${uuid1}/${uuid2}: mkdir has failed"
3266         echo FOOFOO > /tmp/${uuid1}/${uuid2}/foo ||
3267                 error "/tmp/${uuid1}/${uuid2}/foo: echo has failed"
3268         $LCTL set_param llite/$FSNAME-*/foreign_symlink_prefix=/tmp/
3269         $CHECKSTAT -t link -l /tmp/${uuid1}/${uuid2} $DIR/$tdir/${tdir}.new ||
3270                 error "$DIR/$tdir/${tdir}.new: not seen as a symlink"
3271         cat $DIR/$tdir/${tdir}.new/foo | grep FOOFOO ||
3272                 error "$DIR/$tdir/${tdir}.new: symlink resolution has failed"
3273
3274         #check that getstripe fails now that foreign_symlink enabled
3275         $LFS getdirstripe $DIR/$tdir/${tdir}.new ||
3276                 error "$DIR/$tdir/${tdir}.new: getdirstripe should still work with foreign_symlink enabled"
3277
3278         # file create in dir should work now
3279         cp /etc/passwd $DIR/$tdir/${tdir}.new/$tfile ||
3280                 error "$DIR/$tdir/${tdir}.new/$tfile: file create should fail"
3281         diff /etc/passwd $DIR/$tdir/${tdir}.new/$tfile ||
3282                 error "$DIR/$tdir/${tdir}.new/$tfile: diff has failed"
3283         diff /etc/passwd /tmp/${uuid1}/${uuid2}/$tfile ||
3284                 error "/tmp/${uuid1}/${uuid2}/$tfile: diff has failed"
3285
3286         # chmod should still succeed
3287         chmod 755 $DIR/$tdir/${tdir}.new ||
3288                 error "$DIR/$tdir/${tdir}.new: chmod has failed"
3289
3290         # chown should still succeed
3291         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/${tdir}.new ||
3292                 error "$DIR/$tdir/${tdir}.new: chown has failed"
3293
3294         # rename should still succeed
3295         mv $DIR/$tdir/${tdir}.new $DIR/$tdir/${tdir} ||
3296                 error "$DIR/$tdir/${tdir}.new: rename of foreign_symlink dir has failed"
3297
3298         #remove foreign_symlink dir should still fail
3299         rmdir $DIR/$tdir/${tdir} &&
3300                 error "$DIR/$tdir/${tdir}: remove of foreign_symlink dir should fail"
3301
3302         #use special ioctl() to unlink foreign_symlink file
3303         $LFS unlink_foreign $DIR/$tdir/${tdir} ||
3304                 error "$DIR/$tdir/$tdir: unlink/ioctl failed"
3305
3306         #created file should still exist
3307         [[ -f /tmp/${uuid1}/${uuid2}/$tfile ]] ||
3308                 error "/tmp/${uuid1}/${uuid2}/$tfile has been removed"
3309         diff /etc/passwd /tmp/${uuid1}/${uuid2}/$tfile ||
3310                 error "/tmp/${uuid1}/${uuid2}/$tfile: diff has failed"
3311 }
3312 run_test 27P "basic ops on foreign dir of foreign_symlink type"
3313
3314 test_27Q() {
3315         rm -f $TMP/$tfile $TMP/$tfile.loop $TMP/$tfile.none $TMP/$tfile.broken
3316         stack_trap "rm -f $TMP/$tfile*"
3317
3318         test_mkdir $DIR/$tdir-1
3319         test_mkdir $DIR/$tdir-2
3320
3321         echo 'It is what it is' > $DIR/$tdir-1/$tfile
3322         lov_getstripe_old $DIR/$tdir-1/$tfile || error "$DIR/$tdir-1/$tfile: rc = $?"
3323
3324         ln -s $DIR/$tdir-1/$tfile $DIR/$tdir-2/$tfile
3325         lov_getstripe_old $DIR/$tdir-2/$tfile || error "$DIR/$tdir-2/$tfile: rc = $?"
3326
3327         ln -s $DIR/$tdir-1/$tfile $TMP/$tfile
3328         lov_getstripe_old $TMP/$tfile || error "$TMP/$tfile: rc = $?"
3329
3330         # Create some bad symlinks and ensure that we don't loop
3331         # forever or something. These should return ELOOP (40) and
3332         # ENOENT (2) but I don't want to test for that because there's
3333         # always some weirdo architecture that needs to ruin
3334         # everything by defining these error numbers differently.
3335
3336         ln -s $TMP/$tfile.loop $TMP/$tfile.loop
3337         lov_getstripe_old $TMP/$tfile.loop && error "$TMP/$tfile.loop: rc = $?"
3338
3339         ln -s $TMP/$tfile.none $TMP/$tfile.broken
3340         lov_getstripe_old $TMP/$tfile.broken && error "$TMP/$tfile.broken: rc = $?"
3341
3342         return 0
3343 }
3344 run_test 27Q "llapi_file_get_stripe() works on symlinks"
3345
3346 test_27R() {
3347         (( $MDS1_VERSION >= $(version_code 2.14.55) )) ||
3348                 skip "need MDS 2.14.55 or later"
3349         (( $OSTCOUNT >= 2 )) || skip_env "needs at least 2 OSTs"
3350
3351         local testdir="$DIR/$tdir"
3352         test_mkdir -p $testdir
3353         stack_trap "rm -rf $testdir"
3354         $LFS setstripe -c -1 $testdir || error "setstripe failed"
3355
3356         local f1="$testdir/f1"
3357         touch $f1 || error "failed to touch $f1"
3358         local count=$($LFS getstripe -c $f1)
3359         (( $count == $OSTCOUNT )) || error "wrong stripe count"
3360
3361         do_facet $SINGLEMDS $LCTL set_param lod.*.max_stripecount=-1
3362         (( $? == 34 )) || error "setting max_stripecount to -1 should fail and return ERANGE"
3363
3364         local maxcount=$(($OSTCOUNT - 1))
3365         local mdts=$(comma_list $(mdts_nodes))
3366         do_nodes $mdts $LCTL set_param lod.*.max_stripecount=$maxcount
3367         stack_trap "do_nodes $mdts $LCTL set_param lod.*.max_stripecount=0"
3368
3369         local f2="$testdir/f2"
3370         touch $f2 || error "failed to touch $f2"
3371         local count=$($LFS getstripe -c $f2)
3372         (( $count == $maxcount )) || error "wrong stripe count"
3373 }
3374 run_test 27R "test max_stripecount limitation when stripe count is set to -1"
3375
3376 test_27S() {
3377         (( $MDS1_VERSION >= $(version_code 2.14.54) )) ||
3378                 skip "Need MDS version at least 2.14.54"
3379         [[ "$(facet_host mds1)" != "$(facet_host ost1)" ]] ||
3380                 skip "needs different host for mdt1 ost1"
3381
3382         local count=$(precreated_ost_obj_count 0 0)
3383
3384         echo "precreate count $count"
3385         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
3386         $LFS setstripe -i 0 -c 1 $DIR/$tdir || error "setstripe $tdir failed"
3387         #define OBD_FAIL_OSP_GET_LAST_FID       0x2109
3388         do_facet mds1 $LCTL set_param fail_loc=0x2109
3389         #define OBD_FAIL_OST_GET_LAST_FID       0x252
3390         do_facet ost1 $LCTL set_param fail_loc=0x252
3391         createmany -o $DIR/$tdir/f $count &
3392         pid=$!
3393         echo "precreate count $(precreated_ost_obj_count 0 0)"
3394         do_facet mds1 $LCTL set_param fail_loc=0
3395         do_facet ost1 $LCTL set_param fail_loc=0
3396         wait $pid || error "createmany failed"
3397         echo "precreate count $(precreated_ost_obj_count 0 0)"
3398 }
3399 run_test 27S "don't deactivate OSP on network issue"
3400
3401 # createtest also checks that device nodes are created and
3402 # then visible correctly (#2091)
3403 test_28() { # bug 2091
3404         test_mkdir $DIR/d28
3405         $CREATETEST $DIR/d28/ct || error "createtest failed"
3406 }
3407 run_test 28 "create/mknod/mkdir with bad file types ============"
3408
3409 test_29() {
3410         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3411
3412         [ $MDS1_VERSION -ge $(version_code 2.14.51) ] && {
3413                 disable_opencache
3414                 stack_trap "restore_opencache"
3415         }
3416
3417         sync; sleep 1; sync # flush out any dirty pages from previous tests
3418         cancel_lru_locks
3419         test_mkdir $DIR/d29
3420         touch $DIR/d29/foo
3421         log 'first d29'
3422         ls -l $DIR/d29
3423
3424         declare -i LOCKCOUNTORIG=0
3425         for lock_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_count); do
3426                 let LOCKCOUNTORIG=$LOCKCOUNTORIG+$lock_count
3427         done
3428         [ $LOCKCOUNTORIG -eq 0 ] && error "No mdc lock count" && return 1
3429
3430         declare -i LOCKUNUSEDCOUNTORIG=0
3431         for unused_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_unused_count); do
3432                 let LOCKUNUSEDCOUNTORIG=$LOCKUNUSEDCOUNTORIG+$unused_count
3433         done
3434
3435         log 'second d29'
3436         ls -l $DIR/d29
3437         log 'done'
3438
3439         declare -i LOCKCOUNTCURRENT=0
3440         for lock_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_count); do
3441                 let LOCKCOUNTCURRENT=$LOCKCOUNTCURRENT+$lock_count
3442         done
3443
3444         declare -i LOCKUNUSEDCOUNTCURRENT=0
3445         for unused_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_unused_count); do
3446                 let LOCKUNUSEDCOUNTCURRENT=$LOCKUNUSEDCOUNTCURRENT+$unused_count
3447         done
3448
3449         if [[ $LOCKCOUNTCURRENT -gt $LOCKCOUNTORIG ]]; then
3450                 $LCTL set_param -n ldlm.dump_namespaces ""
3451                 error "CURRENT: $LOCKCOUNTCURRENT > $LOCKCOUNTORIG"
3452                 $LCTL dk | sort -k4 -t: > $TMP/test_29.dk
3453                 log "dumped log to $TMP/test_29.dk (bug 5793)"
3454                 return 2
3455         fi
3456         if [[ $LOCKUNUSEDCOUNTCURRENT -gt $LOCKUNUSEDCOUNTORIG ]]; then
3457                 error "UNUSED: $LOCKUNUSEDCOUNTCURRENT > $LOCKUNUSEDCOUNTORIG"
3458                 $LCTL dk | sort -k4 -t: > $TMP/test_29.dk
3459                 log "dumped log to $TMP/test_29.dk (bug 5793)"
3460                 return 3
3461         fi
3462 }
3463 run_test 29 "IT_GETATTR regression  ============================"
3464
3465 test_30a() { # was test_30
3466         cp $(which ls) $DIR || cp /bin/ls $DIR
3467         $DIR/ls / || error "Can't execute binary from lustre"
3468         rm $DIR/ls
3469 }
3470 run_test 30a "execute binary from Lustre (execve) =============="
3471
3472 test_30b() {
3473         cp `which ls` $DIR || cp /bin/ls $DIR
3474         chmod go+rx $DIR/ls
3475         $RUNAS $DIR/ls / || error "Can't execute binary from lustre as non-root"
3476         rm $DIR/ls
3477 }
3478 run_test 30b "execute binary from Lustre as non-root ==========="
3479
3480 test_30c() { # b=22376
3481         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3482
3483         cp $(which ls) $DIR || cp /bin/ls $DIR
3484         chmod a-rw $DIR/ls
3485         cancel_lru_locks mdc
3486         cancel_lru_locks osc
3487         $RUNAS $DIR/ls / || error "Can't execute binary from lustre"
3488         rm -f $DIR/ls
3489 }
3490 run_test 30c "execute binary from Lustre without read perms ===="
3491
3492 test_30d() {
3493         cp $(which dd) $DIR || error "failed to copy dd to $DIR/dd"
3494
3495         for i in {1..10}; do
3496                 $DIR/dd bs=1M count=128 if=/dev/zero of=$DIR/$tfile &
3497                 local PID=$!
3498                 sleep 1
3499                 $LCTL set_param ldlm.namespaces.*MDT*.lru_size=clear
3500                 wait $PID || error "executing dd from Lustre failed"
3501                 rm -f $DIR/$tfile
3502         done
3503
3504         rm -f $DIR/dd
3505 }
3506 run_test 30d "execute binary from Lustre while clear locks"
3507
3508 test_31a() {
3509         $OPENUNLINK $DIR/f31 $DIR/f31 || error "openunlink failed"
3510         $CHECKSTAT -a $DIR/f31 || error "$DIR/f31 exists"
3511 }
3512 run_test 31a "open-unlink file =================================="
3513
3514 test_31b() {
3515         touch $DIR/f31 || error "touch $DIR/f31 failed"
3516         ln $DIR/f31 $DIR/f31b || error "ln failed"
3517         $MULTIOP $DIR/f31b Ouc || error "multiop failed"
3518         $CHECKSTAT -t file $DIR/f31 || error "$DIR/f31 not file type"
3519 }
3520 run_test 31b "unlink file with multiple links while open ======="
3521
3522 test_31c() {
3523         touch $DIR/f31 || error "touch $DIR/f31 failed"
3524         ln $DIR/f31 $DIR/f31c || error "ln failed"
3525         multiop_bg_pause $DIR/f31 O_uc ||
3526                 error "multiop_bg_pause for $DIR/f31 failed"
3527         MULTIPID=$!
3528         $MULTIOP $DIR/f31c Ouc
3529         kill -USR1 $MULTIPID
3530         wait $MULTIPID
3531 }
3532 run_test 31c "open-unlink file with multiple links ============="
3533
3534 test_31d() {
3535         opendirunlink $DIR/d31d $DIR/d31d || error "opendirunlink failed"
3536         $CHECKSTAT -a $DIR/d31d || error "$DIR/d31d exists"
3537 }
3538 run_test 31d "remove of open directory ========================="
3539
3540 test_31e() { # bug 2904
3541         openfilleddirunlink $DIR/d31e || error "openfilleddirunlink failed"
3542 }
3543 run_test 31e "remove of open non-empty directory ==============="
3544
3545 test_31f() { # bug 4554
3546         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3547
3548         set -vx
3549         test_mkdir $DIR/d31f
3550         $LFS setstripe -S 1048576 -c 1 $DIR/d31f
3551         cp /etc/hosts $DIR/d31f
3552         ls -l $DIR/d31f
3553         $LFS getstripe $DIR/d31f/hosts
3554         multiop_bg_pause $DIR/d31f D_c || return 1
3555         MULTIPID=$!
3556
3557         rm -rv $DIR/d31f || error "first of $DIR/d31f"
3558         test_mkdir $DIR/d31f
3559         $LFS setstripe -S 1048576 -c 1 $DIR/d31f
3560         cp /etc/hosts $DIR/d31f
3561         ls -l $DIR/d31f
3562         $LFS getstripe $DIR/d31f/hosts
3563         multiop_bg_pause $DIR/d31f D_c || return 1
3564         MULTIPID2=$!
3565
3566         kill -USR1 $MULTIPID || error "first opendir $MULTIPID not running"
3567         wait $MULTIPID || error "first opendir $MULTIPID failed"
3568
3569         sleep 6
3570
3571         kill -USR1 $MULTIPID2 || error "second opendir $MULTIPID not running"
3572         wait $MULTIPID2 || error "second opendir $MULTIPID2 failed"
3573         set +vx
3574 }
3575 run_test 31f "remove of open directory with open-unlink file ==="
3576
3577 test_31g() {
3578         echo "-- cross directory link --"
3579         test_mkdir -c1 $DIR/${tdir}ga
3580         test_mkdir -c1 $DIR/${tdir}gb
3581         touch $DIR/${tdir}ga/f
3582         ln $DIR/${tdir}ga/f $DIR/${tdir}gb/g
3583         $CHECKSTAT -t file $DIR/${tdir}ga/f || error "source"
3584         [ `stat -c%h $DIR/${tdir}ga/f` == '2' ] || error "source nlink"
3585         $CHECKSTAT -t file $DIR/${tdir}gb/g || error "target"
3586         [ `stat -c%h $DIR/${tdir}gb/g` == '2' ] || error "target nlink"
3587 }
3588 run_test 31g "cross directory link==============="
3589
3590 test_31h() {
3591         echo "-- cross directory link --"
3592         test_mkdir -c1 $DIR/${tdir}
3593         test_mkdir -c1 $DIR/${tdir}/dir
3594         touch $DIR/${tdir}/f
3595         ln $DIR/${tdir}/f $DIR/${tdir}/dir/g
3596         $CHECKSTAT -t file $DIR/${tdir}/f || error "source"
3597         [ `stat -c%h $DIR/${tdir}/f` == '2' ] || error "source nlink"
3598         $CHECKSTAT -t file $DIR/${tdir}/dir/g || error "target"
3599         [ `stat -c%h $DIR/${tdir}/dir/g` == '2' ] || error "target nlink"
3600 }
3601 run_test 31h "cross directory link under child==============="
3602
3603 test_31i() {
3604         echo "-- cross directory link --"
3605         test_mkdir -c1 $DIR/$tdir
3606         test_mkdir -c1 $DIR/$tdir/dir
3607         touch $DIR/$tdir/dir/f
3608         ln $DIR/$tdir/dir/f $DIR/$tdir/g
3609         $CHECKSTAT -t file $DIR/$tdir/dir/f || error "source"
3610         [ `stat -c%h $DIR/$tdir/dir/f` == '2' ] || error "source nlink"
3611         $CHECKSTAT -t file $DIR/$tdir/g || error "target"
3612         [ `stat -c%h $DIR/$tdir/g` == '2' ] || error "target nlink"
3613 }
3614 run_test 31i "cross directory link under parent==============="
3615
3616 test_31j() {
3617         test_mkdir -c1 -p $DIR/$tdir
3618         test_mkdir -c1 -p $DIR/$tdir/dir1
3619         ln $DIR/$tdir/dir1 $DIR/$tdir/dir2 && error "ln for dir"
3620         link $DIR/$tdir/dir1 $DIR/$tdir/dir3 && error "link for dir"
3621         mlink $DIR/$tdir/dir1 $DIR/$tdir/dir4 && error "mlink for dir"
3622         mlink $DIR/$tdir/dir1 $DIR/$tdir/dir1 && error "mlink to the same dir"
3623         return 0
3624 }
3625 run_test 31j "link for directory==============="
3626
3627 test_31k() {
3628         test_mkdir -c1 -p $DIR/$tdir
3629         touch $DIR/$tdir/s
3630         touch $DIR/$tdir/exist
3631         mlink $DIR/$tdir/s $DIR/$tdir/t || error "mlink"
3632         mlink $DIR/$tdir/s $DIR/$tdir/exist && error "mlink to exist file"
3633         mlink $DIR/$tdir/s $DIR/$tdir/s && error "mlink to the same file"
3634         mlink $DIR/$tdir/s $DIR/$tdir && error "mlink to parent dir"
3635         mlink $DIR/$tdir $DIR/$tdir/s && error "mlink parent dir to target"
3636         mlink $DIR/$tdir/not-exist $DIR/$tdir/foo && error "mlink non-existing to new"
3637         mlink $DIR/$tdir/not-exist $DIR/$tdir/s && error "mlink non-existing to exist"
3638         return 0
3639 }
3640 run_test 31k "link to file: the same, non-existing, dir==============="
3641
3642 test_31m() {
3643         mkdir $DIR/d31m
3644         touch $DIR/d31m/s
3645         mkdir $DIR/d31m2
3646         touch $DIR/d31m2/exist
3647         mlink $DIR/d31m/s $DIR/d31m2/t || error "mlink"
3648         mlink $DIR/d31m/s $DIR/d31m2/exist && error "mlink to exist file"
3649         mlink $DIR/d31m/s $DIR/d31m2 && error "mlink to parent dir"
3650         mlink $DIR/d31m2 $DIR/d31m/s && error "mlink parent dir to target"
3651         mlink $DIR/d31m/not-exist $DIR/d31m2/foo && error "mlink non-existing to new"
3652         mlink $DIR/d31m/not-exist $DIR/d31m2/s && error "mlink non-existing to exist"
3653         return 0
3654 }
3655 run_test 31m "link to file: the same, non-existing, dir==============="
3656
3657 test_31n() {
3658         touch $DIR/$tfile || error "cannot create '$DIR/$tfile'"
3659         nlink=$(stat --format=%h $DIR/$tfile)
3660         [ ${nlink:--1} -eq 1 ] || error "nlink is $nlink, expected 1"
3661         local fd=$(free_fd)
3662         local cmd="exec $fd<$DIR/$tfile"
3663         eval $cmd
3664         cmd="exec $fd<&-"
3665         trap "eval $cmd" EXIT
3666         nlink=$(stat --dereference --format=%h /proc/self/fd/$fd)
3667         [ ${nlink:--1} -eq 1 ] || error "nlink is $nlink, expected 1"
3668         rm $DIR/$tfile || error "cannot remove '$DIR/$tfile'"
3669         nlink=$(stat --dereference --format=%h /proc/self/fd/$fd)
3670         [ ${nlink:--1} -eq 0 ] || error "nlink is $nlink, expected 0"
3671         eval $cmd
3672 }
3673 run_test 31n "check link count of unlinked file"
3674
3675 link_one() {
3676         local tempfile=$(mktemp $1_XXXXXX)
3677         mlink $tempfile $1 2> /dev/null &&
3678                 echo "$BASHPID: link $tempfile to $1 succeeded"
3679         munlink $tempfile
3680 }
3681
3682 test_31o() { # LU-2901
3683         test_mkdir $DIR/$tdir
3684         for LOOP in $(seq 100); do
3685                 rm -f $DIR/$tdir/$tfile*
3686                 for THREAD in $(seq 8); do
3687                         link_one $DIR/$tdir/$tfile.$LOOP &
3688                 done
3689                 wait
3690                 local LINKS=$(ls -1 $DIR/$tdir | grep -c $tfile.$LOOP)
3691                 [[ $LINKS -gt 1 ]] && ls $DIR/$tdir &&
3692                         error "$LINKS duplicate links to $tfile.$LOOP" &&
3693                         break || true
3694         done
3695 }
3696 run_test 31o "duplicate hard links with same filename"
3697
3698 test_31p() {
3699         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
3700
3701         test_mkdir $DIR/$tdir
3702         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
3703         $LFS setdirstripe -D -c2 -H all_char $DIR/$tdir/striped_dir
3704
3705         opendirunlink $DIR/$tdir/striped_dir/test1 ||
3706                 error "open unlink test1 failed"
3707         opendirunlink $DIR/$tdir/striped_dir/test2 ||
3708                 error "open unlink test2 failed"
3709
3710         $CHECKSTAT -a $DIR/$tdir/striped_dir/test1 ||
3711                 error "test1 still exists"
3712         $CHECKSTAT -a $DIR/$tdir/striped_dir/test2 ||
3713                 error "test2 still exists"
3714 }
3715 run_test 31p "remove of open striped directory"
3716
3717 test_31q() {
3718         [ $MDSCOUNT -lt 3 ] && skip_env "needs >= 3 MDTs"
3719
3720         $LFS mkdir -i 3,1 $DIR/$tdir || error "mkdir failed"
3721         index=$($LFS getdirstripe -i $DIR/$tdir)
3722         [ $index -eq 3 ] || error "first stripe index $index != 3"
3723         index=$($LFS getdirstripe $DIR/$tdir | tail -1 | awk '{print $1}')
3724         [ $index -eq 1 ] || error "second stripe index $index != 1"
3725
3726         # when "-c <stripe_count>" is set, the number of MDTs specified after
3727         # "-i" should equal to the stripe count
3728         $LFS mkdir -i 3,1 -c 3 $DIR/$tdir.2 && error "mkdir should fail" || true
3729 }
3730 run_test 31q "create striped directory on specific MDTs"
3731
3732 #LU-14949
3733 test_31r() {
3734         touch $DIR/$tfile.target
3735         touch $DIR/$tfile.source
3736
3737         #OBD_FAIL_LLITE_OPEN_DELAY 0x1419
3738         $LCTL set_param fail_loc=0x1419 fail_val=3
3739         cat $DIR/$tfile.target &
3740         CATPID=$!
3741
3742         # Guarantee open is waiting before we get here
3743         sleep 1
3744         mv $DIR/$tfile.source $DIR/$tfile.target
3745
3746         wait $CATPID
3747         RC=$?
3748         if [[ $RC -ne 0 ]]; then
3749                 error "open with cat failed, rc=$RC"
3750         fi
3751 }
3752 run_test 31r "open-rename(replace) race"
3753
3754 cleanup_test32_mount() {
3755         local rc=0
3756         trap 0
3757         local loopdev=$(losetup -a | grep $EXT2_DEV | sed -ne 's/:.*$//p')
3758         $UMOUNT $DIR/$tdir/ext2-mountpoint || rc=$?
3759         losetup -d $loopdev || true
3760         rm -rf $DIR/$tdir
3761         return $rc
3762 }
3763
3764 test_32a() {
3765         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3766
3767         echo "== more mountpoints and symlinks ================="
3768         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3769         trap cleanup_test32_mount EXIT
3770         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3771         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3772                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3773         $CHECKSTAT -t dir $DIR/$tdir/ext2-mountpoint/.. ||
3774                 error "$DIR/$tdir/ext2-mountpoint/.. not dir type"
3775         cleanup_test32_mount
3776 }
3777 run_test 32a "stat d32a/ext2-mountpoint/.. ====================="
3778
3779 test_32b() {
3780         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3781
3782         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3783         trap cleanup_test32_mount EXIT
3784         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3785         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3786                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3787         ls -al $DIR/$tdir/ext2-mountpoint/.. ||
3788                 error "Can't list $DIR/$tdir/ext2-mountpoint/.."
3789         cleanup_test32_mount
3790 }
3791 run_test 32b "open d32b/ext2-mountpoint/.. ====================="
3792
3793 test_32c() {
3794         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3795
3796         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3797         trap cleanup_test32_mount EXIT
3798         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3799         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3800                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3801         test_mkdir -p $DIR/$tdir/d2/test_dir
3802         $CHECKSTAT -t dir $DIR/$tdir/ext2-mountpoint/../d2/test_dir ||
3803                 error "$DIR/$tdir/ext2-mountpoint/../d2/test_dir not dir type"
3804         cleanup_test32_mount
3805 }
3806 run_test 32c "stat d32c/ext2-mountpoint/../d2/test_dir ========="
3807
3808 test_32d() {
3809         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3810
3811         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3812         trap cleanup_test32_mount EXIT
3813         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3814         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3815                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3816         test_mkdir -p $DIR/$tdir/d2/test_dir
3817         ls -al $DIR/$tdir/ext2-mountpoint/../d2/test_dir ||
3818                 error "Can't list $DIR/$tdir/ext2-mountpoint/../d2/test_dir"
3819         cleanup_test32_mount
3820 }
3821 run_test 32d "open d32d/ext2-mountpoint/../d2/test_dir"
3822
3823 test_32e() {
3824         rm -fr $DIR/$tdir
3825         test_mkdir -p $DIR/$tdir/tmp
3826         local tmp_dir=$DIR/$tdir/tmp
3827         ln -s $DIR/$tdir $tmp_dir/symlink11
3828         ln -s $tmp_dir/symlink11 $tmp_dir/../symlink01
3829         $CHECKSTAT -t link $DIR/$tdir/tmp/symlink11 || error "symlink11 bad"
3830         $CHECKSTAT -t link $DIR/$tdir/symlink01 || error "symlink01 bad"
3831 }
3832 run_test 32e "stat d32e/symlink->tmp/symlink->lustre-subdir"
3833
3834 test_32f() {
3835         rm -fr $DIR/$tdir
3836         test_mkdir -p $DIR/$tdir/tmp
3837         local tmp_dir=$DIR/$tdir/tmp
3838         ln -s $DIR/$tdir $tmp_dir/symlink11
3839         ln -s $tmp_dir/symlink11 $tmp_dir/../symlink01
3840         ls $DIR/$tdir/tmp/symlink11  || error "symlink11 bad"
3841         ls $DIR/$tdir/symlink01 || error "symlink01 bad"
3842 }
3843 run_test 32f "open d32f/symlink->tmp/symlink->lustre-subdir"
3844
3845 test_32g() {
3846         local tmp_dir=$DIR/$tdir/tmp
3847         test_mkdir -p $tmp_dir
3848         test_mkdir $DIR/${tdir}2
3849         ln -s $DIR/${tdir}2 $tmp_dir/symlink12
3850         ln -s $tmp_dir/symlink12 $tmp_dir/../symlink02
3851         $CHECKSTAT -t link $tmp_dir/symlink12 || error "symlink12 not a link"
3852         $CHECKSTAT -t link $DIR/$tdir/symlink02 || error "symlink02 not a link"
3853         $CHECKSTAT -t dir -f $tmp_dir/symlink12 || error "symlink12 not a dir"
3854         $CHECKSTAT -t dir -f $DIR/$tdir/symlink02 || error "symlink12 not a dir"
3855 }
3856 run_test 32g "stat d32g/symlink->tmp/symlink->lustre-subdir/${tdir}2"
3857
3858 test_32h() {
3859         rm -fr $DIR/$tdir $DIR/${tdir}2
3860         tmp_dir=$DIR/$tdir/tmp
3861         test_mkdir -p $tmp_dir
3862         test_mkdir $DIR/${tdir}2
3863         ln -s $DIR/${tdir}2 $tmp_dir/symlink12
3864         ln -s $tmp_dir/symlink12 $tmp_dir/../symlink02
3865         ls $tmp_dir/symlink12 || error "listing symlink12"
3866         ls $DIR/$tdir/symlink02  || error "listing symlink02"
3867 }
3868 run_test 32h "open d32h/symlink->tmp/symlink->lustre-subdir/${tdir}2"
3869
3870 test_32i() {
3871         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3872
3873         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3874         trap cleanup_test32_mount EXIT
3875         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3876         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3877                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3878         touch $DIR/$tdir/test_file
3879         $CHECKSTAT -t file $DIR/$tdir/ext2-mountpoint/../test_file ||
3880                 error "$DIR/$tdir/ext2-mountpoint/../test_file not file type"
3881         cleanup_test32_mount
3882 }
3883 run_test 32i "stat d32i/ext2-mountpoint/../test_file ==========="
3884
3885 test_32j() {
3886         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3887
3888         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3889         trap cleanup_test32_mount EXIT
3890         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3891         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3892                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3893         touch $DIR/$tdir/test_file
3894         cat $DIR/$tdir/ext2-mountpoint/../test_file ||
3895                 error "Can't open $DIR/$tdir/ext2-mountpoint/../test_file"
3896         cleanup_test32_mount
3897 }
3898 run_test 32j "open d32j/ext2-mountpoint/../test_file ==========="
3899
3900 test_32k() {
3901         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3902
3903         rm -fr $DIR/$tdir
3904         trap cleanup_test32_mount EXIT
3905         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3906         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3907                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3908         test_mkdir -p $DIR/$tdir/d2
3909         touch $DIR/$tdir/d2/test_file || error "touch failed"
3910         $CHECKSTAT -t file $DIR/$tdir/ext2-mountpoint/../d2/test_file ||
3911                 error "$DIR/$tdir/ext2-mountpoint/../d2/test_file not file type"
3912         cleanup_test32_mount
3913 }
3914 run_test 32k "stat d32k/ext2-mountpoint/../d2/test_file ========"
3915
3916 test_32l() {
3917         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3918
3919         rm -fr $DIR/$tdir
3920         trap cleanup_test32_mount EXIT
3921         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3922         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3923                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3924         test_mkdir -p $DIR/$tdir/d2
3925         touch $DIR/$tdir/d2/test_file || error "touch failed"
3926         cat  $DIR/$tdir/ext2-mountpoint/../d2/test_file ||
3927                 error "Can't open $DIR/$tdir/ext2-mountpoint/../d2/test_file"
3928         cleanup_test32_mount
3929 }
3930 run_test 32l "open d32l/ext2-mountpoint/../d2/test_file ========"
3931
3932 test_32m() {
3933         rm -fr $DIR/d32m
3934         test_mkdir -p $DIR/d32m/tmp
3935         TMP_DIR=$DIR/d32m/tmp
3936         ln -s $DIR $TMP_DIR/symlink11
3937         ln -s $TMP_DIR/symlink11 $TMP_DIR/../symlink01
3938         $CHECKSTAT -t link $DIR/d32m/tmp/symlink11 ||
3939                 error "symlink11 not a link"
3940         $CHECKSTAT -t link $DIR/d32m/symlink01 ||
3941                 error "symlink01 not a link"
3942 }
3943 run_test 32m "stat d32m/symlink->tmp/symlink->lustre-root ======"
3944
3945 test_32n() {
3946         rm -fr $DIR/d32n
3947         test_mkdir -p $DIR/d32n/tmp
3948         TMP_DIR=$DIR/d32n/tmp
3949         ln -s $DIR $TMP_DIR/symlink11
3950         ln -s $TMP_DIR/symlink11 $TMP_DIR/../symlink01
3951         ls -l $DIR/d32n/tmp/symlink11  || error "listing symlink11"
3952         ls -l $DIR/d32n/symlink01 || error "listing symlink01"
3953 }
3954 run_test 32n "open d32n/symlink->tmp/symlink->lustre-root ======"
3955
3956 test_32o() {
3957         touch $DIR/$tfile
3958         test_mkdir -p $DIR/d32o/tmp
3959         TMP_DIR=$DIR/d32o/tmp
3960         ln -s $DIR/$tfile $TMP_DIR/symlink12
3961         ln -s $TMP_DIR/symlink12 $TMP_DIR/../symlink02
3962         $CHECKSTAT -t link $DIR/d32o/tmp/symlink12 ||
3963                 error "symlink12 not a link"
3964         $CHECKSTAT -t link $DIR/d32o/symlink02 || error "symlink02 not a link"
3965         $CHECKSTAT -t file -f $DIR/d32o/tmp/symlink12 ||
3966                 error "$DIR/d32o/tmp/symlink12 not file type"
3967         $CHECKSTAT -t file -f $DIR/d32o/symlink02 ||
3968                 error "$DIR/d32o/symlink02 not file type"
3969 }
3970 run_test 32o "stat d32o/symlink->tmp/symlink->lustre-root/$tfile"
3971
3972 test_32p() {
3973         log 32p_1
3974         rm -fr $DIR/d32p
3975         log 32p_2
3976         rm -f $DIR/$tfile
3977         log 32p_3
3978         touch $DIR/$tfile
3979         log 32p_4
3980         test_mkdir -p $DIR/d32p/tmp
3981         log 32p_5
3982         TMP_DIR=$DIR/d32p/tmp
3983         log 32p_6
3984         ln -s $DIR/$tfile $TMP_DIR/symlink12
3985         log 32p_7
3986         ln -s $TMP_DIR/symlink12 $TMP_DIR/../symlink02
3987         log 32p_8
3988         cat $DIR/d32p/tmp/symlink12 ||
3989                 error "Can't open $DIR/d32p/tmp/symlink12"
3990         log 32p_9
3991         cat $DIR/d32p/symlink02 || error "Can't open $DIR/d32p/symlink02"
3992         log 32p_10
3993 }
3994 run_test 32p "open d32p/symlink->tmp/symlink->lustre-root/$tfile"
3995
3996 test_32q() {
3997         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3998
3999         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
4000         trap cleanup_test32_mount EXIT
4001         test_mkdir -p $DIR/$tdir/ext2-mountpoint
4002         touch $DIR/$tdir/ext2-mountpoint/under_the_mount || error "touch failed"
4003         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
4004                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
4005         ls $DIR/$tdir/ext2-mountpoint | grep "\<under_the_mount\>" && error
4006         cleanup_test32_mount
4007 }
4008 run_test 32q "stat follows mountpoints in Lustre (should return error)"
4009
4010 test_32r() {
4011         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4012
4013         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
4014         trap cleanup_test32_mount EXIT
4015         test_mkdir -p $DIR/$tdir/ext2-mountpoint
4016         touch $DIR/$tdir/ext2-mountpoint/under_the_mount || error "touch failed"
4017         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
4018                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
4019         ls $DIR/$tdir/ext2-mountpoint | grep -q under_the_mount && error || true
4020         cleanup_test32_mount
4021 }
4022 run_test 32r "opendir follows mountpoints in Lustre (should return error)"
4023
4024 test_33aa() {
4025         rm -f $DIR/$tfile
4026         touch $DIR/$tfile
4027         chmod 444 $DIR/$tfile
4028         chown $RUNAS_ID $DIR/$tfile
4029         log 33_1
4030         $RUNAS $OPENFILE -f O_RDWR $DIR/$tfile && error || true
4031         log 33_2
4032 }
4033 run_test 33aa "write file with mode 444 (should return error)"
4034
4035 test_33a() {
4036         rm -fr $DIR/$tdir
4037         test_mkdir $DIR/$tdir
4038         chown $RUNAS_ID $DIR/$tdir
4039         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $DIR/$tdir/$tfile ||
4040                 error "$RUNAS create $tdir/$tfile failed"
4041         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $DIR/$tdir/$tfile &&
4042                 error "open RDWR" || true
4043 }
4044 run_test 33a "test open file(mode=0444) with O_RDWR (should return error)"
4045
4046 test_33b() {
4047         rm -fr $DIR/$tdir
4048         test_mkdir $DIR/$tdir
4049         chown $RUNAS_ID $DIR/$tdir
4050         $RUNAS $OPENFILE -f 1286739555 $DIR/$tdir/$tfile || true
4051 }
4052 run_test 33b "test open file with malformed flags (No panic)"
4053
4054 test_33c() {
4055         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4056         remote_ost_nodsh && skip "remote OST with nodsh"
4057
4058         local ostnum
4059         local ostname
4060         local write_bytes
4061         local all_zeros
4062
4063         all_zeros=true
4064         test_mkdir $DIR/$tdir
4065         # Read: 0, Write: 4, create/destroy: 2/0, stat: 1, punch: 0
4066
4067         sync
4068         for ostnum in $(seq $OSTCOUNT); do
4069                 # test-framework's OST numbering is one-based, while Lustre's
4070                 # is zero-based
4071                 ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
4072                 # check if at least some write_bytes stats are counted
4073                 write_bytes=$(do_facet ost$ostnum lctl get_param -n \
4074                               obdfilter.$ostname.stats |
4075                               awk '/^write_bytes/ {print $7}' )
4076                 echo "baseline_write_bytes@ost$ostnum/$ostname=$write_bytes"
4077                 if (( ${write_bytes:-0} > 0 )); then
4078                         all_zeros=false
4079                         break
4080                 fi
4081         done
4082
4083         $all_zeros || return 0
4084
4085         # Write four bytes
4086         echo foo > $DIR/$tdir/bar
4087         # Really write them
4088         sync
4089
4090         # Total up write_bytes after writing.  We'd better find non-zeros.
4091         for ostnum in $(seq $OSTCOUNT); do
4092                 ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
4093                 write_bytes=$(do_facet ost$ostnum lctl get_param -n \
4094                               obdfilter/$ostname/stats |
4095                               awk '/^write_bytes/ {print $7}' )
4096                 echo "write_bytes@ost$ostnum/$ostname=$write_bytes"
4097                 if (( ${write_bytes:-0} > 0 )); then
4098                         all_zeros=false
4099                         break
4100                 fi
4101         done
4102
4103         if $all_zeros; then
4104                 for ostnum in $(seq $OSTCOUNT); do
4105                         ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
4106                         echo "Check write_bytes is in obdfilter.*.stats:"
4107                         do_facet ost$ostnum lctl get_param -n \
4108                                 obdfilter.$ostname.stats
4109                 done
4110                 error "OST not keeping write_bytes stats (b=22312)"
4111         fi
4112 }
4113 run_test 33c "test write_bytes stats"
4114
4115 test_33d() {
4116         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
4117         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4118
4119         local MDTIDX=1
4120         local remote_dir=$DIR/$tdir/remote_dir
4121
4122         test_mkdir $DIR/$tdir
4123         $LFS mkdir -i $MDTIDX $remote_dir ||
4124                 error "create remote directory failed"
4125
4126         touch $remote_dir/$tfile
4127         chmod 444 $remote_dir/$tfile
4128         chown $RUNAS_ID $remote_dir/$tfile
4129
4130         $RUNAS $OPENFILE -f O_RDWR $DIR/$tfile && error || true
4131
4132         chown $RUNAS_ID $remote_dir
4133         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $remote_dir/f33 ||
4134                                         error "create" || true
4135         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $remote_dir/f33 &&
4136                                     error "open RDWR" || true
4137         $RUNAS $OPENFILE -f 1286739555 $remote_dir/f33 || true
4138 }
4139 run_test 33d "openfile with 444 modes and malformed flags under remote dir"
4140
4141 test_33e() {
4142         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
4143
4144         mkdir $DIR/$tdir
4145
4146         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
4147         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
4148         mkdir $DIR/$tdir/local_dir
4149
4150         local s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
4151         local s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
4152         local l_mode=$(stat -c%f $DIR/$tdir/local_dir)
4153
4154         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
4155                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode"
4156
4157         rmdir $DIR/$tdir/* || error "rmdir failed"
4158
4159         umask 777
4160         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
4161         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
4162         mkdir $DIR/$tdir/local_dir
4163
4164         s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
4165         s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
4166         l_mode=$(stat -c%f $DIR/$tdir/local_dir)
4167
4168         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
4169                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode 777"
4170
4171         rmdir $DIR/$tdir/* || error "rmdir(umask 777) failed"
4172
4173         umask 000
4174         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
4175         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
4176         mkdir $DIR/$tdir/local_dir
4177
4178         s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
4179         s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
4180         l_mode=$(stat -c%f $DIR/$tdir/local_dir)
4181
4182         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
4183                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode 0"
4184 }
4185 run_test 33e "mkdir and striped directory should have same mode"
4186
4187 cleanup_33f() {
4188         trap 0
4189         do_facet $SINGLEMDS $LCTL set_param mdt.*.enable_remote_dir_gid=0
4190 }
4191
4192 test_33f() {
4193         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
4194         remote_mds_nodsh && skip "remote MDS with nodsh"
4195
4196         mkdir $DIR/$tdir
4197         chmod go+rwx $DIR/$tdir
4198         do_facet $SINGLEMDS $LCTL set_param mdt.*.enable_remote_dir_gid=-1
4199         trap cleanup_33f EXIT
4200
4201         $RUNAS lfs mkdir -i 0 -c$MDSCOUNT $DIR/$tdir/striped_dir ||
4202                 error "cannot create striped directory"
4203
4204         $RUNAS touch $DIR/$tdir/striped_dir/{0..16} ||
4205                 error "cannot create files in striped directory"
4206
4207         $RUNAS rm $DIR/$tdir/striped_dir/{0..16} ||
4208                 error "cannot remove files in striped directory"
4209
4210         $RUNAS rmdir $DIR/$tdir/striped_dir ||
4211                 error "cannot remove striped directory"
4212
4213         cleanup_33f
4214 }
4215 run_test 33f "nonroot user can create, access, and remove a striped directory"
4216
4217 test_33g() {
4218         mkdir -p $DIR/$tdir/dir2
4219
4220         local err=$($RUNAS mkdir $DIR/$tdir/dir2 2>&1)
4221         echo $err
4222         [[ $err =~ "exists" ]] || error "Not exists error"
4223 }
4224 run_test 33g "nonroot user create already existing root created file"
4225
4226 test_33h() {
4227         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
4228         [ $MDS1_VERSION -lt $(version_code 2.13.50) ] &&
4229                 skip "Need MDS version at least 2.13.50"
4230
4231         test_mkdir -c $MDSCOUNT -H crush $DIR/$tdir ||
4232                 error "mkdir $tdir failed"
4233         touch $DIR/$tdir/$tfile || error "touch $tfile failed"
4234
4235         local index=$($LFS getstripe -m $DIR/$tdir/$tfile)
4236         local index2
4237
4238         for fname in $DIR/$tdir/$tfile.bak \
4239                      $DIR/$tdir/$tfile.SAV \
4240                      $DIR/$tdir/$tfile.orig \
4241                      $DIR/$tdir/$tfile~; do
4242                 touch $fname  || error "touch $fname failed"
4243                 index2=$($LFS getstripe -m $fname)
4244                 [ $index -eq $index2 ] ||
4245                         error "$fname MDT index mismatch $index != $index2"
4246         done
4247
4248         local failed=0
4249         for i in {1..250}; do
4250                 for fname in $(mktemp -u $DIR/$tdir/.$tfile.XXXXXX) \
4251                              $(mktemp $DIR/$tdir/$tfile.XXXXXXXX); do
4252                         touch $fname  || error "touch $fname failed"
4253                         index2=$($LFS getstripe -m $fname)
4254                         if [[ $index != $index2 ]]; then
4255                                 failed=$((failed + 1))
4256                                 echo "$fname MDT index mismatch $index != $index2"
4257                         fi
4258                 done
4259         done
4260         echo "$failed MDT index mismatches"
4261         (( failed < 20 )) || error "MDT index mismatch $failed times"
4262
4263 }
4264 run_test 33h "temp file is located on the same MDT as target"
4265
4266 test_33i()
4267 {
4268         (( MDSCOUNT < 2 )) && skip "needs >= 2 MDTs"
4269
4270         local FNAME=$(str_repeat 'f' 250)
4271
4272         test_mkdir -i 0 -c $MDSCOUNT $DIR/$tdir || error "mkdir $tdir failed"
4273         createmany -o $DIR/$tdir/$FNAME 1000 || error "createmany failed"
4274
4275         local count
4276         local total
4277
4278         count=$($LFS getstripe -m $DIR/$tdir/* | grep -cw 1)
4279
4280         local MDC=$(lctl dl | awk '/MDT0001-mdc-[^M]/ { print $4 }')
4281
4282         lctl --device %$MDC deactivate
4283         stack_trap "lctl --device %$MDC activate"
4284         ls $DIR/$tdir > /dev/null && error "ls should return an error"
4285         total=$(\ls -l $DIR/$tdir | wc -l)
4286         # "ls -l" will list total in the first line
4287         total=$((total - 1))
4288         (( total + count == 1000 )) ||
4289                 error "ls list $total files, $count files on MDT1"
4290 }
4291 run_test 33i "striped directory can be accessed when one MDT is down"
4292
4293 TEST_34_SIZE=${TEST_34_SIZE:-2000000000000}
4294 test_34a() {
4295         rm -f $DIR/f34
4296         $MCREATE $DIR/f34 || error "mcreate failed"
4297         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
4298                 error "getstripe failed"
4299         $TRUNCATE $DIR/f34 $TEST_34_SIZE || error "truncate failed"
4300         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
4301                 error "getstripe failed"
4302         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4303                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4304 }
4305 run_test 34a "truncate file that has not been opened ==========="
4306
4307 test_34b() {
4308         [ ! -f $DIR/f34 ] && test_34a
4309         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4310                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4311         $OPENFILE -f O_RDONLY $DIR/f34
4312         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
4313                 error "getstripe failed"
4314         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4315                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4316 }
4317 run_test 34b "O_RDONLY opening file doesn't create objects ====="
4318
4319 test_34c() {
4320         [ ! -f $DIR/f34 ] && test_34a
4321         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4322                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4323         $OPENFILE -f O_RDWR $DIR/f34
4324         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" &&
4325                 error "$LFS getstripe failed"
4326         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4327                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4328 }
4329 run_test 34c "O_RDWR opening file-with-size works =============="
4330
4331 test_34d() {
4332         [ ! -f $DIR/f34 ] && test_34a
4333         dd if=/dev/zero of=$DIR/f34 conv=notrunc bs=4k count=1 ||
4334                 error "dd failed"
4335         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4336                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4337         rm $DIR/f34
4338 }
4339 run_test 34d "write to sparse file ============================="
4340
4341 test_34e() {
4342         rm -f $DIR/f34e
4343         $MCREATE $DIR/f34e || error "mcreate failed"
4344         $TRUNCATE $DIR/f34e 1000 || error "truncate failed"
4345         $CHECKSTAT -s 1000 $DIR/f34e ||
4346                 error "Size of $DIR/f34e not equal to 1000 bytes"
4347         $OPENFILE -f O_RDWR $DIR/f34e
4348         $CHECKSTAT -s 1000 $DIR/f34e ||
4349                 error "Size of $DIR/f34e not equal to 1000 bytes"
4350 }
4351 run_test 34e "create objects, some with size and some without =="
4352
4353 test_34f() { # bug 6242, 6243
4354         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4355
4356         SIZE34F=48000
4357         rm -f $DIR/f34f
4358         $MCREATE $DIR/f34f || error "mcreate failed"
4359         $TRUNCATE $DIR/f34f $SIZE34F || error "truncating $DIR/f3f to $SIZE34F"
4360         dd if=$DIR/f34f of=$TMP/f34f
4361         $CHECKSTAT -s $SIZE34F $TMP/f34f || error "$TMP/f34f not $SIZE34F bytes"
4362         dd if=/dev/zero of=$TMP/f34fzero bs=$SIZE34F count=1
4363         cmp $DIR/f34f $TMP/f34fzero || error "$DIR/f34f not all zero"
4364         cmp $TMP/f34f $TMP/f34fzero || error "$TMP/f34f not all zero"
4365         rm $TMP/f34f $TMP/f34fzero $DIR/f34f
4366 }
4367 run_test 34f "read from a file with no objects until EOF ======="
4368
4369 test_34g() {
4370         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4371
4372         dd if=/dev/zero of=$DIR/$tfile bs=1 count=100 seek=$TEST_34_SIZE ||
4373                 error "dd failed"
4374         $TRUNCATE $DIR/$tfile $((TEST_34_SIZE / 2))|| error "truncate failed"
4375         $CHECKSTAT -s $((TEST_34_SIZE / 2)) $DIR/$tfile ||
4376                 error "Size of $DIR/$tfile not equal to $((TEST_34_SIZE / 2))"
4377         cancel_lru_locks osc
4378         $CHECKSTAT -s $((TEST_34_SIZE / 2)) $DIR/$tfile ||
4379                 error "wrong size after lock cancel"
4380
4381         $TRUNCATE $DIR/$tfile $TEST_34_SIZE || error "truncate failed"
4382         $CHECKSTAT -s $TEST_34_SIZE $DIR/$tfile ||
4383                 error "expanding truncate failed"
4384         cancel_lru_locks osc
4385         $CHECKSTAT -s $TEST_34_SIZE $DIR/$tfile ||
4386                 error "wrong expanded size after lock cancel"
4387 }
4388 run_test 34g "truncate long file ==============================="
4389
4390 test_34h() {
4391         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4392
4393         local gid=10
4394         local sz=1000
4395
4396         dd if=/dev/zero of=$DIR/$tfile bs=1M count=10 || error "dd failed"
4397         sync # Flush the cache so that multiop below does not block on cache
4398              # flush when getting the group lock
4399         $MULTIOP $DIR/$tfile OG${gid}T${sz}g${gid}c &
4400         MULTIPID=$!
4401
4402         # Since just timed wait is not good enough, let's do a sync write
4403         # that way we are sure enough time for a roundtrip + processing
4404         # passed + 2 seconds of extra margin.
4405         dd if=/dev/zero of=$DIR/${tfile}-1 bs=$PAGE_SIZE oflag=direct count=1
4406         rm $DIR/${tfile}-1
4407         sleep 2
4408
4409         if [[ `ps h -o comm -p $MULTIPID` == "multiop" ]]; then
4410                 error "Multiop blocked on ftruncate, pid=$MULTIPID"
4411                 kill -9 $MULTIPID
4412         fi
4413         wait $MULTIPID
4414         local nsz=`stat -c %s $DIR/$tfile`
4415         [[ $nsz == $sz ]] || error "New size wrong $nsz != $sz"
4416 }
4417 run_test 34h "ftruncate file under grouplock should not block"
4418
4419 test_35a() {
4420         cp /bin/sh $DIR/f35a
4421         chmod 444 $DIR/f35a
4422         chown $RUNAS_ID $DIR/f35a
4423         $RUNAS $DIR/f35a && error || true
4424         rm $DIR/f35a
4425 }
4426 run_test 35a "exec file with mode 444 (should return and not leak)"
4427
4428 test_36a() {
4429         rm -f $DIR/f36
4430         utime $DIR/f36 || error "utime failed for MDS"
4431 }
4432 run_test 36a "MDS utime check (mknod, utime)"
4433
4434 test_36b() {
4435         echo "" > $DIR/f36
4436         utime $DIR/f36 || error "utime failed for OST"
4437 }
4438 run_test 36b "OST utime check (open, utime)"
4439
4440 test_36c() {
4441         rm -f $DIR/d36/f36
4442         test_mkdir $DIR/d36
4443         chown $RUNAS_ID $DIR/d36
4444         $RUNAS utime $DIR/d36/f36 || error "utime failed for MDS as non-root"
4445 }
4446 run_test 36c "non-root MDS utime check (mknod, utime)"
4447
4448 test_36d() {
4449         [ ! -d $DIR/d36 ] && test_36c
4450         echo "" > $DIR/d36/f36
4451         $RUNAS utime $DIR/d36/f36 || error "utime failed for OST as non-root"
4452 }
4453 run_test 36d "non-root OST utime check (open, utime)"
4454
4455 test_36e() {
4456         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID -- skipping"
4457
4458         test_mkdir $DIR/$tdir
4459         touch $DIR/$tdir/$tfile
4460         $RUNAS utime $DIR/$tdir/$tfile &&
4461                 error "utime worked, expected failure" || true
4462 }
4463 run_test 36e "utime on non-owned file (should return error)"
4464
4465 subr_36fh() {
4466         local fl="$1"
4467         local LANG_SAVE=$LANG
4468         local LC_LANG_SAVE=$LC_LANG
4469         export LANG=C LC_LANG=C # for date language
4470
4471         DATESTR="Dec 20  2000"
4472         test_mkdir $DIR/$tdir
4473         lctl set_param fail_loc=$fl
4474         date; date +%s
4475         cp /etc/hosts $DIR/$tdir/$tfile
4476         sync & # write RPC generated with "current" inode timestamp, but delayed
4477         sleep 1
4478         touch --date="$DATESTR" $DIR/$tdir/$tfile # setattr timestamp in past
4479         LS_BEFORE="`ls -l $DIR/$tdir/$tfile`" # old timestamp from client cache
4480         cancel_lru_locks $OSC
4481         LS_AFTER="`ls -l $DIR/$tdir/$tfile`"  # timestamp from OST object
4482         date; date +%s
4483         [ "$LS_BEFORE" != "$LS_AFTER" ] && \
4484                 echo "BEFORE: $LS_BEFORE" && \
4485                 echo "AFTER : $LS_AFTER" && \
4486                 echo "WANT  : $DATESTR" && \
4487                 error "$DIR/$tdir/$tfile timestamps changed" || true
4488
4489         export LANG=$LANG_SAVE LC_LANG=$LC_LANG_SAVE
4490 }
4491
4492 test_36f() {
4493         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4494
4495         #define OBD_FAIL_OST_BRW_PAUSE_BULK 0x214
4496         subr_36fh "0x80000214"
4497 }
4498 run_test 36f "utime on file racing with OST BRW write =========="
4499
4500 test_36g() {
4501         remote_ost_nodsh && skip "remote OST with nodsh"
4502         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4503         [ $MDS1_VERSION -lt $(version_code 2.12.51) ] &&
4504                 skip "Need MDS version at least 2.12.51"
4505
4506         local fmd_max_age
4507         local fmd
4508         local facet="ost1"
4509         local tgt="obdfilter"
4510
4511         [[ $OSC == "mdc" ]] && tgt="mdt" && facet="mds1"
4512
4513         test_mkdir $DIR/$tdir
4514         fmd_max_age=$(do_facet $facet \
4515                 "lctl get_param -n $tgt.*.tgt_fmd_seconds 2> /dev/null | \
4516                 head -n 1")
4517
4518         echo "FMD max age: ${fmd_max_age}s"
4519         touch $DIR/$tdir/$tfile
4520         fmd=$(do_facet $facet "lctl get_param -n $tgt.*.exports.*.fmd_count" |
4521                 gawk '{cnt=cnt+$1}  END{print cnt}')
4522         echo "FMD before: $fmd"
4523         [[ $fmd == 0 ]] &&
4524                 error "FMD wasn't create by touch"
4525         sleep $((fmd_max_age + 12))
4526         fmd=$(do_facet $facet "lctl get_param -n $tgt.*.exports.*.fmd_count" |
4527                 gawk '{cnt=cnt+$1}  END{print cnt}')
4528         echo "FMD after: $fmd"
4529         [[ $fmd == 0 ]] ||
4530                 error "FMD wasn't expired by ping"
4531 }
4532 run_test 36g "FMD cache expiry ====================="
4533
4534 test_36h() {
4535         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4536
4537         #define OBD_FAIL_OST_BRW_PAUSE_BULK2 0x227
4538         subr_36fh "0x80000227"
4539 }
4540 run_test 36h "utime on file racing with OST BRW write =========="
4541
4542 test_36i() {
4543         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
4544
4545         test_mkdir $DIR/$tdir
4546         $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir
4547
4548         local mtime=$(stat -c%Y $DIR/$tdir/striped_dir)
4549         local new_mtime=$((mtime + 200))
4550
4551         #change Modify time of striped dir
4552         touch -m -d @$new_mtime $DIR/$tdir/striped_dir ||
4553                         error "change mtime failed"
4554
4555         local got=$(stat -c%Y $DIR/$tdir/striped_dir)
4556
4557         [ "$new_mtime" = "$got" ] || error "expect $new_mtime got $got"
4558 }
4559 run_test 36i "change mtime on striped directory"
4560
4561 # test_37 - duplicate with tests 32q 32r
4562
4563 test_38() {
4564         local file=$DIR/$tfile
4565         touch $file
4566         openfile -f O_DIRECTORY $file
4567         local RC=$?
4568         local ENOTDIR=20
4569         [ $RC -eq 0 ] && error "opened file $file with O_DIRECTORY" || true
4570         [ $RC -eq $ENOTDIR ] || error "error $RC should be ENOTDIR ($ENOTDIR)"
4571 }
4572 run_test 38 "open a regular file with O_DIRECTORY should return -ENOTDIR ==="
4573
4574 test_39a() { # was test_39
4575         touch $DIR/$tfile
4576         touch $DIR/${tfile}2
4577 #       ls -l  $DIR/$tfile $DIR/${tfile}2
4578 #       ls -lu  $DIR/$tfile $DIR/${tfile}2
4579 #       ls -lc  $DIR/$tfile $DIR/${tfile}2
4580         sleep 2
4581         $OPENFILE -f O_CREAT:O_TRUNC:O_WRONLY $DIR/${tfile}2
4582         if [ ! $DIR/${tfile}2 -nt $DIR/$tfile ]; then
4583                 echo "mtime"
4584                 ls -l --full-time $DIR/$tfile $DIR/${tfile}2
4585                 echo "atime"
4586                 ls -lu --full-time $DIR/$tfile $DIR/${tfile}2
4587                 echo "ctime"
4588                 ls -lc --full-time $DIR/$tfile $DIR/${tfile}2
4589                 error "O_TRUNC didn't change timestamps"
4590         fi
4591 }
4592 run_test 39a "mtime changed on create"
4593
4594 test_39b() {
4595         test_mkdir -c1 $DIR/$tdir
4596         cp -p /etc/passwd $DIR/$tdir/fopen
4597         cp -p /etc/passwd $DIR/$tdir/flink
4598         cp -p /etc/passwd $DIR/$tdir/funlink
4599         cp -p /etc/passwd $DIR/$tdir/frename
4600         ln $DIR/$tdir/funlink $DIR/$tdir/funlink2
4601
4602         sleep 1
4603         echo "aaaaaa" >> $DIR/$tdir/fopen
4604         echo "aaaaaa" >> $DIR/$tdir/flink
4605         echo "aaaaaa" >> $DIR/$tdir/funlink
4606         echo "aaaaaa" >> $DIR/$tdir/frename
4607
4608         local open_new=`stat -c %Y $DIR/$tdir/fopen`
4609         local link_new=`stat -c %Y $DIR/$tdir/flink`
4610         local unlink_new=`stat -c %Y $DIR/$tdir/funlink`
4611         local rename_new=`stat -c %Y $DIR/$tdir/frename`
4612
4613         cat $DIR/$tdir/fopen > /dev/null
4614         ln $DIR/$tdir/flink $DIR/$tdir/flink2
4615         rm -f $DIR/$tdir/funlink2
4616         mv -f $DIR/$tdir/frename $DIR/$tdir/frename2
4617
4618         for (( i=0; i < 2; i++ )) ; do
4619                 local open_new2=`stat -c %Y $DIR/$tdir/fopen`
4620                 local link_new2=`stat -c %Y $DIR/$tdir/flink`
4621                 local unlink_new2=`stat -c %Y $DIR/$tdir/funlink`
4622                 local rename_new2=`stat -c %Y $DIR/$tdir/frename2`
4623
4624                 [ $open_new2 -eq $open_new ] || error "open file reverses mtime"
4625                 [ $link_new2 -eq $link_new ] || error "link file reverses mtime"
4626                 [ $unlink_new2 -eq $unlink_new ] || error "unlink file reverses mtime"
4627                 [ $rename_new2 -eq $rename_new ] || error "rename file reverses mtime"
4628
4629                 cancel_lru_locks $OSC
4630                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4631         done
4632 }
4633 run_test 39b "mtime change on open, link, unlink, rename  ======"
4634
4635 # this should be set to past
4636 TEST_39_MTIME=`date -d "1 year ago" +%s`
4637
4638 # bug 11063
4639 test_39c() {
4640         touch $DIR1/$tfile
4641         sleep 2
4642         local mtime0=`stat -c %Y $DIR1/$tfile`
4643
4644         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4645         local mtime1=`stat -c %Y $DIR1/$tfile`
4646         [ "$mtime1" = $TEST_39_MTIME ] || \
4647                 error "mtime is not set to past: $mtime1, should be $TEST_39_MTIME"
4648
4649         local d1=`date +%s`
4650         echo hello >> $DIR1/$tfile
4651         local d2=`date +%s`
4652         local mtime2=`stat -c %Y $DIR1/$tfile`
4653         [ "$mtime2" -ge "$d1" ] && [ "$mtime2" -le "$d2" ] || \
4654                 error "mtime is not updated on write: $d1 <= $mtime2 <= $d2"
4655
4656         mv $DIR1/$tfile $DIR1/$tfile-1
4657
4658         for (( i=0; i < 2; i++ )) ; do
4659                 local mtime3=`stat -c %Y $DIR1/$tfile-1`
4660                 [ "$mtime2" = "$mtime3" ] || \
4661                         error "mtime ($mtime2) changed (to $mtime3) on rename"
4662
4663                 cancel_lru_locks $OSC
4664                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4665         done
4666 }
4667 run_test 39c "mtime change on rename ==========================="
4668
4669 # bug 21114
4670 test_39d() {
4671         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4672
4673         touch $DIR1/$tfile
4674         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4675
4676         for (( i=0; i < 2; i++ )) ; do
4677                 local mtime=`stat -c %Y $DIR1/$tfile`
4678                 [ $mtime = $TEST_39_MTIME ] || \
4679                         error "mtime($mtime) is not set to $TEST_39_MTIME"
4680
4681                 cancel_lru_locks $OSC
4682                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4683         done
4684 }
4685 run_test 39d "create, utime, stat =============================="
4686
4687 # bug 21114
4688 test_39e() {
4689         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4690
4691         touch $DIR1/$tfile
4692         local mtime1=`stat -c %Y $DIR1/$tfile`
4693
4694         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4695
4696         for (( i=0; i < 2; i++ )) ; do
4697                 local mtime2=`stat -c %Y $DIR1/$tfile`
4698                 [ $mtime2 = $TEST_39_MTIME ] || \
4699                         error "mtime($mtime2) is not set to $TEST_39_MTIME"
4700
4701                 cancel_lru_locks $OSC
4702                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4703         done
4704 }
4705 run_test 39e "create, stat, utime, stat ========================"
4706
4707 # bug 21114
4708 test_39f() {
4709         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4710
4711         touch $DIR1/$tfile
4712         mtime1=`stat -c %Y $DIR1/$tfile`
4713
4714         sleep 2
4715         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4716
4717         for (( i=0; i < 2; i++ )) ; do
4718                 local mtime2=`stat -c %Y $DIR1/$tfile`
4719                 [ $mtime2 = $TEST_39_MTIME ] || \
4720                         error "mtime($mtime2) is not set to $TEST_39_MTIME"
4721
4722                 cancel_lru_locks $OSC
4723                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4724         done
4725 }
4726 run_test 39f "create, stat, sleep, utime, stat ================="
4727
4728 # bug 11063
4729 test_39g() {
4730         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4731
4732         echo hello >> $DIR1/$tfile
4733         local mtime1=`stat -c %Y $DIR1/$tfile`
4734
4735         sleep 2
4736         chmod o+r $DIR1/$tfile
4737
4738         for (( i=0; i < 2; i++ )) ; do
4739                 local mtime2=`stat -c %Y $DIR1/$tfile`
4740                 [ "$mtime1" = "$mtime2" ] || \
4741                         error "lost mtime: $mtime2, should be $mtime1"
4742
4743                 cancel_lru_locks $OSC
4744                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4745         done
4746 }
4747 run_test 39g "write, chmod, stat ==============================="
4748
4749 # bug 11063
4750 test_39h() {
4751         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4752
4753         touch $DIR1/$tfile
4754         sleep 1
4755
4756         local d1=`date`
4757         echo hello >> $DIR1/$tfile
4758         local mtime1=`stat -c %Y $DIR1/$tfile`
4759
4760         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4761         local d2=`date`
4762         if [ "$d1" != "$d2" ]; then
4763                 echo "write and touch not within one second"
4764         else
4765                 for (( i=0; i < 2; i++ )) ; do
4766                         local mtime2=`stat -c %Y $DIR1/$tfile`
4767                         [ "$mtime2" = $TEST_39_MTIME ] || \
4768                                 error "lost mtime: $mtime2, should be $TEST_39_MTIME"
4769
4770                         cancel_lru_locks $OSC
4771                         if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4772                 done
4773         fi
4774 }
4775 run_test 39h "write, utime within one second, stat ============="
4776
4777 test_39i() {
4778         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4779
4780         touch $DIR1/$tfile
4781         sleep 1
4782
4783         echo hello >> $DIR1/$tfile
4784         local mtime1=`stat -c %Y $DIR1/$tfile`
4785
4786         mv $DIR1/$tfile $DIR1/$tfile-1
4787
4788         for (( i=0; i < 2; i++ )) ; do
4789                 local mtime2=`stat -c %Y $DIR1/$tfile-1`
4790
4791                 [ "$mtime1" = "$mtime2" ] || \
4792                         error "lost mtime: $mtime2, should be $mtime1"
4793
4794                 cancel_lru_locks $OSC
4795                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4796         done
4797 }
4798 run_test 39i "write, rename, stat =============================="
4799
4800 test_39j() {
4801         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4802
4803         start_full_debug_logging
4804         touch $DIR1/$tfile
4805         sleep 1
4806
4807         #define OBD_FAIL_OSC_DELAY_SETTIME       0x412
4808         lctl set_param fail_loc=0x80000412
4809         multiop_bg_pause $DIR1/$tfile oO_RDWR:w2097152_c ||
4810                 error "multiop failed"
4811         local multipid=$!
4812         local mtime1=`stat -c %Y $DIR1/$tfile`
4813
4814         mv $DIR1/$tfile $DIR1/$tfile-1
4815
4816         kill -USR1 $multipid
4817         wait $multipid || error "multiop close failed"
4818
4819         for (( i=0; i < 2; i++ )) ; do
4820                 local mtime2=`stat -c %Y $DIR1/$tfile-1`
4821                 [ "$mtime1" = "$mtime2" ] ||
4822                         error "mtime is lost on close: $mtime2, " \
4823                               "should be $mtime1"
4824
4825                 cancel_lru_locks
4826                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4827         done
4828         lctl set_param fail_loc=0
4829         stop_full_debug_logging
4830 }
4831 run_test 39j "write, rename, close, stat ======================="
4832
4833 test_39k() {
4834         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4835
4836         touch $DIR1/$tfile
4837         sleep 1
4838
4839         multiop_bg_pause $DIR1/$tfile oO_RDWR:w2097152_c || error "multiop failed"
4840         local multipid=$!
4841         local mtime1=`stat -c %Y $DIR1/$tfile`
4842
4843         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4844
4845         kill -USR1 $multipid
4846         wait $multipid || error "multiop close failed"
4847
4848         for (( i=0; i < 2; i++ )) ; do
4849                 local mtime2=`stat -c %Y $DIR1/$tfile`
4850
4851                 [ "$mtime2" = $TEST_39_MTIME ] || \
4852                         error "mtime is lost on close: $mtime2, should be $TEST_39_MTIME"
4853
4854                 cancel_lru_locks
4855                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4856         done
4857 }
4858 run_test 39k "write, utime, close, stat ========================"
4859
4860 # this should be set to future
4861 TEST_39_ATIME=`date -d "1 year" +%s`
4862
4863 test_39l() {
4864         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4865         remote_mds_nodsh && skip "remote MDS with nodsh"
4866
4867         local atime_diff=$(do_facet $SINGLEMDS \
4868                                 lctl get_param -n mdd.*MDT0000*.atime_diff)
4869         rm -rf $DIR/$tdir
4870         mkdir_on_mdt0 $DIR/$tdir
4871
4872         # test setting directory atime to future
4873         touch -a -d @$TEST_39_ATIME $DIR/$tdir
4874         local atime=$(stat -c %X $DIR/$tdir)
4875         [ "$atime" = $TEST_39_ATIME ] ||
4876                 error "atime is not set to future: $atime, $TEST_39_ATIME"
4877
4878         # test setting directory atime from future to now
4879         local now=$(date +%s)
4880         touch -a -d @$now $DIR/$tdir
4881
4882         atime=$(stat -c %X $DIR/$tdir)
4883         [ "$atime" -eq "$now"  ] ||
4884                 error "atime is not updated from future: $atime, $now"
4885
4886         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=2
4887         sleep 3
4888
4889         # test setting directory atime when now > dir atime + atime_diff
4890         local d1=$(date +%s)
4891         ls $DIR/$tdir
4892         local d2=$(date +%s)
4893         cancel_lru_locks mdc
4894         atime=$(stat -c %X $DIR/$tdir)
4895         [ "$atime" -ge "$d1" -a "$atime" -le "$d2" ] ||
4896                 error "atime is not updated  : $atime, should be $d2"
4897
4898         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=60
4899         sleep 3
4900
4901         # test not setting directory atime when now < dir atime + atime_diff
4902         ls $DIR/$tdir
4903         cancel_lru_locks mdc
4904         atime=$(stat -c %X $DIR/$tdir)
4905         [ "$atime" -ge "$d1" -a "$atime" -le "$d2" ] ||
4906                 error "atime is updated to $atime, should remain $d1<atime<$d2"
4907
4908         do_facet $SINGLEMDS \
4909                 lctl set_param -n mdd.*MDT0000*.atime_diff=$atime_diff
4910 }
4911 run_test 39l "directory atime update ==========================="
4912
4913 test_39m() {
4914         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4915
4916         touch $DIR1/$tfile
4917         sleep 2
4918         local far_past_mtime=$(date -d "May 29 1953" +%s)
4919         local far_past_atime=$(date -d "Dec 17 1903" +%s)
4920
4921         touch -m -d @$far_past_mtime $DIR1/$tfile
4922         touch -a -d @$far_past_atime $DIR1/$tfile
4923
4924         for (( i=0; i < 2; i++ )) ; do
4925                 local timestamps=$(stat -c "%X %Y" $DIR1/$tfile)
4926                 [ "$timestamps" = "$far_past_atime $far_past_mtime" ] || \
4927                         error "atime or mtime set incorrectly"
4928
4929                 cancel_lru_locks $OSC
4930                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4931         done
4932 }
4933 run_test 39m "test atime and mtime before 1970"
4934
4935 test_39n() { # LU-3832
4936         remote_mds_nodsh && skip "remote MDS with nodsh"
4937
4938         local atime_diff=$(do_facet $SINGLEMDS \
4939                 lctl get_param -n mdd.*MDT0000*.atime_diff)
4940         local atime0
4941         local atime1
4942         local atime2
4943
4944         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=1
4945
4946         rm -rf $DIR/$tfile
4947         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 status=noxfer
4948         atime0=$(stat -c %X $DIR/$tfile)
4949
4950         sleep 5
4951         $MULTIOP $DIR/$tfile oO_RDONLY:O_NOATIME:r4096c
4952         atime1=$(stat -c %X $DIR/$tfile)
4953
4954         sleep 5
4955         cancel_lru_locks mdc
4956         cancel_lru_locks osc
4957         $MULTIOP $DIR/$tfile oO_RDONLY:O_NOATIME:r4096c
4958         atime2=$(stat -c %X $DIR/$tfile)
4959
4960         do_facet $SINGLEMDS \
4961                 lctl set_param -n mdd.*MDT0000*.atime_diff=$atime_diff
4962
4963         [ "$atime0" -eq "$atime1" ] || error "atime0 $atime0 != atime1 $atime1"
4964         [ "$atime1" -eq "$atime2" ] || error "atime0 $atime0 != atime1 $atime1"
4965 }
4966 run_test 39n "check that O_NOATIME is honored"
4967
4968 test_39o() {
4969         TESTDIR=$DIR/$tdir/$tfile
4970         [ -e $TESTDIR ] && rm -rf $TESTDIR
4971         mkdir -p $TESTDIR
4972         cd $TESTDIR
4973         links1=2
4974         ls
4975         mkdir a b
4976         ls
4977         links2=$(stat -c %h .)
4978         [ $(($links1 + 2)) != $links2 ] &&
4979                 error "wrong links count $(($links1 + 2)) != $links2"
4980         rmdir b
4981         links3=$(stat -c %h .)
4982         [ $(($links1 + 1)) != $links3 ] &&
4983                 error "wrong links count $links1 != $links3"
4984         return 0
4985 }
4986 run_test 39o "directory cached attributes updated after create"
4987
4988 test_39p() {
4989         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
4990
4991         local MDTIDX=1
4992         TESTDIR=$DIR/$tdir/$tdir
4993         [ -e $TESTDIR ] && rm -rf $TESTDIR
4994         test_mkdir -p $TESTDIR
4995         cd $TESTDIR
4996         links1=2
4997         ls
4998         test_mkdir -i $MDTIDX $TESTDIR/remote_dir1
4999         test_mkdir -i $MDTIDX $TESTDIR/remote_dir2
5000         ls
5001         links2=$(stat -c %h .)
5002         [ $(($links1 + 2)) != $links2 ] &&
5003                 error "wrong links count $(($links1 + 2)) != $links2"
5004         rmdir remote_dir2
5005         links3=$(stat -c %h .)
5006         [ $(($links1 + 1)) != $links3 ] &&
5007                 error "wrong links count $links1 != $links3"
5008         return 0
5009 }
5010 run_test 39p "remote directory cached attributes updated after create ========"
5011
5012 test_39r() {
5013         [ $OST1_VERSION -ge $(version_code 2.13.52) ] ||
5014                 skip "no atime update on old OST"
5015         if [ "$ost1_FSTYPE" != ldiskfs ]; then
5016                 skip_env "ldiskfs only test"
5017         fi
5018
5019         local saved_adiff
5020         saved_adiff=$(do_facet ost1 \
5021                 lctl get_param -n obdfilter.*OST0000.atime_diff)
5022         stack_trap "do_facet ost1 \
5023                 lctl set_param obdfilter.*.atime_diff=$saved_adiff"
5024
5025         do_facet ost1 "lctl set_param obdfilter.*.atime_diff=5"
5026
5027         $LFS setstripe -i 0 $DIR/$tfile
5028         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 ||
5029                 error "can't write initial file"
5030         cancel_lru_locks osc
5031
5032         # exceed atime_diff and access file
5033         sleep 6
5034         dd if=$DIR/$tfile of=/dev/null bs=4k count=1 ||
5035                 error "can't udpate atime"
5036
5037         local atime_cli=$(stat -c %X $DIR/$tfile)
5038         echo "client atime: $atime_cli"
5039         # allow atime update to be written to device
5040         do_facet ost1 "$LCTL set_param -n osd*.*OST*.force_sync 1"
5041         sleep 5
5042
5043         local ostdev=$(ostdevname 1)
5044         local fid=($(lfs getstripe -y $DIR/$tfile |
5045                         awk '/l_fid:/ { print $2 }' | tr ':' ' '))
5046         local objpath="O/0/d$((${fid[1]} % 32))/$((${fid[1]}))"
5047         local cmd="debugfs -c -R \\\"stat $objpath\\\" $ostdev"
5048
5049         echo "OST atime: $(do_facet ost1 "$cmd" |& grep atime)"
5050         local atime_ost=$(do_facet ost1 "$cmd" |&
5051                           awk -F'[: ]' '/atime:/ { print $4 }')
5052         (( atime_cli == atime_ost )) ||
5053                 error "atime on client $atime_cli != ost $atime_ost"
5054 }
5055 run_test 39r "lazy atime update on OST"
5056
5057 test_39q() { # LU-8041
5058         local testdir=$DIR/$tdir
5059         mkdir -p $testdir
5060         multiop_bg_pause $testdir D_c || error "multiop failed"
5061         local multipid=$!
5062         cancel_lru_locks mdc
5063         kill -USR1 $multipid
5064         local atime=$(stat -c %X $testdir)
5065         [ "$atime" -ne 0 ] || error "atime is zero"
5066 }
5067 run_test 39q "close won't zero out atime"
5068
5069 test_40() {
5070         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1
5071         $RUNAS $OPENFILE -f O_WRONLY:O_TRUNC $DIR/$tfile &&
5072                 error "openfile O_WRONLY:O_TRUNC $tfile failed"
5073         $CHECKSTAT -t file -s 4096 $DIR/$tfile ||
5074                 error "$tfile is not 4096 bytes in size"
5075 }
5076 run_test 40 "failed open(O_TRUNC) doesn't truncate ============="
5077
5078 test_41() {
5079         # bug 1553
5080         small_write $DIR/f41 18
5081 }
5082 run_test 41 "test small file write + fstat ====================="
5083
5084 count_ost_writes() {
5085         lctl get_param -n ${OSC}.*.stats |
5086                 awk -vwrites=0 '/ost_write/ { writes += $2 } \
5087                         END { printf("%0.0f", writes) }'
5088 }
5089
5090 # decent default
5091 WRITEBACK_SAVE=500
5092 DIRTY_RATIO_SAVE=40
5093 MAX_DIRTY_RATIO=50
5094 BG_DIRTY_RATIO_SAVE=10
5095 MAX_BG_DIRTY_RATIO=25
5096
5097 start_writeback() {
5098         trap 0
5099         # in 2.6, restore /proc/sys/vm/dirty_writeback_centisecs,
5100         # dirty_ratio, dirty_background_ratio
5101         if [ -f /proc/sys/vm/dirty_writeback_centisecs ]; then
5102                 sysctl -w vm.dirty_writeback_centisecs=$WRITEBACK_SAVE
5103                 sysctl -w vm.dirty_background_ratio=$BG_DIRTY_RATIO_SAVE
5104                 sysctl -w vm.dirty_ratio=$DIRTY_RATIO_SAVE
5105         else
5106                 # if file not here, we are a 2.4 kernel
5107                 kill -CONT `pidof kupdated`
5108         fi
5109 }
5110
5111 stop_writeback() {
5112         # setup the trap first, so someone cannot exit the test at the
5113         # exact wrong time and mess up a machine
5114         trap start_writeback EXIT
5115         # in 2.6, save and 0 /proc/sys/vm/dirty_writeback_centisecs
5116         if [ -f /proc/sys/vm/dirty_writeback_centisecs ]; then
5117                 WRITEBACK_SAVE=`sysctl -n vm.dirty_writeback_centisecs`
5118                 sysctl -w vm.dirty_writeback_centisecs=0
5119                 sysctl -w vm.dirty_writeback_centisecs=0
5120                 # save and increase /proc/sys/vm/dirty_ratio
5121                 DIRTY_RATIO_SAVE=`sysctl -n vm.dirty_ratio`
5122                 sysctl -w vm.dirty_ratio=$MAX_DIRTY_RATIO
5123                 # save and increase /proc/sys/vm/dirty_background_ratio
5124                 BG_DIRTY_RATIO_SAVE=`sysctl -n vm.dirty_background_ratio`
5125                 sysctl -w vm.dirty_background_ratio=$MAX_BG_DIRTY_RATIO
5126         else
5127                 # if file not here, we are a 2.4 kernel
5128                 kill -STOP `pidof kupdated`
5129         fi
5130 }
5131
5132 # ensure that all stripes have some grant before we test client-side cache
5133 setup_test42() {
5134         for i in `seq -f $DIR/f42-%g 1 $OSTCOUNT`; do
5135                 dd if=/dev/zero of=$i bs=4k count=1
5136                 rm $i
5137         done
5138 }
5139
5140 # Tests 42* verify that our behaviour is correct WRT caching, file closure,
5141 # file truncation, and file removal.
5142 test_42a() {
5143         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5144
5145         setup_test42
5146         cancel_lru_locks $OSC
5147         stop_writeback
5148         sync; sleep 1; sync # just to be safe
5149         BEFOREWRITES=`count_ost_writes`
5150         lctl get_param -n osc.*[oO][sS][cC][_-]*.cur_grant_bytes | grep "[0-9]"
5151         dd if=/dev/zero of=$DIR/f42a bs=1024 count=100
5152         AFTERWRITES=`count_ost_writes`
5153         [ $BEFOREWRITES -eq $AFTERWRITES ] || \
5154                 error "$BEFOREWRITES < $AFTERWRITES"
5155         start_writeback
5156 }
5157 run_test 42a "ensure that we don't flush on close"
5158
5159 test_42b() {
5160         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5161
5162         setup_test42
5163         cancel_lru_locks $OSC
5164         stop_writeback
5165         sync
5166         dd if=/dev/zero of=$DIR/f42b bs=1024 count=100
5167         BEFOREWRITES=$(count_ost_writes)
5168         $MUNLINK $DIR/f42b || error "$MUNLINK $DIR/f42b: $?"
5169         AFTERWRITES=$(count_ost_writes)
5170         if [[ $BEFOREWRITES -lt $AFTERWRITES ]]; then
5171                 error "$BEFOREWRITES < $AFTERWRITES on unlink"
5172         fi
5173         BEFOREWRITES=$(count_ost_writes)
5174         sync || error "sync: $?"
5175         AFTERWRITES=$(count_ost_writes)
5176         if [[ $BEFOREWRITES -lt $AFTERWRITES ]]; then
5177                 error "$BEFOREWRITES < $AFTERWRITES on sync"
5178         fi
5179         dmesg | grep 'error from obd_brw_async' && error 'error writing back'
5180         start_writeback
5181         return 0
5182 }
5183 run_test 42b "test destroy of file with cached dirty data ======"
5184
5185 # if these tests just want to test the effect of truncation,
5186 # they have to be very careful.  consider:
5187 # - the first open gets a {0,EOF}PR lock
5188 # - the first write conflicts and gets a {0, count-1}PW
5189 # - the rest of the writes are under {count,EOF}PW
5190 # - the open for truncate tries to match a {0,EOF}PR
5191 #   for the filesize and cancels the PWs.
5192 # any number of fixes (don't get {0,EOF} on open, match
5193 # composite locks, do smarter file size management) fix
5194 # this, but for now we want these tests to verify that
5195 # the cancellation with truncate intent works, so we
5196 # start the file with a full-file pw lock to match against
5197 # until the truncate.
5198 trunc_test() {
5199         test=$1
5200         file=$DIR/$test
5201         offset=$2
5202         cancel_lru_locks $OSC
5203         stop_writeback
5204         # prime the file with 0,EOF PW to match
5205         touch $file
5206         $TRUNCATE $file 0
5207         sync; sync
5208         # now the real test..
5209         dd if=/dev/zero of=$file bs=1024 count=100
5210         BEFOREWRITES=`count_ost_writes`
5211         $TRUNCATE $file $offset
5212         cancel_lru_locks $OSC
5213         AFTERWRITES=`count_ost_writes`
5214         start_writeback
5215 }
5216
5217 test_42c() {
5218         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5219
5220         trunc_test 42c 1024
5221         [ $BEFOREWRITES -eq $AFTERWRITES ] &&
5222                 error "beforewrites $BEFOREWRITES == afterwrites $AFTERWRITES on truncate"
5223         rm $file
5224 }
5225 run_test 42c "test partial truncate of file with cached dirty data"
5226
5227 test_42d() {
5228         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5229
5230         trunc_test 42d 0
5231         [ $BEFOREWRITES -eq $AFTERWRITES ] ||
5232                 error "beforewrites $BEFOREWRITES != afterwrites $AFTERWRITES on truncate"
5233         rm $file
5234 }
5235 run_test 42d "test complete truncate of file with cached dirty data"
5236
5237 test_42e() { # bug22074
5238         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5239
5240         local TDIR=$DIR/${tdir}e
5241         local pages=16 # hardcoded 16 pages, don't change it.
5242         local files=$((OSTCOUNT * 500)) # hopefully 500 files on each OST
5243         local proc_osc0="osc.${FSNAME}-OST0000-osc-[^MDT]*"
5244         local max_dirty_mb
5245         local warmup_files
5246
5247         test_mkdir $DIR/${tdir}e
5248         $LFS setstripe -c 1 $TDIR
5249         createmany -o $TDIR/f $files
5250
5251         max_dirty_mb=$($LCTL get_param -n $proc_osc0/max_dirty_mb)
5252
5253         # we assume that with $OSTCOUNT files, at least one of them will
5254         # be allocated on OST0.
5255         warmup_files=$((OSTCOUNT * max_dirty_mb))
5256         createmany -o $TDIR/w $warmup_files
5257
5258         # write a large amount of data into one file and sync, to get good
5259         # avail_grant number from OST.
5260         for ((i=0; i<$warmup_files; i++)); do
5261                 idx=$($LFS getstripe -i $TDIR/w$i)
5262                 [ $idx -ne 0 ] && continue
5263                 dd if=/dev/zero of=$TDIR/w$i bs="$max_dirty_mb"M count=1
5264                 break
5265         done
5266         [[ $i -gt $warmup_files ]] && error "OST0 is still cold"
5267         sync
5268         $LCTL get_param $proc_osc0/cur_dirty_bytes
5269         $LCTL get_param $proc_osc0/cur_grant_bytes
5270
5271         # create as much dirty pages as we can while not to trigger the actual
5272         # RPCs directly. but depends on the env, VFS may trigger flush during this
5273         # period, hopefully we are good.
5274         for ((i=0; i<$warmup_files; i++)); do
5275                 idx=$($LFS getstripe -i $TDIR/w$i)
5276                 [ $idx -ne 0 ] && continue
5277                 dd if=/dev/zero of=$TDIR/w$i bs=1M count=1 2>/dev/null
5278         done
5279         $LCTL get_param $proc_osc0/cur_dirty_bytes
5280         $LCTL get_param $proc_osc0/cur_grant_bytes
5281
5282         # perform the real test
5283         $LCTL set_param $proc_osc0/rpc_stats 0
5284         for ((;i<$files; i++)); do
5285                 [ $($LFS getstripe -i $TDIR/f$i) -eq 0 ] || continue
5286                 dd if=/dev/zero of=$TDIR/f$i bs=$PAGE_SIZE count=$pages 2>/dev/null
5287         done
5288         sync
5289         $LCTL get_param $proc_osc0/rpc_stats
5290
5291         local percent=0
5292         local have_ppr=false
5293         $LCTL get_param $proc_osc0/rpc_stats |
5294                 while read PPR RRPC RPCT RCUM BAR WRPC WPCT WCUM; do
5295                         # skip lines until we are at the RPC histogram data
5296                         [ "$PPR" == "pages" ] && have_ppr=true && continue
5297                         $have_ppr || continue
5298
5299                         # we only want the percent stat for < 16 pages
5300                         [[ $(echo $PPR | tr -d ':') -ge $pages ]] && break
5301
5302                         percent=$((percent + WPCT))
5303                         if [[ $percent -gt 15 ]]; then
5304                                 error "less than 16-pages write RPCs" \
5305                                       "$percent% > 15%"
5306                                 break
5307                         fi
5308                 done
5309         rm -rf $TDIR
5310 }
5311 run_test 42e "verify sub-RPC writes are not done synchronously"
5312
5313 test_43A() { # was test_43
5314         test_mkdir $DIR/$tdir
5315         cp -p /bin/ls $DIR/$tdir/$tfile
5316         $MULTIOP $DIR/$tdir/$tfile Ow_c &
5317         pid=$!
5318         # give multiop a chance to open
5319         sleep 1
5320
5321         $DIR/$tdir/$tfile && error "execute $DIR/$tdir/$tfile succeeded" || true
5322         kill -USR1 $pid
5323         # Wait for multiop to exit
5324         wait $pid
5325 }
5326 run_test 43A "execution of file opened for write should return -ETXTBSY"
5327
5328 test_43a() {
5329         test_mkdir $DIR/$tdir
5330         cp -p $(which sleep) $DIR/$tdir/sleep || error "can't copy"
5331         $DIR/$tdir/sleep 60 &
5332         SLEEP_PID=$!
5333         # Make sure exec of $tdir/sleep wins race with truncate
5334         sleep 1
5335         $MULTIOP $DIR/$tdir/sleep Oc && error "expected error, got success"
5336         kill $SLEEP_PID
5337 }
5338 run_test 43a "open(RDWR) of file being executed should return -ETXTBSY"
5339
5340 test_43b() {
5341         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5342
5343         test_mkdir $DIR/$tdir
5344         cp -p $(which sleep) $DIR/$tdir/sleep || error "can't copy"
5345         $DIR/$tdir/sleep 60 &
5346         SLEEP_PID=$!
5347         # Make sure exec of $tdir/sleep wins race with truncate
5348         sleep 1
5349         $TRUNCATE $DIR/$tdir/sleep 0 && error "expected error, got success"
5350         kill $SLEEP_PID
5351 }
5352 run_test 43b "truncate of file being executed should return -ETXTBSY"
5353
5354 test_43c() {
5355         local testdir="$DIR/$tdir"
5356         test_mkdir $testdir
5357         cp $SHELL $testdir/
5358         ( cd $(dirname $SHELL) && md5sum $(basename $SHELL) ) |
5359                 ( cd $testdir && md5sum -c )
5360 }
5361 run_test 43c "md5sum of copy into lustre"
5362
5363 test_44A() { # was test_44
5364         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
5365
5366         dd if=/dev/zero of=$DIR/f1 bs=4k count=1 seek=1023
5367         dd if=$DIR/f1 bs=4k count=1 > /dev/null
5368 }
5369 run_test 44A "zero length read from a sparse stripe"
5370
5371 test_44a() {
5372         local nstripe=$($LFS getstripe -c -d $DIR)
5373         [ -z "$nstripe" ] && skip "can't get stripe info"
5374         [[ $nstripe -gt $OSTCOUNT ]] &&
5375                 skip "Wrong default stripe_count: $nstripe OSTCOUNT: $OSTCOUNT"
5376
5377         local stride=$($LFS getstripe -S -d $DIR)
5378         if [[ $nstripe -eq 0 || $nstripe -eq -1 ]]; then
5379                 nstripe=$($LFS df $DIR | grep OST: | wc -l)
5380         fi
5381
5382         OFFSETS="0 $((stride/2)) $((stride-1))"
5383         for offset in $OFFSETS; do
5384                 for i in $(seq 0 $((nstripe-1))); do
5385                         local GLOBALOFFSETS=""
5386                         # size in Bytes
5387                         local size=$((((i + 2 * $nstripe )*$stride + $offset)))
5388                         local myfn=$DIR/d44a-$size
5389                         echo "--------writing $myfn at $size"
5390                         ll_sparseness_write $myfn $size ||
5391                                 error "ll_sparseness_write"
5392                         GLOBALOFFSETS="$GLOBALOFFSETS $size"
5393                         ll_sparseness_verify $myfn $GLOBALOFFSETS ||
5394                                 error "ll_sparseness_verify $GLOBALOFFSETS"
5395
5396                         for j in $(seq 0 $((nstripe-1))); do
5397                                 # size in Bytes
5398                                 size=$((((j + $nstripe )*$stride + $offset)))
5399                                 ll_sparseness_write $myfn $size ||
5400                                         error "ll_sparseness_write"
5401                                 GLOBALOFFSETS="$GLOBALOFFSETS $size"
5402                         done
5403                         ll_sparseness_verify $myfn $GLOBALOFFSETS ||
5404                                 error "ll_sparseness_verify $GLOBALOFFSETS"
5405                         rm -f $myfn
5406                 done
5407         done
5408 }
5409 run_test 44a "test sparse pwrite ==============================="
5410
5411 dirty_osc_total() {
5412         tot=0
5413         for d in `lctl get_param -n ${OSC}.*.cur_dirty_bytes`; do
5414                 tot=$(($tot + $d))
5415         done
5416         echo $tot
5417 }
5418 do_dirty_record() {
5419         before=`dirty_osc_total`
5420         echo executing "\"$*\""
5421         eval $*
5422         after=`dirty_osc_total`
5423         echo before $before, after $after
5424 }
5425 test_45() {
5426         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5427
5428         f="$DIR/f45"
5429         # Obtain grants from OST if it supports it
5430         echo blah > ${f}_grant
5431         stop_writeback
5432         sync
5433         do_dirty_record "echo blah > $f"
5434         [[ $before -eq $after ]] && error "write wasn't cached"
5435         do_dirty_record "> $f"
5436         [[ $before -gt $after ]] || error "truncate didn't lower dirty count"
5437         do_dirty_record "echo blah > $f"
5438         [[ $before -eq $after ]] && error "write wasn't cached"
5439         do_dirty_record "sync"
5440         [[ $before -gt $after ]] || error "writeback didn't lower dirty count"
5441         do_dirty_record "echo blah > $f"
5442         [[ $before -eq $after ]] && error "write wasn't cached"
5443         do_dirty_record "cancel_lru_locks osc"
5444         [[ $before -gt $after ]] ||
5445                 error "lock cancellation didn't lower dirty count"
5446         start_writeback
5447 }
5448 run_test 45 "osc io page accounting ============================"
5449
5450 # in a 2 stripe file (lov.sh), page 1023 maps to page 511 in its object.  this
5451 # test tickles a bug where re-dirtying a page was failing to be mapped to the
5452 # objects offset and an assert hit when an rpc was built with 1023's mapped
5453 # offset 511 and 511's raw 511 offset. it also found general redirtying bugs.
5454 test_46() {
5455         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5456
5457         f="$DIR/f46"
5458         stop_writeback
5459         sync
5460         dd if=/dev/zero of=$f bs=$PAGE_SIZE seek=511 count=1
5461         sync
5462         dd conv=notrunc if=/dev/zero of=$f bs=$PAGE_SIZE seek=1023 count=1
5463         dd conv=notrunc if=/dev/zero of=$f bs=$PAGE_SIZE seek=511 count=1
5464         sync
5465         start_writeback
5466 }
5467 run_test 46 "dirtying a previously written page ================"
5468
5469 # test_47 is removed "Device nodes check" is moved to test_28
5470
5471 test_48a() { # bug 2399
5472         [ "$mds1_FSTYPE" = "zfs" ] &&
5473         [ $MDS1_VERSION -lt $(version_code 2.3.63) ] &&
5474                 skip "MDS prior to 2.3.63 handle ZFS dir .. incorrectly"
5475
5476         test_mkdir $DIR/$tdir
5477         cd $DIR/$tdir
5478         mv $DIR/$tdir $DIR/$tdir.new || error "move directory failed"
5479         test_mkdir $DIR/$tdir
5480         touch foo || error "'touch foo' failed after recreating cwd"
5481         test_mkdir bar
5482         touch .foo || error "'touch .foo' failed after recreating cwd"
5483         test_mkdir .bar
5484         ls . > /dev/null || error "'ls .' failed after recreating cwd"
5485         ls .. > /dev/null || error "'ls ..' failed after removing cwd"
5486         cd . || error "'cd .' failed after recreating cwd"
5487         mkdir . && error "'mkdir .' worked after recreating cwd"
5488         rmdir . && error "'rmdir .' worked after recreating cwd"
5489         ln -s . baz || error "'ln -s .' failed after recreating cwd"
5490         cd .. || error "'cd ..' failed after recreating cwd"
5491 }
5492 run_test 48a "Access renamed working dir (should return errors)="
5493
5494 test_48b() { # bug 2399
5495         rm -rf $DIR/$tdir
5496         test_mkdir $DIR/$tdir
5497         cd $DIR/$tdir
5498         rmdir $DIR/$tdir || error "remove cwd $DIR/$tdir failed"
5499         touch foo && error "'touch foo' worked after removing cwd"
5500         mkdir foo && error "'mkdir foo' worked after removing cwd"
5501         touch .foo && error "'touch .foo' worked after removing cwd"
5502         mkdir .foo && error "'mkdir .foo' worked after removing cwd"
5503         ls . > /dev/null && error "'ls .' worked after removing cwd"
5504         ls .. > /dev/null || error "'ls ..' failed after removing cwd"
5505         mkdir . && error "'mkdir .' worked after removing cwd"
5506         rmdir . && error "'rmdir .' worked after removing cwd"
5507         ln -s . foo && error "'ln -s .' worked after removing cwd"
5508         cd .. || echo "'cd ..' failed after removing cwd `pwd`"  #bug 3517
5509 }
5510 run_test 48b "Access removed working dir (should return errors)="
5511
5512 test_48c() { # bug 2350
5513         #lctl set_param debug=-1
5514         #set -vx
5515         rm -rf $DIR/$tdir
5516         test_mkdir -p $DIR/$tdir/dir
5517         cd $DIR/$tdir/dir
5518         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
5519         $TRACE touch foo && error "touch foo worked after removing cwd"
5520         $TRACE mkdir foo && error "'mkdir foo' worked after removing cwd"
5521         touch .foo && error "touch .foo worked after removing cwd"
5522         mkdir .foo && error "mkdir .foo worked after removing cwd"
5523         $TRACE ls . && error "'ls .' worked after removing cwd"
5524         $TRACE ls .. || error "'ls ..' failed after removing cwd"
5525         $TRACE mkdir . && error "'mkdir .' worked after removing cwd"
5526         $TRACE rmdir . && error "'rmdir .' worked after removing cwd"
5527         $TRACE ln -s . foo && error "'ln -s .' worked after removing cwd"
5528         $TRACE cd .. || echo "'cd ..' failed after removing cwd `pwd`" #bug 3415
5529 }
5530 run_test 48c "Access removed working subdir (should return errors)"
5531
5532 test_48d() { # bug 2350
5533         #lctl set_param debug=-1
5534         #set -vx
5535         rm -rf $DIR/$tdir
5536         test_mkdir -p $DIR/$tdir/dir
5537         cd $DIR/$tdir/dir
5538         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
5539         $TRACE rmdir $DIR/$tdir || error "remove parent $DIR/$tdir failed"
5540         $TRACE touch foo && error "'touch foo' worked after removing parent"
5541         $TRACE mkdir foo && error "mkdir foo worked after removing parent"
5542         touch .foo && error "'touch .foo' worked after removing parent"
5543         mkdir .foo && error "mkdir .foo worked after removing parent"
5544         $TRACE ls . && error "'ls .' worked after removing parent"
5545         $TRACE ls .. && error "'ls ..' worked after removing parent"
5546         $TRACE mkdir . && error "'mkdir .' worked after removing parent"
5547         $TRACE rmdir . && error "'rmdir .' worked after removing parent"
5548         $TRACE ln -s . foo && error "'ln -s .' worked after removing parent"
5549         true
5550 }
5551 run_test 48d "Access removed parent subdir (should return errors)"
5552
5553 test_48e() { # bug 4134
5554         #lctl set_param debug=-1
5555         #set -vx
5556         rm -rf $DIR/$tdir
5557         test_mkdir -p $DIR/$tdir/dir
5558         cd $DIR/$tdir/dir
5559         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
5560         $TRACE rmdir $DIR/$tdir || error "remove parent $DIR/$tdir failed"
5561         $TRACE touch $DIR/$tdir || error "'touch $DIR/$tdir' failed"
5562         $TRACE chmod +x $DIR/$tdir || error "'chmod +x $DIR/$tdir' failed"
5563         # On a buggy kernel addition of "touch foo" after cd .. will
5564         # produce kernel oops in lookup_hash_it
5565         touch ../foo && error "'cd ..' worked after recreate parent"
5566         cd $DIR
5567         $TRACE rm $DIR/$tdir || error "rm '$DIR/$tdir' failed"
5568 }
5569 run_test 48e "Access to recreated parent subdir (should return errors)"
5570
5571 test_48f() {
5572         [[ $MDS1_VERSION -ge $(version_code 2.13.55) ]] ||
5573                 skip "need MDS >= 2.13.55"
5574         [[ $MDSCOUNT -ge 2 ]] || skip "needs >= 2 MDTs"
5575         [[ "$(facet_host mds1)" != "$(facet_host mds2)" ]] ||
5576                 skip "needs different host for mdt1 mdt2"
5577         [[ $(facet_fstype mds1) == ldiskfs ]] || skip "ldiskfs only"
5578
5579         $LFS mkdir -i0 $DIR/$tdir
5580         $LFS mkdir -i 1 $DIR/$tdir/sub1 $DIR/$tdir/sub2 $DIR/$tdir/sub3
5581
5582         for d in sub1 sub2 sub3; do
5583                 #define OBD_FAIL_OSD_REF_DEL    0x19c
5584                 do_facet mds1 $LCTL set_param fail_loc=0x8000019c
5585                 rm -rf $DIR/$tdir/$d && error "rm $d should fail"
5586         done
5587
5588         rm -d --interactive=never $DIR/$tdir || error "rm $tdir fail"
5589 }
5590 run_test 48f "non-zero nlink dir unlink won't LBUG()"
5591
5592 test_49() { # LU-1030
5593         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5594         remote_ost_nodsh && skip "remote OST with nodsh"
5595
5596         # get ost1 size - $FSNAME-OST0000
5597         ost1_size=$(do_facet ost1 $LFS df | grep ${ost1_svc} |
5598                 awk '{ print $4 }')
5599         # write 800M at maximum
5600         [[ $ost1_size -lt 2 ]] && ost1_size=2
5601         [[ $ost1_size -gt 819200 ]] && ost1_size=819200
5602
5603         $LFS setstripe -c 1 -i 0 $DIR/$tfile
5604         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((ost1_size >> 2)) &
5605         local dd_pid=$!
5606
5607         # change max_pages_per_rpc while writing the file
5608         local osc1_mppc=osc.$(get_osc_import_name client ost1).max_pages_per_rpc
5609         local orig_mppc=$($LCTL get_param -n $osc1_mppc)
5610         # loop until dd process exits
5611         while ps ax -opid | grep -wq $dd_pid; do
5612                 $LCTL set_param $osc1_mppc=$((RANDOM % 256 + 1))
5613                 sleep $((RANDOM % 5 + 1))
5614         done
5615         # restore original max_pages_per_rpc
5616         $LCTL set_param $osc1_mppc=$orig_mppc
5617         rm $DIR/$tfile || error "rm $DIR/$tfile failed"
5618 }
5619 run_test 49 "Change max_pages_per_rpc won't break osc extent"
5620
5621 test_50() {
5622         # bug 1485
5623         test_mkdir $DIR/$tdir
5624         cd $DIR/$tdir
5625         ls /proc/$$/cwd || error "ls /proc/$$/cwd failed"
5626 }
5627 run_test 50 "special situations: /proc symlinks  ==============="
5628
5629 test_51a() {    # was test_51
5630         # bug 1516 - create an empty entry right after ".." then split dir
5631         test_mkdir -c1 $DIR/$tdir
5632         touch $DIR/$tdir/foo
5633         $MCREATE $DIR/$tdir/bar
5634         rm $DIR/$tdir/foo
5635         createmany -m $DIR/$tdir/longfile 201
5636         FNUM=202
5637         while [[ $(ls -sd $DIR/$tdir | awk '{ print $1 }') -eq 4 ]]; do
5638                 $MCREATE $DIR/$tdir/longfile$FNUM
5639                 FNUM=$(($FNUM + 1))
5640                 echo -n "+"
5641         done
5642         echo
5643         ls -l $DIR/$tdir > /dev/null || error "ls -l $DIR/$tdir failed"
5644 }
5645 run_test 51a "special situations: split htree with empty entry =="
5646
5647 cleanup_print_lfs_df () {
5648         trap 0
5649         $LFS df
5650         $LFS df -i
5651 }
5652
5653 test_51b() {
5654         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5655
5656         local dir=$DIR/$tdir
5657         local nrdirs=$((65536 + 100))
5658
5659         # cleanup the directory
5660         rm -fr $dir
5661
5662         mkdir_on_mdt -i $((RANDOM % MDSCOUNT)) $dir
5663
5664         $LFS df
5665         $LFS df -i
5666         local mdtidx=$(printf "%04x" $($LFS getstripe -m $dir))
5667         local numfree=$(lctl get_param -n mdc.$FSNAME-MDT$mdtidx*.filesfree)
5668         [[ $numfree -lt $nrdirs ]] &&
5669                 skip "not enough free inodes ($numfree) on MDT$mdtidx"
5670
5671         # need to check free space for the directories as well
5672         local blkfree=$(lctl get_param -n mdc.$FSNAME-MDT$mdtidx*.kbytesavail)
5673         numfree=$(( blkfree / $(fs_inode_ksize) ))
5674         [[ $numfree -lt $nrdirs ]] && skip "not enough blocks ($numfree)"
5675
5676         trap cleanup_print_lfs_df EXIT
5677
5678         # create files
5679         createmany -d $dir/d $nrdirs || {
5680                 unlinkmany $dir/d $nrdirs
5681                 error "failed to create $nrdirs subdirs in MDT$mdtidx:$dir"
5682         }
5683
5684         # really created :
5685         nrdirs=$(ls -U $dir | wc -l)
5686
5687         # unlink all but 100 subdirectories, then check it still works
5688         local left=100
5689         local delete=$((nrdirs - left))
5690
5691         $LFS df
5692         $LFS df -i
5693
5694         # for ldiskfs the nlink count should be 1, but this is OSD specific
5695         # and so this is listed for informational purposes only
5696         echo "nlink before: $(stat -c %h $dir), created before: $nrdirs"
5697         unlinkmany -d $dir/d $delete ||
5698                 error "unlink of first $delete subdirs failed"
5699
5700         echo "nlink between: $(stat -c %h $dir)"
5701         local found=$(ls -U $dir | wc -l)
5702         [ $found -ne $left ] &&
5703                 error "can't find subdirs: found only $found, expected $left"
5704
5705         unlinkmany -d $dir/d $delete $left ||
5706                 error "unlink of second $left subdirs failed"
5707         # regardless of whether the backing filesystem tracks nlink accurately
5708         # or not, the nlink count shouldn't be more than "." and ".." here
5709         local after=$(stat -c %h $dir)
5710         [[ $after -gt 2 ]] && error "nlink after: $after > 2" ||
5711                 echo "nlink after: $after"
5712
5713         cleanup_print_lfs_df
5714 }
5715 run_test 51b "exceed 64k subdirectory nlink limit on create, verify unlink"
5716
5717 test_51d() {
5718         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5719         [[ $OSTCOUNT -lt 3 ]] && skip_env "needs >= 3 OSTs"
5720         local qos_old
5721
5722         test_mkdir $DIR/$tdir
5723         $LFS setstripe -c $OSTCOUNT $DIR/$tdir
5724
5725         qos_old=$(do_facet mds1 \
5726                 "$LCTL get_param -n lod.$FSNAME-*.qos_threshold_rr" | head -n 1)
5727         do_nodes $(comma_list $(mdts_nodes)) \
5728                 "$LCTL set_param lod.$FSNAME-*.qos_threshold_rr=100"
5729         stack_trap "do_nodes $(comma_list $(mdts_nodes)) \
5730                 '$LCTL set_param lod.$FSNAME-*.qos_threshold_rr=${qos_old%%%}'"
5731
5732         createmany -o $DIR/$tdir/t- 1000
5733         $LFS getstripe $DIR/$tdir > $TMP/$tfile
5734         for ((n = 0; n < $OSTCOUNT; n++)); do
5735                 objs[$n]=$(awk -vobjs=0 '($1 == '$n') { objs += 1 } \
5736                            END { printf("%0.0f", objs) }' $TMP/$tfile)
5737                 objs0[$n]=$(grep -A 1 idx $TMP/$tfile | awk -vobjs=0 \
5738                             '($1 == '$n') { objs += 1 } \
5739                             END { printf("%0.0f", objs) }')
5740                 log "OST$n has ${objs[$n]} objects, ${objs0[$n]} are index 0"
5741         done
5742         unlinkmany $DIR/$tdir/t- 1000
5743
5744         nlast=0
5745         for ((n = 0; n < $OSTCOUNT; n++)); do
5746                 (( ${objs[$n]} > ${objs[$nlast]} * 4 / 5 )) ||
5747                         { $LFS df && $LFS df -i &&
5748                         error "OST $n has fewer objects vs. OST $nlast" \
5749                               " (${objs[$n]} < ${objs[$nlast]}"; }
5750                 (( ${objs[$n]} < ${objs[$nlast]} * 5 / 4 )) ||
5751                         { $LFS df && $LFS df -i &&
5752                         error "OST $n has fewer objects vs. OST $nlast" \
5753                               " (${objs[$n]} < ${objs[$nlast]}"; }
5754
5755                 (( ${objs0[$n]} > ${objs0[$nlast]} * 4 / 5 )) ||
5756                         { $LFS df && $LFS df -i &&
5757                         error "OST $n has fewer #0 objects vs. OST $nlast" \
5758                               " (${objs0[$n]} < ${objs0[$nlast]}"; }
5759                 (( ${objs0[$n]} < ${objs0[$nlast]} * 5 / 4 )) ||
5760                         { $LFS df && $LFS df -i &&
5761                         error "OST $n has fewer #0 objects vs. OST $nlast" \
5762                               " (${objs0[$n]} < ${objs0[$nlast]}"; }
5763                 nlast=$n
5764         done
5765 }
5766 run_test 51d "check object distribution"
5767
5768 test_51e() {
5769         if [ "$mds1_FSTYPE" != ldiskfs ]; then
5770                 skip_env "ldiskfs only test"
5771         fi
5772
5773         test_mkdir -c1 $DIR/$tdir
5774         test_mkdir -c1 $DIR/$tdir/d0
5775
5776         touch $DIR/$tdir/d0/foo
5777         createmany -l $DIR/$tdir/d0/foo $DIR/$tdir/d0/f- 65001 &&
5778                 error "file exceed 65000 nlink limit!"
5779         unlinkmany $DIR/$tdir/d0/f- 65001
5780         return 0
5781 }
5782 run_test 51e "check file nlink limit"
5783
5784 test_51f() {
5785         test_mkdir $DIR/$tdir
5786
5787         local max=100000
5788         local ulimit_old=$(ulimit -n)
5789         local spare=20 # number of spare fd's for scripts/libraries, etc.
5790         local mdt=$($LFS getstripe -m $DIR/$tdir)
5791         local numfree=$($LFS df -i $DIR/$tdir | awk '/MDT:'$mdt'/ { print $4 }')
5792
5793         echo "MDT$mdt numfree=$numfree, max=$max"
5794         [[ $numfree -gt $max ]] && numfree=$max || numfree=$((numfree * 7 / 8))
5795         if [ $((numfree + spare)) -gt $ulimit_old ]; then
5796                 while ! ulimit -n $((numfree + spare)); do
5797                         numfree=$((numfree * 3 / 4))
5798                 done
5799                 echo "changed ulimit from $ulimit_old to $((numfree + spare))"
5800         else
5801                 echo "left ulimit at $ulimit_old"
5802         fi
5803
5804         createmany -o -k -t 120 $DIR/$tdir/f $numfree || {
5805                 unlinkmany $DIR/$tdir/f $numfree
5806                 error "create+open $numfree files in $DIR/$tdir failed"
5807         }
5808         ulimit -n $ulimit_old
5809
5810         # if createmany exits at 120s there will be fewer than $numfree files
5811         unlinkmany $DIR/$tdir/f $numfree || true
5812 }
5813 run_test 51f "check many open files limit"
5814
5815 test_52a() {
5816         [ -f $DIR/$tdir/foo ] && chattr -a $DIR/$tdir/foo
5817         test_mkdir $DIR/$tdir
5818         touch $DIR/$tdir/foo
5819         chattr +a $DIR/$tdir/foo || error "chattr +a failed"
5820         echo bar >> $DIR/$tdir/foo || error "append bar failed"
5821         cp /etc/hosts $DIR/$tdir/foo && error "cp worked"
5822         rm -f $DIR/$tdir/foo 2>/dev/null && error "rm worked"
5823         link $DIR/$tdir/foo $DIR/$tdir/foo_link 2>/dev/null &&
5824                                         error "link worked"
5825         echo foo >> $DIR/$tdir/foo || error "append foo failed"
5826         mrename $DIR/$tdir/foo $DIR/$tdir/foo_ren && error "rename worked"
5827         lsattr $DIR/$tdir/foo | egrep -q "^-+a[-e]+ $DIR/$tdir/foo" ||
5828                                                      error "lsattr"
5829         chattr -a $DIR/$tdir/foo || error "chattr -a failed"
5830         cp -r $DIR/$tdir $TMP/
5831         rm -fr $DIR/$tdir $TMP/$tdir || error "cleanup rm failed"
5832 }
5833 run_test 52a "append-only flag test (should return errors)"
5834
5835 test_52b() {
5836         [ -f $DIR/$tdir/foo ] && chattr -i $DIR/$tdir/foo
5837         test_mkdir $DIR/$tdir
5838         touch $DIR/$tdir/foo
5839         chattr +i $DIR/$tdir/foo || error "chattr +i failed"
5840         cat test > $DIR/$tdir/foo && error "cat test worked"
5841         cp /etc/hosts $DIR/$tdir/foo && error "cp worked"
5842         rm -f $DIR/$tdir/foo 2>/dev/null && error "rm worked"
5843         link $DIR/$tdir/foo $DIR/$tdir/foo_link 2>/dev/null &&
5844                                         error "link worked"
5845         echo foo >> $DIR/$tdir/foo && error "echo worked"
5846         mrename $DIR/$tdir/foo $DIR/$tdir/foo_ren && error "rename worked"
5847         [ -f $DIR/$tdir/foo ] || error "$tdir/foo is not a file"
5848         [ -f $DIR/$tdir/foo_ren ] && error "$tdir/foo_ren is not a file"
5849         lsattr $DIR/$tdir/foo | egrep -q "^-+i[-e]+ $DIR/$tdir/foo" ||
5850                                                         error "lsattr"
5851         chattr -i $DIR/$tdir/foo || error "chattr failed"
5852
5853         rm -fr $DIR/$tdir || error "unable to remove $DIR/$tdir"
5854 }
5855 run_test 52b "immutable flag test (should return errors) ======="
5856
5857 test_53() {
5858         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5859         remote_mds_nodsh && skip "remote MDS with nodsh"
5860         remote_ost_nodsh && skip "remote OST with nodsh"
5861
5862         local param
5863         local param_seq
5864         local ostname
5865         local mds_last
5866         local mds_last_seq
5867         local ost_last
5868         local ost_last_seq
5869         local ost_last_id
5870         local ostnum
5871         local node
5872         local found=false
5873         local support_last_seq=true
5874
5875         [[ $MDS1_VERSION -ge $(version_code 2.3.60) ]] ||
5876                 support_last_seq=false
5877
5878         # only test MDT0000
5879         local mdtosc=$(get_mdtosc_proc_path $SINGLEMDS)
5880         local value
5881         for value in $(do_facet $SINGLEMDS \
5882                        $LCTL get_param osp.$mdtosc.prealloc_last_id) ; do
5883                 param=$(echo ${value[0]} | cut -d "=" -f1)
5884                 ostname=$(echo $param | cut -d "." -f2 | cut -d - -f 1-2)
5885
5886                 if $support_last_seq; then
5887                         param_seq=$(echo $param |
5888                                 sed -e s/prealloc_last_id/prealloc_last_seq/g)
5889                         mds_last_seq=$(do_facet $SINGLEMDS \
5890                                        $LCTL get_param -n $param_seq)
5891                 fi
5892                 mds_last=$(do_facet $SINGLEMDS $LCTL get_param -n $param)
5893
5894                 ostnum=$(index_from_ostuuid ${ostname}_UUID)
5895                 node=$(facet_active_host ost$((ostnum+1)))
5896                 param="obdfilter.$ostname.last_id"
5897                 for ost_last in $(do_node $node $LCTL get_param -n $param) ; do
5898                         echo "$ostname.last_id=$ost_last; MDS.last_id=$mds_last"
5899                         ost_last_id=$ost_last
5900
5901                         if $support_last_seq; then
5902                                 ost_last_id=$(echo $ost_last |
5903                                               awk -F':' '{print $2}' |
5904                                               sed -e "s/^0x//g")
5905                                 ost_last_seq=$(echo $ost_last |
5906                                                awk -F':' '{print $1}')
5907                                 [[ $ost_last_seq = $mds_last_seq ]] || continue
5908                         fi
5909
5910                         if [[ $ost_last_id != $mds_last ]]; then
5911                                 error "$ost_last_id != $mds_last"
5912                         else
5913                                 found=true
5914                                 break
5915                         fi
5916                 done
5917         done
5918         $found || error "can not match last_seq/last_id for $mdtosc"
5919         return 0
5920 }
5921 run_test 53 "verify that MDS and OSTs agree on pre-creation ===="
5922
5923 test_54a() {
5924         perl -MSocket -e ';' || skip "no Socket perl module installed"
5925
5926         $SOCKETSERVER $DIR/socket ||
5927                 error "$SOCKETSERVER $DIR/socket failed: $?"
5928         $SOCKETCLIENT $DIR/socket ||
5929                 error "$SOCKETCLIENT $DIR/socket failed: $?"
5930         $MUNLINK $DIR/socket || error "$MUNLINK $DIR/socket failed: $?"
5931 }
5932 run_test 54a "unix domain socket test =========================="
5933
5934 test_54b() {
5935         f="$DIR/f54b"
5936         mknod $f c 1 3
5937         chmod 0666 $f
5938         dd if=/dev/zero of=$f bs=$PAGE_SIZE count=1
5939 }
5940 run_test 54b "char device works in lustre ======================"
5941
5942 find_loop_dev() {
5943         [ -b /dev/loop/0 ] && LOOPBASE=/dev/loop/
5944         [ -b /dev/loop0 ] && LOOPBASE=/dev/loop
5945         [ -z "$LOOPBASE" ] && echo "/dev/loop/0 and /dev/loop0 gone?" && return
5946
5947         for i in $(seq 3 7); do
5948                 losetup $LOOPBASE$i > /dev/null 2>&1 && continue
5949                 LOOPDEV=$LOOPBASE$i
5950                 LOOPNUM=$i
5951                 break
5952         done
5953 }
5954
5955 cleanup_54c() {
5956         local rc=0
5957         loopdev="$DIR/loop54c"
5958
5959         trap 0
5960         $UMOUNT $DIR/$tdir || rc=$?
5961         losetup -d $loopdev || true
5962         losetup -d $LOOPDEV || true
5963         rm -rf $loopdev $DIR/$tfile $DIR/$tdir
5964         return $rc
5965 }
5966
5967 test_54c() {
5968         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5969
5970         loopdev="$DIR/loop54c"
5971
5972         find_loop_dev
5973         [ -z "$LOOPNUM" ] && skip_env "couldn't find empty loop device"
5974         trap cleanup_54c EXIT
5975         mknod $loopdev b 7 $LOOPNUM
5976         echo "make a loop file system with $DIR/$tfile on $loopdev ($LOOPNUM)."
5977         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE seek=1024 count=1 > /dev/null
5978         losetup $loopdev $DIR/$tfile ||
5979                 error "can't set up $loopdev for $DIR/$tfile"
5980         mkfs.ext2 $loopdev || error "mke2fs on $loopdev"
5981         test_mkdir $DIR/$tdir
5982         mount -t ext2 $loopdev $DIR/$tdir ||
5983                 error "error mounting $loopdev on $DIR/$tdir"
5984         dd if=/dev/zero of=$DIR/$tdir/tmp bs=$PAGE_SIZE count=30 ||
5985                 error "dd write"
5986         df $DIR/$tdir
5987         dd if=$DIR/$tdir/tmp of=/dev/zero bs=$PAGE_SIZE count=30 ||
5988                 error "dd read"
5989         cleanup_54c
5990 }
5991 run_test 54c "block device works in lustre ====================="
5992
5993 test_54d() {
5994         f="$DIR/f54d"
5995         string="aaaaaa"
5996         mknod $f p
5997         [ "$string" = $(echo $string > $f | cat $f) ] || error "$f != $string"
5998 }
5999 run_test 54d "fifo device works in lustre ======================"
6000
6001 test_54e() {
6002         f="$DIR/f54e"
6003         string="aaaaaa"
6004         cp -aL /dev/console $f
6005         echo $string > $f || error "echo $string to $f failed"
6006 }
6007 run_test 54e "console/tty device works in lustre ======================"
6008
6009 test_56a() {
6010         local numfiles=3
6011         local numdirs=2
6012         local dir=$DIR/$tdir
6013
6014         rm -rf $dir
6015         test_mkdir -p $dir/dir
6016         for i in $(seq $numfiles); do
6017                 touch $dir/file$i
6018                 touch $dir/dir/file$i
6019         done
6020
6021         local numcomp=$($LFS getstripe --component-count $dir)
6022
6023         [[ $numcomp == 0 ]] && numcomp=1
6024
6025         # test lfs getstripe with --recursive
6026         local filenum=$($LFS getstripe -r $dir | egrep -c "obdidx|l_ost_idx")
6027
6028         [[ $filenum -eq $((numfiles * 2)) ]] ||
6029                 error "$LFS getstripe -r: found $filenum != $((numfiles * 2))"
6030         filenum=$($LFS getstripe $dir | egrep -c "obdidx|l_ost_idx")
6031         [[ $filenum -eq $numfiles ]] ||
6032                 error "$LFS getstripe $dir: found $filenum, not $numfiles"
6033         echo "$LFS getstripe showed obdidx or l_ost_idx"
6034
6035         # test lfs getstripe with file instead of dir
6036         filenum=$($LFS getstripe $dir/file1 | egrep -c "obdidx|l_ost_idx")
6037         [[ $filenum -eq 1 ]] ||
6038                 error "$LFS getstripe $dir/file1: found $filenum, not 1"
6039         echo "$LFS getstripe file1 passed"
6040
6041         #test lfs getstripe with --verbose
6042         filenum=$($LFS getstripe --verbose $dir | grep -c lmm_magic)
6043         [[ $filenum -eq $((numfiles * numcomp)) ]] ||
6044                 error "$LFS getstripe --verbose $dir: "\
6045                       "got $filenum want $((numfiles * numcomp)) lmm_magic"
6046         [[ $($LFS getstripe $dir | grep -c lmm_magic) -eq 0 ]] ||
6047                 error "$LFS getstripe $dir: showed lmm_magic"
6048
6049         #test lfs getstripe with -v prints lmm_fid
6050         filenum=$($LFS getstripe -v $dir | grep -c lmm_fid)
6051         local countfids=$((numdirs + numfiles * numcomp))
6052         [[ $filenum -eq $countfids ]] ||
6053                 error "$LFS getstripe -v $dir: "\
6054                       "got $filenum want $countfids lmm_fid"
6055         [[ $($LFS getstripe $dir | grep -c lmm_fid) -eq 0 ]] ||
6056                 error "$LFS getstripe $dir: showed lmm_fid by default"
6057         echo "$LFS getstripe --verbose passed"
6058
6059         #check for FID information
6060         local fid1=$($LFS getstripe --fid $dir/file1)
6061         local fid2=$($LFS getstripe --verbose $dir/file1 |
6062                      awk '/lmm_fid: / { print $2; exit; }')
6063         local fid3=$($LFS path2fid $dir/file1)
6064
6065         [ "$fid1" != "$fid2" ] &&
6066                 error "getstripe --fid '$fid1' != getstripe --verbose '$fid2'"
6067         [ "$fid1" != "$fid3" ] &&
6068                 error "getstripe --fid '$fid1' != lfs path2fid '$fid3'"
6069         echo "$LFS getstripe --fid passed"
6070
6071         #test lfs getstripe with --obd
6072         $LFS getstripe --obd wrong_uuid $dir 2>&1 | grep -q "unknown obduuid" ||
6073                 error "$LFS getstripe --obd wrong_uuid: should return error"
6074
6075         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
6076
6077         local ostidx=1
6078         local obduuid=$(ostuuid_from_index $ostidx)
6079         local found=$($LFS getstripe -r --obd $obduuid $dir |
6080                 grep 'lmm_stripe_offset:' | grep -c " $ostidx\$")
6081
6082         filenum=$($LFS getstripe -ir $dir | grep -c "^$ostidx\$")
6083         [[ $($LFS getstripe -id $dir) -ne $ostidx ]] ||
6084                 ((filenum--))
6085         [[ $($LFS getstripe -id $dir/dir) -ne $ostidx ]] ||
6086                 ((filenum--))
6087
6088         [[ $found -eq $filenum ]] ||
6089                 error "$LFS getstripe --obd: found $found expect $filenum"
6090         [[ $($LFS getstripe -r -v --obd $obduuid $dir |
6091                 sed '/^[         ]*'${ostidx}'[  ]/d' |
6092                 sed -n '/^[      ]*[0-9][0-9]*[  ]/p' | wc -l) -eq 0 ]] ||
6093                 error "$LFS getstripe --obd: should not show file on other obd"
6094         echo "$LFS getstripe --obd passed"
6095 }
6096 run_test 56a "check $LFS getstripe"
6097
6098 test_56b() {
6099         local dir=$DIR/$tdir
6100         local numdirs=3
6101
6102         test_mkdir $dir
6103         for i in $(seq $numdirs); do
6104                 test_mkdir $dir/dir$i
6105         done
6106
6107         # test lfs getdirstripe default mode is non-recursion, which is
6108         # different from lfs getstripe
6109         local dircnt=$($LFS getdirstripe $dir | grep -c lmv_stripe_count)
6110
6111         [[ $dircnt -eq 1 ]] ||
6112                 error "$LFS getdirstripe: found $dircnt, not 1"
6113         dircnt=$($LFS getdirstripe --recursive $dir |
6114                 grep -c lmv_stripe_count)
6115         [[ $dircnt -eq $((numdirs + 1)) ]] ||
6116                 error "$LFS getdirstripe -r: $dircnt, != $((numdirs + 1))"
6117 }
6118 run_test 56b "check $LFS getdirstripe"
6119
6120 test_56c() {
6121         remote_ost_nodsh && skip "remote OST with nodsh"
6122
6123         local ost_idx=0
6124         local ost_name=$(ostname_from_index $ost_idx)
6125         local old_status=$(ost_dev_status $ost_idx)
6126         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
6127
6128         [[ -z "$old_status" ]] ||
6129                 skip_env "OST $ost_name is in $old_status status"
6130
6131         do_facet ost1 $LCTL set_param -n obdfilter.$ost_name.degraded=1
6132         [[ $OST1_VERSION -lt $(version_code 2.12.55) ]] || do_facet ost1 \
6133                 $LCTL set_param -n obdfilter.$ost_name.no_precreate=1
6134         if [[ $OST1_VERSION -ge $(version_code 2.12.57) ]]; then
6135                 save_lustre_params ost1 osd-*.$ost_name.nonrotational > $p
6136                 do_facet ost1 $LCTL set_param -n osd-*.$ost_name.nonrotational=1
6137         fi
6138
6139         [[ $($LFS df -v $MOUNT |& grep -c "inactive device") -eq 0 ]] ||
6140                 error "$LFS df -v showing inactive devices"
6141         sleep_maxage
6142
6143         local new_status=$(ost_dev_status $ost_idx $MOUNT -v)
6144
6145         [[ "$new_status" =~ "D" ]] ||
6146                 error "$ost_name status is '$new_status', missing 'D'"
6147         if [[ $OST1_VERSION -ge $(version_code 2.12.55) ]]; then
6148                 [[ "$new_status" =~ "N" ]] ||
6149                         error "$ost_name status is '$new_status', missing 'N'"
6150         fi
6151         if [[ $OST1_VERSION -ge $(version_code 2.12.57) ]]; then
6152                 [[ "$new_status" =~ "f" ]] ||
6153                         error "$ost_name status is '$new_status', missing 'f'"
6154         fi
6155
6156         do_facet ost1 $LCTL set_param -n obdfilter.$ost_name.degraded=0
6157         [[ $OST1_VERSION -lt $(version_code 2.12.55) ]] || do_facet ost1 \
6158                 $LCTL set_param -n obdfilter.$ost_name.no_precreate=0
6159         [[ -z "$p" ]] && restore_lustre_params < $p || true
6160         sleep_maxage
6161
6162         new_status=$(ost_dev_status $ost_idx)
6163         [[ ! "$new_status" =~ "D" && ! "$new_status" =~ "N" ]] ||
6164                 error "$ost_name status is '$new_status', has 'D' and/or 'N'"
6165         # can't check 'f' as devices may actually be on flash
6166 }
6167 run_test 56c "check 'lfs df' showing device status"
6168
6169 test_56d() {
6170         local mdts=$($LFS df -v $MOUNT | grep -c MDT)
6171         local osts=$($LFS df -v $MOUNT | grep -c OST)
6172
6173         $LFS df $MOUNT
6174
6175         (( mdts == MDSCOUNT )) ||
6176                 error "lfs df -v showed $mdts MDTs, not $MDSCOUNT"
6177         (( osts == OSTCOUNT )) ||
6178                 error "lfs df -v showed $osts OSTs, not $OSTCOUNT"
6179 }
6180 run_test 56d "'lfs df -v' prints only configured devices"
6181
6182 test_56e() {
6183         err_enoent=2 # No such file or directory
6184         err_eopnotsupp=95 # Operation not supported
6185
6186         enoent_mnt=/pmt1 # Invalid dentry. Path not present
6187         notsup_mnt=/tmp  # Valid dentry, but Not a lustreFS
6188
6189         # Check for handling of path not exists
6190         output=$($LFS df $enoent_mnt 2>&1)
6191         ret=$?
6192
6193         fs=$(echo $output | awk -F: '{print $2}' | awk '{print $3}' | tr -d \')
6194         [[ $fs = $enoent_mnt && $ret -eq $err_enoent ]] ||
6195                 error "expect failure $err_enoent, not $ret"
6196
6197         # Check for handling of non-Lustre FS
6198         output=$($LFS df $notsup_mnt)
6199         ret=$?
6200
6201         fs=$(echo $output | awk '{print $1}' | awk -F: '{print $2}')
6202         [[ $fs = $notsup_mnt && $ret -eq $err_eopnotsupp ]] ||
6203                 error "expect success $err_eopnotsupp, not $ret"
6204
6205         # Check for multiple LustreFS argument
6206         output=$($LFS df $MOUNT $MOUNT $MOUNT | grep -c "filesystem_summary:")
6207         ret=$?
6208
6209         [[ $output -eq 3 && $ret -eq 0 ]] ||
6210                 error "expect success 3, not $output, rc = $ret"
6211
6212         # Check for correct non-Lustre FS handling among multiple
6213         # LustreFS argument
6214         output=$($LFS df $MOUNT $notsup_mnt $MOUNT |
6215                 grep -c "filesystem_summary:"; exit ${PIPESTATUS[0]})
6216         ret=$?
6217
6218         [[ $output -eq 2 && $ret -eq $err_eopnotsupp ]] ||
6219                 error "expect success 2, not $output, rc = $ret"
6220 }
6221 run_test 56e "'lfs df' Handle non LustreFS & multiple LustreFS"
6222
6223 NUMFILES=3
6224 NUMDIRS=3
6225 setup_56() {
6226         local local_tdir="$1"
6227         local local_numfiles="$2"
6228         local local_numdirs="$3"
6229         local dir_params="$4"
6230         local dir_stripe_params="$5"
6231
6232         if [ ! -d "$local_tdir" ] ; then
6233                 test_mkdir -p $dir_stripe_params $local_tdir
6234                 [ "$dir_params" ] && $LFS setstripe $dir_params $local_tdir
6235                 for i in $(seq $local_numfiles) ; do
6236                         touch $local_tdir/file$i
6237                 done
6238                 for i in $(seq $local_numdirs) ; do
6239                         test_mkdir $dir_stripe_params $local_tdir/dir$i
6240                         for j in $(seq $local_numfiles) ; do
6241                                 touch $local_tdir/dir$i/file$j
6242                         done
6243                 done
6244         fi
6245 }
6246
6247 setup_56_special() {
6248         local local_tdir=$1
6249         local local_numfiles=$2
6250         local local_numdirs=$3
6251
6252         setup_56 $local_tdir $local_numfiles $local_numdirs
6253
6254         if [ ! -e "$local_tdir/loop${local_numfiles}b" ] ; then
6255                 for i in $(seq $local_numfiles) ; do
6256                         mknod $local_tdir/loop${i}b b 7 $i
6257                         mknod $local_tdir/null${i}c c 1 3
6258                         ln -s $local_tdir/file1 $local_tdir/link${i}
6259                 done
6260                 for i in $(seq $local_numdirs) ; do
6261                         mknod $local_tdir/dir$i/loop${i}b b 7 $i
6262                         mknod $local_tdir/dir$i/null${i}c c 1 3
6263                         ln -s $local_tdir/dir$i/file1 $local_tdir/dir$i/link${i}
6264                 done
6265         fi
6266 }
6267
6268 test_56g() {
6269         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6270         local expected=$(($NUMDIRS + 2))
6271
6272         setup_56 $dir $NUMFILES $NUMDIRS
6273
6274         # test lfs find with -name
6275         for i in $(seq $NUMFILES) ; do
6276                 local nums=$($LFS find -name "*$i" $dir | wc -l)
6277
6278                 [ $nums -eq $expected ] ||
6279                         error "lfs find -name '*$i' $dir wrong: "\
6280                               "found $nums, expected $expected"
6281         done
6282 }
6283 run_test 56g "check lfs find -name"
6284
6285 test_56h() {
6286         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6287         local expected=$(((NUMDIRS + 1) * (NUMFILES - 1) + NUMFILES))
6288
6289         setup_56 $dir $NUMFILES $NUMDIRS
6290
6291         # test lfs find with ! -name
6292         for i in $(seq $NUMFILES) ; do
6293                 local nums=$($LFS find ! -name "*$i" $dir | wc -l)
6294
6295                 [ $nums -eq $expected ] ||
6296                         error "lfs find ! -name '*$i' $dir wrong: "\
6297                               "found $nums, expected $expected"
6298         done
6299 }
6300 run_test 56h "check lfs find ! -name"
6301
6302 test_56i() {
6303         local dir=$DIR/$tdir
6304
6305         test_mkdir $dir
6306
6307         local cmd="$LFS find -ost $(ostuuid_from_index 0 $dir) $dir"
6308         local out=$($cmd)
6309
6310         [ -z "$out" ] || error "'$cmd' returned directory '$out'"
6311 }
6312 run_test 56i "check 'lfs find -ost UUID' skips directories"
6313
6314 test_56j() {
6315         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6316
6317         setup_56_special $dir $NUMFILES $NUMDIRS
6318
6319         local expected=$((NUMDIRS + 1))
6320         local cmd="$LFS find -type d $dir"
6321         local nums=$($cmd | wc -l)
6322
6323         [ $nums -eq $expected ] ||
6324                 error "'$cmd' wrong: found $nums, expected $expected"
6325 }
6326 run_test 56j "check lfs find -type d"
6327
6328 test_56k() {
6329         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6330
6331         setup_56_special $dir $NUMFILES $NUMDIRS
6332
6333         local expected=$(((NUMDIRS + 1) * NUMFILES))
6334         local cmd="$LFS find -type f $dir"
6335         local nums=$($cmd | wc -l)
6336
6337         [ $nums -eq $expected ] ||
6338                 error "'$cmd' wrong: found $nums, expected $expected"
6339 }
6340 run_test 56k "check lfs find -type f"
6341
6342 test_56l() {
6343         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6344
6345         setup_56_special $dir $NUMFILES $NUMDIRS
6346
6347         local expected=$((NUMDIRS + NUMFILES))
6348         local cmd="$LFS find -type b $dir"
6349         local nums=$($cmd | wc -l)
6350
6351         [ $nums -eq $expected ] ||
6352                 error "'$cmd' wrong: found $nums, expected $expected"
6353 }
6354 run_test 56l "check lfs find -type b"
6355
6356 test_56m() {
6357         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6358
6359         setup_56_special $dir $NUMFILES $NUMDIRS
6360
6361         local expected=$((NUMDIRS + NUMFILES))
6362         local cmd="$LFS find -type c $dir"
6363         local nums=$($cmd | wc -l)
6364         [ $nums -eq $expected ] ||
6365                 error "'$cmd' wrong: found $nums, expected $expected"
6366 }
6367 run_test 56m "check lfs find -type c"
6368
6369 test_56n() {
6370         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6371         setup_56_special $dir $NUMFILES $NUMDIRS
6372
6373         local expected=$((NUMDIRS + NUMFILES))
6374         local cmd="$LFS find -type l $dir"
6375         local nums=$($cmd | wc -l)
6376
6377         [ $nums -eq $expected ] ||
6378                 error "'$cmd' wrong: found $nums, expected $expected"
6379 }
6380 run_test 56n "check lfs find -type l"
6381
6382 test_56o() {
6383         local dir=$DIR/$tdir
6384
6385         setup_56 $dir $NUMFILES $NUMDIRS
6386         utime $dir/file1 > /dev/null || error "utime (1)"
6387         utime $dir/file2 > /dev/null || error "utime (2)"
6388         utime $dir/dir1 > /dev/null || error "utime (3)"
6389         utime $dir/dir2 > /dev/null || error "utime (4)"
6390         utime $dir/dir1/file1 > /dev/null || error "utime (5)"
6391         dd if=/dev/zero count=1 >> $dir/dir1/file1 && sync
6392
6393         local expected=4
6394         local nums=$($LFS find -mtime +0 $dir | wc -l)
6395
6396         [ $nums -eq $expected ] ||
6397                 error "lfs find -mtime +0 $dir: found $nums expect $expected"
6398
6399         expected=12
6400         cmd="$LFS find -mtime 0 $dir"
6401         nums=$($cmd | wc -l)
6402         [ $nums -eq $expected ] ||
6403                 error "'$cmd' wrong: found $nums, expected $expected"
6404 }
6405 run_test 56o "check lfs find -mtime for old files"
6406
6407 test_56ob() {
6408         local dir=$DIR/$tdir
6409         local expected=1
6410         local count=0
6411
6412         # just to make sure there is something that won't be found
6413         test_mkdir $dir
6414         touch $dir/$tfile.now
6415
6416         for age in year week day hour min; do
6417                 count=$((count + 1))
6418
6419                 touch $dir/$tfile-a.$age $dir/$tfile-m.$age
6420                 touch --date="$count $age ago" -a $dir/$tfile-a.$age
6421                 touch --date="$count $age ago" -m $dir/$tfile-m.$age
6422
6423                 local cmd="$LFS find $dir -mtime $count${age:0:1}"
6424                 local nums=$($cmd | wc -l)
6425                 [ $nums -eq $expected ] ||
6426                         error "'$cmd' wrong: found $nums, expected $expected"
6427
6428                 cmd="$LFS find $dir -atime $count${age:0:1}"
6429                 nums=$($cmd | wc -l)
6430                 [ $nums -eq $expected ] ||
6431                         error "'$cmd' wrong: found $nums, expected $expected"
6432         done
6433
6434         sleep 2
6435         cmd="$LFS find $dir -ctime +1s -type f"
6436         nums=$($cmd | wc -l)
6437         (( $nums == $count * 2 + 1)) ||
6438                 error "'$cmd' wrong: found $nums, expected $((count * 2 + 1))"
6439 }
6440 run_test 56ob "check lfs find -atime -mtime -ctime with units"
6441
6442 test_newerXY_base() {
6443         local x=$1
6444         local y=$2
6445         local dir=$DIR/$tdir
6446         local ref
6447         local negref
6448
6449         if [ $y == "t" ]; then
6450                 if [ $x == "b" ]; then
6451                         ref=\"$(do_facet mds1 date +"%Y-%m-%d\ %H:%M:%S")\"
6452                 else
6453                         ref=\"$(date +"%Y-%m-%d %H:%M:%S")\"
6454                 fi
6455         else
6456                 ref=$DIR/$tfile.newer.$x$y
6457                 touch $ref || error "touch $ref failed"
6458         fi
6459
6460         echo "before = $ref"
6461         sleep 2
6462         setup_56 $dir $NUMFILES $NUMDIRS "-i0 -c1" "-i0 -c1"
6463         sleep 2
6464         if [ $y == "t" ]; then
6465                 if [ $x == "b" ]; then
6466                         negref=\"$(do_facet mds1 date +"%Y-%m-%d\ %H:%M:%S")\"
6467                 else
6468                         negref=\"$(date +"%Y-%m-%d %H:%M:%S")\"
6469                 fi
6470         else
6471                 negref=$DIR/$tfile.negnewer.$x$y
6472                 touch $negref || error "touch $negref failed"
6473         fi
6474
6475         echo "after = $negref"
6476         local cmd="$LFS find $dir -newer$x$y $ref"
6477         local nums=$(eval $cmd | wc -l)
6478         local expected=$(((NUMFILES + 2) * NUMDIRS + 1))
6479
6480         [ $nums -eq $expected ] || { ls -lauR --full-time $dir ;
6481                 error "'$cmd' wrong: found $nums newer, expected $expected"  ; }
6482
6483         cmd="$LFS find $dir ! -newer$x$y $negref"
6484         nums=$(eval $cmd | wc -l)
6485         [ $nums -eq $expected ] || { ls -lauR --full-time $dir ;
6486                 error "'$cmd' wrong: found $nums older, expected $expected"  ; }
6487
6488         cmd="$LFS find $dir -newer$x$y $ref ! -newer$x$y $negref"
6489         nums=$(eval $cmd | wc -l)
6490         [ $nums -eq $expected ] || { ls -lauR --full-time $dir ;
6491                 error "'$cmd' wrong: found $nums between, expected $expected"; }
6492
6493         rm -rf $DIR/*
6494 }
6495
6496 test_56oc() {
6497         test_newerXY_base "a" "a"
6498         test_newerXY_base "a" "m"
6499         test_newerXY_base "a" "c"
6500         test_newerXY_base "m" "a"
6501         test_newerXY_base "m" "m"
6502         test_newerXY_base "m" "c"
6503         test_newerXY_base "c" "a"
6504         test_newerXY_base "c" "m"
6505         test_newerXY_base "c" "c"
6506
6507         [[ -n "$sles_version" ]] &&
6508                 echo "skip timestamp tests on SLES, LU-13665" && return 0
6509
6510         test_newerXY_base "a" "t"
6511         test_newerXY_base "m" "t"
6512         test_newerXY_base "c" "t"
6513
6514         [[ $MDS1_VERSION -lt $(version_code 2.13.54) ||
6515            $CLIENT_VERSION -lt $(version_code 2.13.54) ]] &&
6516                 ! btime_supported && echo "btime unsupported" && return 0
6517
6518         test_newerXY_base "b" "b"
6519         test_newerXY_base "b" "t"
6520 }
6521 run_test 56oc "check lfs find -newerXY work"
6522
6523 btime_supported() {
6524         local dir=$DIR/$tdir
6525         local rc
6526
6527         mkdir -p $dir
6528         touch $dir/$tfile
6529         $LFS find $dir -btime -1d -type f
6530         rc=$?
6531         rm -rf $dir
6532         return $rc
6533 }
6534
6535 test_56od() {
6536         [ $MDS1_VERSION -lt $(version_code 2.13.53) ] &&
6537                 ! btime_supported && skip "btime unsupported on MDS"
6538
6539         [ $CLIENT_VERSION -lt $(version_code 2.13.53) ] &&
6540                 ! btime_supported && skip "btime unsupported on clients"
6541
6542         local dir=$DIR/$tdir
6543         local ref=$DIR/$tfile.ref
6544         local negref=$DIR/$tfile.negref
6545
6546         mkdir $dir || error "mkdir $dir failed"
6547         touch $dir/$tfile.n1 || error "touch $dir/$tfile.n1 failed"
6548         touch $dir/$tfile.n2 || error "touch $dir/$tfile.n2 failed"
6549         mkdir $dir/$tdir.n1 || error "mkdir $dir/$tdir.n1 failed"
6550         mkdir $dir/$tdir.n2 || error "mkdir $dir/$tdir.n2 failed"
6551         touch $ref || error "touch $ref failed"
6552         # sleep 3 seconds at least
6553         sleep 3
6554
6555         local before=$(do_facet mds1 date +%s)
6556         local skew=$(($(date +%s) - before + 1))
6557
6558         if (( skew < 0 && skew > -5 )); then
6559                 sleep $((0 - skew + 1))
6560                 skew=0
6561         fi
6562
6563         # Set the dir stripe params to limit files all on MDT0,
6564         # otherwise we need to calc the max clock skew between
6565         # the client and MDTs.
6566         setup_56 $dir/d.btime $NUMFILES $NUMDIRS "-i0 -c1" "-i0 -c1"
6567         sleep 2
6568         touch $negref || error "touch $negref failed"
6569
6570         local cmd="$LFS find $dir -newerbb $ref ! -newerbb $negref -type f"
6571         local nums=$($cmd | wc -l)
6572         local expected=$(((NUMFILES + 1) * NUMDIRS))
6573
6574         [ $nums -eq $expected ] ||
6575                 error "'$cmd' wrong: found $nums, expected $expected"
6576
6577         cmd="$LFS find $dir -newerbb $ref ! -newerbb $negref -type d"
6578         nums=$($cmd | wc -l)
6579         expected=$((NUMFILES + 1))
6580         [ $nums -eq $expected ] ||
6581                 error "'$cmd' wrong: found $nums, expected $expected"
6582
6583         [ $skew -lt 0 ] && return
6584
6585         local after=$(do_facet mds1 date +%s)
6586         local age=$((after - before + 1 + skew))
6587
6588         cmd="$LFS find $dir -btime -${age}s -type f"
6589         nums=$($cmd | wc -l)
6590         expected=$(((NUMFILES + 1) * NUMDIRS))
6591
6592         echo "Clock skew between client and server: $skew, age:$age"
6593         [ $nums -eq $expected ] ||
6594                 error "'$cmd' wrong: found $nums, expected $expected"
6595
6596         expected=$(($NUMDIRS + 1))
6597         cmd="$LFS find $dir -btime -${age}s -type d"
6598         nums=$($cmd | wc -l)
6599         [ $nums -eq $expected ] ||
6600                 error "'$cmd' wrong: found $nums, expected $expected"
6601         rm -f $ref $negref || error "Failed to remove $ref $negref"
6602 }
6603 run_test 56od "check lfs find -btime with units"
6604
6605 test_56p() {
6606         [ $RUNAS_ID -eq $UID ] &&
6607                 skip_env "RUNAS_ID = UID = $UID -- skipping"
6608
6609         local dir=$DIR/$tdir
6610
6611         setup_56 $dir $NUMFILES $NUMDIRS
6612         chown $RUNAS_ID $dir/file* || error "chown $DIR/${tdir}g/file$i failed"
6613
6614         local expected=$NUMFILES
6615         local cmd="$LFS find -uid $RUNAS_ID $dir"
6616         local nums=$($cmd | wc -l)
6617
6618         [ $nums -eq $expected ] ||
6619                 error "'$cmd' wrong: found $nums, expected $expected"
6620
6621         expected=$(((NUMFILES + 1) * NUMDIRS + 1))
6622         cmd="$LFS find ! -uid $RUNAS_ID $dir"
6623         nums=$($cmd | wc -l)
6624         [ $nums -eq $expected ] ||
6625                 error "'$cmd' wrong: found $nums, expected $expected"
6626 }
6627 run_test 56p "check lfs find -uid and ! -uid"
6628
6629 test_56q() {
6630         [ $RUNAS_ID -eq $UID ] &&
6631                 skip_env "RUNAS_ID = UID = $UID -- skipping"
6632
6633         local dir=$DIR/$tdir
6634
6635         setup_56 $dir $NUMFILES $NUMDIRS
6636         chgrp $RUNAS_GID $dir/file* || error "chown $dir/file$i failed"
6637
6638         local expected=$NUMFILES
6639         local cmd="$LFS find -gid $RUNAS_GID $dir"
6640         local nums=$($cmd | wc -l)
6641
6642         [ $nums -eq $expected ] ||
6643                 error "'$cmd' wrong: found $nums, expected $expected"
6644
6645         expected=$(( ($NUMFILES+1) * $NUMDIRS + 1))
6646         cmd="$LFS find ! -gid $RUNAS_GID $dir"
6647         nums=$($cmd | wc -l)
6648         [ $nums -eq $expected ] ||
6649                 error "'$cmd' wrong: found $nums, expected $expected"
6650 }
6651 run_test 56q "check lfs find -gid and ! -gid"
6652
6653 test_56r() {
6654         local dir=$DIR/$tdir
6655
6656         setup_56 $dir $NUMFILES $NUMDIRS
6657
6658         local expected=12
6659         local cmd="$LFS find -size 0 -type f -lazy $dir"
6660         local nums=$($cmd | wc -l)
6661
6662         [ $nums -eq $expected ] ||
6663                 error "'$cmd' wrong: found $nums, expected $expected"
6664         cmd="$LFS find -size 0 -type f $dir"
6665         nums=$($cmd | wc -l)
6666         [ $nums -eq $expected ] ||
6667                 error "'$cmd' wrong: found $nums, expected $expected"
6668
6669         expected=0
6670         cmd="$LFS find ! -size 0 -type f -lazy $dir"
6671         nums=$($cmd | wc -l)
6672         [ $nums -eq $expected ] ||
6673                 error "'$cmd' wrong: found $nums, expected $expected"
6674         cmd="$LFS find ! -size 0 -type f $dir"
6675         nums=$($cmd | wc -l)
6676         [ $nums -eq $expected ] ||
6677                 error "'$cmd' wrong: found $nums, expected $expected"
6678
6679         echo "test" > $dir/$tfile
6680         echo "test2" > $dir/$tfile.2 && sync
6681         expected=1
6682         cmd="$LFS find -size 5 -type f -lazy $dir"
6683         nums=$($cmd | wc -l)
6684         [ $nums -eq $expected ] ||
6685                 error "'$cmd' wrong: found $nums, expected $expected"
6686         cmd="$LFS find -size 5 -type f $dir"
6687         nums=$($cmd | wc -l)
6688         [ $nums -eq $expected ] ||
6689                 error "'$cmd' wrong: found $nums, expected $expected"
6690
6691         expected=1
6692         cmd="$LFS find -size +5 -type f -lazy $dir"
6693         nums=$($cmd | wc -l)
6694         [ $nums -eq $expected ] ||
6695                 error "'$cmd' wrong: found $nums, expected $expected"
6696         cmd="$LFS find -size +5 -type f $dir"
6697         nums=$($cmd | wc -l)
6698         [ $nums -eq $expected ] ||
6699                 error "'$cmd' wrong: found $nums, expected $expected"
6700
6701         expected=2
6702         cmd="$LFS find -size +0 -type f -lazy $dir"
6703         nums=$($cmd | wc -l)
6704         [ $nums -eq $expected ] ||
6705                 error "'$cmd' wrong: found $nums, expected $expected"
6706         cmd="$LFS find -size +0 -type f $dir"
6707         nums=$($cmd | wc -l)
6708         [ $nums -eq $expected ] ||
6709                 error "'$cmd' wrong: found $nums, expected $expected"
6710
6711         expected=2
6712         cmd="$LFS find ! -size -5 -type f -lazy $dir"
6713         nums=$($cmd | wc -l)
6714         [ $nums -eq $expected ] ||
6715                 error "'$cmd' wrong: found $nums, expected $expected"
6716         cmd="$LFS find ! -size -5 -type f $dir"
6717         nums=$($cmd | wc -l)
6718         [ $nums -eq $expected ] ||
6719                 error "'$cmd' wrong: found $nums, expected $expected"
6720
6721         expected=12
6722         cmd="$LFS find -size -5 -type f -lazy $dir"
6723         nums=$($cmd | wc -l)
6724         [ $nums -eq $expected ] ||
6725                 error "'$cmd' wrong: found $nums, expected $expected"
6726         cmd="$LFS find -size -5 -type f $dir"
6727         nums=$($cmd | wc -l)
6728         [ $nums -eq $expected ] ||
6729                 error "'$cmd' wrong: found $nums, expected $expected"
6730 }
6731 run_test 56r "check lfs find -size works"
6732
6733 test_56ra_sub() {
6734         local expected=$1
6735         local glimpses=$2
6736         local cmd="$3"
6737
6738         cancel_lru_locks $OSC
6739
6740         local rpcs_before=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
6741         local nums=$($cmd | wc -l)
6742
6743         [ $nums -eq $expected ] ||
6744                 error "'$cmd' wrong: found $nums, expected $expected"
6745
6746         local rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
6747
6748         if (( rpcs_before + glimpses != rpcs_after )); then
6749                 echo "Before: $rpcs_before After: $rpcs_after $NUMFILES"
6750                 $LCTL get_param osc.*.stats | grep ldlm_glimpse_enqueue
6751
6752                 if [[ $glimpses == 0 ]]; then
6753                         error "'$cmd' should not send glimpse RPCs to OST"
6754                 else
6755                         error "'$cmd' should send $glimpses glimpse RPCs to OST"
6756                 fi
6757         fi
6758 }
6759
6760 test_56ra() {
6761         [[ $MDS1_VERSION -gt $(version_code 2.12.58) ]] ||
6762                 skip "MDS < 2.12.58 doesn't return LSOM data"
6763         local dir=$DIR/$tdir
6764         local old_agl=$($LCTL get_param -n llite.*.statahead_agl)
6765
6766         [[ $OSC == "mdc" ]] && skip "statahead not needed for DoM files"
6767
6768         # statahead_agl may cause extra glimpse which confuses results. LU-13017
6769         $LCTL set_param -n llite.*.statahead_agl=0
6770         stack_trap "$LCTL set_param -n llite.*.statahead_agl=$old_agl"
6771
6772         setup_56 $dir $NUMFILES $NUMDIRS "-c 1"
6773         # open and close all files to ensure LSOM is updated
6774         cancel_lru_locks $OSC
6775         find $dir -type f | xargs cat > /dev/null
6776
6777         #   expect_found  glimpse_rpcs  command_to_run
6778         test_56ra_sub 12  0 "$LFS find -size 0 -type f -lazy $dir"
6779         test_56ra_sub 12 12 "$LFS find -size 0 -type f $dir"
6780         test_56ra_sub  0  0 "$LFS find ! -size 0 -type f -lazy $dir"
6781         test_56ra_sub  0 12 "$LFS find ! -size 0 -type f $dir"
6782
6783         echo "test" > $dir/$tfile
6784         echo "test2" > $dir/$tfile.2 && sync
6785         cancel_lru_locks $OSC
6786         cat $dir/$tfile $dir/$tfile.2 > /dev/null
6787
6788         test_56ra_sub  1  0 "$LFS find -size 5 -type f -lazy $dir"
6789         test_56ra_sub  1 14 "$LFS find -size 5 -type f $dir"
6790         test_56ra_sub  1  0 "$LFS find -size +5 -type f -lazy $dir"
6791         test_56ra_sub  1 14 "$LFS find -size +5 -type f $dir"
6792
6793         test_56ra_sub  2  0 "$LFS find -size +0 -type f -lazy $dir"
6794         test_56ra_sub  2 14 "$LFS find -size +0 -type f $dir"
6795         test_56ra_sub  2  0 "$LFS find ! -size -5 -type f -lazy $dir"
6796         test_56ra_sub  2 14 "$LFS find ! -size -5 -type f $dir"
6797         test_56ra_sub 12  0 "$LFS find -size -5 -type f -lazy $dir"
6798         test_56ra_sub 12 14 "$LFS find -size -5 -type f $dir"
6799 }
6800 run_test 56ra "check lfs find -size -lazy works for data on OSTs"
6801
6802 test_56rb() {
6803         local dir=$DIR/$tdir
6804         local tmp=$TMP/$tfile.log
6805         local mdt_idx;
6806
6807         test_mkdir -p $dir || error "failed to mkdir $dir"
6808         $LFS setstripe -c 1 -i 0 $dir/$tfile ||
6809                 error "failed to setstripe $dir/$tfile"
6810         mdt_idx=$($LFS getdirstripe -i $dir)
6811         dd if=/dev/zero of=$dir/$tfile bs=1M count=1
6812
6813         stack_trap "rm -f $tmp" EXIT
6814         $LFS find --size +100K --ost 0 $dir |& tee $tmp
6815         ! grep -q obd_uuid $tmp ||
6816                 error "failed to find --size +100K --ost 0 $dir"
6817         $LFS find --size +100K --mdt $mdt_idx $dir |& tee $tmp
6818         ! grep -q obd_uuid $tmp ||
6819                 error "failed to find --size +100K --mdt $mdt_idx $dir"
6820 }
6821 run_test 56rb "check lfs find --size --ost/--mdt works"
6822
6823 test_56rc() {
6824         (( MDSCOUNT >= 2 )) || skip "needs at least 2 MDTs"
6825         local dir=$DIR/$tdir
6826         local found
6827
6828         test_mkdir -c 2 -H all_char $dir || error "failed to mkdir $dir"
6829         $LFS mkdir -c 2 --mdt-hash all_char $dir/$tdir-all{1..10}
6830         (( $MDSCOUNT > 2 )) &&
6831                 $LFS mkdir -c 3 --mdt-hash fnv_1a_64 $dir/$tdir-fnv{1..10}
6832         mkdir $dir/$tdir-{1..10}
6833         touch $dir/$tfile-{1..10}
6834
6835         found=$($LFS find $dir --mdt-count 2 | wc -l)
6836         expect=11
6837         (( $found == $expect )) || error "found $found 2-stripe, expect $expect"
6838
6839         found=$($LFS find $dir -T +1 | wc -l)
6840         (( $MDSCOUNT > 2 )) && expect=$((expect + 10))
6841         (( $found == $expect )) || error "found $found 2+stripe, expect $expect"
6842
6843         found=$($LFS find $dir --mdt-hash all_char | wc -l)
6844         expect=11
6845         (( $found == $expect )) || error "found $found all_char, expect $expect"
6846
6847         found=$($LFS find $dir --mdt-hash fnv_1a_64 | wc -l)
6848         (( $MDSCOUNT > 2 )) && expect=10 || expect=0
6849         (( $found == $expect )) || error "found $found all_char, expect $expect"
6850 }
6851 run_test 56rc "check lfs find --mdt-count/--mdt-hash works"
6852
6853 test_56s() { # LU-611 #LU-9369
6854         [[ $OSTCOUNT -lt 2 ]] && skip_env "need at least 2 OSTs"
6855
6856         local dir=$DIR/$tdir
6857         local onestripe=$(((NUMDIRS + 1) * NUMFILES))
6858
6859         setup_56 $dir $NUMFILES $NUMDIRS "-c 1"
6860         for i in $(seq $NUMDIRS); do
6861                 $LFS setstripe -c $((OSTCOUNT + 1)) $dir/dir$i/$tfile
6862         done
6863
6864         local expected=$NUMDIRS
6865         local cmd="$LFS find -c $OSTCOUNT $dir"
6866         local nums=$($cmd | wc -l)
6867
6868         [ $nums -eq $expected ] || {
6869                 $LFS getstripe -R $dir
6870                 error "'$cmd' wrong: found $nums, expected $expected"
6871         }
6872
6873         expected=$((NUMDIRS + onestripe))
6874         cmd="$LFS find -stripe-count +0 -type f $dir"
6875         nums=$($cmd | wc -l)
6876         [ $nums -eq $expected ] || {
6877                 $LFS getstripe -R $dir
6878                 error "'$cmd' wrong: found $nums, expected $expected"
6879         }
6880
6881         expected=$onestripe
6882         cmd="$LFS find -stripe-count 1 -type f $dir"
6883         nums=$($cmd | wc -l)
6884         [ $nums -eq $expected ] || {
6885                 $LFS getstripe -R $dir
6886                 error "'$cmd' wrong: found $nums, expected $expected"
6887         }
6888
6889         cmd="$LFS find -stripe-count -2 -type f $dir"
6890         nums=$($cmd | wc -l)
6891         [ $nums -eq $expected ] || {
6892                 $LFS getstripe -R $dir
6893                 error "'$cmd' wrong: found $nums, expected $expected"
6894         }
6895
6896         expected=0
6897         cmd="$LFS find -stripe-count $((OSTCOUNT + 1)) -type f $dir"
6898         nums=$($cmd | wc -l)
6899         [ $nums -eq $expected ] || {
6900                 $LFS getstripe -R $dir
6901                 error "'$cmd' wrong: found $nums, expected $expected"
6902         }
6903 }
6904 run_test 56s "check lfs find -stripe-count works"
6905
6906 test_56t() { # LU-611 #LU-9369
6907         local dir=$DIR/$tdir
6908
6909         setup_56 $dir 0 $NUMDIRS
6910         for i in $(seq $NUMDIRS); do
6911                 $LFS setstripe -S 8M $dir/dir$i/$tfile
6912         done
6913
6914         local expected=$NUMDIRS
6915         local cmd="$LFS find -S 8M $dir"
6916         local nums=$($cmd | wc -l)
6917
6918         [ $nums -eq $expected ] || {
6919                 $LFS getstripe -R $dir
6920                 error "'$cmd' wrong: found $nums, expected $expected"
6921         }
6922         rm -rf $dir
6923
6924         setup_56 $dir $NUMFILES $NUMDIRS "--stripe-size 512k"
6925
6926         $LFS setstripe -S 256k $dir/$tfile.{0,1,2,3}
6927
6928         expected=$(((NUMDIRS + 1) * NUMFILES))
6929         cmd="$LFS find -stripe-size 512k -type f $dir"
6930         nums=$($cmd | wc -l)
6931         [ $nums -eq $expected ] ||
6932                 error "'$cmd' wrong: found $nums, expected $expected"
6933
6934         cmd="$LFS find -stripe-size +320k -type f $dir"
6935         nums=$($cmd | wc -l)
6936         [ $nums -eq $expected ] ||
6937                 error "'$cmd' wrong: found $nums, expected $expected"
6938
6939         expected=$(((NUMDIRS + 1) * NUMFILES + 4))
6940         cmd="$LFS find -stripe-size +200k -type f $dir"
6941         nums=$($cmd | wc -l)
6942         [ $nums -eq $expected ] ||
6943                 error "'$cmd' wrong: found $nums, expected $expected"
6944
6945         cmd="$LFS find -stripe-size -640k -type f $dir"
6946         nums=$($cmd | wc -l)
6947         [ $nums -eq $expected ] ||
6948                 error "'$cmd' wrong: found $nums, expected $expected"
6949
6950         expected=4
6951         cmd="$LFS find -stripe-size 256k -type f $dir"
6952         nums=$($cmd | wc -l)
6953         [ $nums -eq $expected ] ||
6954                 error "'$cmd' wrong: found $nums, expected $expected"
6955
6956         cmd="$LFS find -stripe-size -320k -type f $dir"
6957         nums=$($cmd | wc -l)
6958         [ $nums -eq $expected ] ||
6959                 error "'$cmd' wrong: found $nums, expected $expected"
6960
6961         expected=0
6962         cmd="$LFS find -stripe-size 1024k -type f $dir"
6963         nums=$($cmd | wc -l)
6964         [ $nums -eq $expected ] ||
6965                 error "'$cmd' wrong: found $nums, expected $expected"
6966 }
6967 run_test 56t "check lfs find -stripe-size works"
6968
6969 test_56u() { # LU-611
6970         local dir=$DIR/$tdir
6971
6972         setup_56 $dir $NUMFILES $NUMDIRS "-i 0 -c 1"
6973
6974         if [[ $OSTCOUNT -gt 1 ]]; then
6975                 $LFS setstripe -i 1 -c 1 $dir/$tfile.{0,1,2,3}
6976                 onestripe=4
6977         else
6978                 onestripe=0
6979         fi
6980
6981         local expected=$(((NUMDIRS + 1) * NUMFILES))
6982         local cmd="$LFS find -stripe-index 0 -type f $dir"
6983         local nums=$($cmd | wc -l)
6984
6985         [ $nums -eq $expected ] ||
6986                 error "'$cmd' wrong: found $nums, expected $expected"
6987
6988         expected=$onestripe
6989         cmd="$LFS find -stripe-index 1 -type f $dir"
6990         nums=$($cmd | wc -l)
6991         [ $nums -eq $expected ] ||
6992                 error "'$cmd' wrong: found $nums, expected $expected"
6993
6994         cmd="$LFS find ! -stripe-index 0 -type f $dir"
6995         nums=$($cmd | wc -l)
6996         [ $nums -eq $expected ] ||
6997                 error "'$cmd' wrong: found $nums, expected $expected"
6998
6999         expected=0
7000         # This should produce an error and not return any files
7001         cmd="$LFS find -stripe-index $OSTCOUNT -type f $dir"
7002         nums=$($cmd 2>/dev/null | wc -l)
7003         [ $nums -eq $expected ] ||
7004                 error "'$cmd' wrong: found $nums, expected $expected"
7005
7006         if [[ $OSTCOUNT -gt 1 ]]; then
7007                 expected=$(((NUMDIRS + 1) * NUMFILES + onestripe))
7008                 cmd="$LFS find -stripe-index 0,1 -type f $dir"
7009                 nums=$($cmd | wc -l)
7010                 [ $nums -eq $expected ] ||
7011                         error "'$cmd' wrong: found $nums, expected $expected"
7012         fi
7013 }
7014 run_test 56u "check lfs find -stripe-index works"
7015
7016 test_56v() {
7017         local mdt_idx=0
7018         local dir=$DIR/$tdir
7019
7020         setup_56 $dir $NUMFILES $NUMDIRS
7021
7022         UUID=$(mdtuuid_from_index $mdt_idx $dir)
7023         [ -z "$UUID" ] && error "mdtuuid_from_index cannot find MDT $mdt_idx"
7024
7025         for file in $($LFS find -m $UUID $dir); do
7026                 file_midx=$($LFS getstripe -m $file)
7027                 [ $file_midx -eq $mdt_idx ] ||
7028                         error "lfs find -m $UUID != getstripe -m $file_midx"
7029         done
7030 }
7031 run_test 56v "check 'lfs find -m match with lfs getstripe -m'"
7032
7033 test_56w() {
7034         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7035         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7036
7037         local dir=$DIR/$tdir
7038
7039         setup_56 $dir $NUMFILES $NUMDIRS "-c $OSTCOUNT" "-c1"
7040
7041         local stripe_size=$($LFS getstripe -S -d $dir) ||
7042                 error "$LFS getstripe -S -d $dir failed"
7043         stripe_size=${stripe_size%% *}
7044
7045         local file_size=$((stripe_size * OSTCOUNT))
7046         local file_num=$((NUMDIRS * NUMFILES + NUMFILES))
7047         local required_space=$((file_num * file_size))
7048         local free_space=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
7049                            head -n1)
7050         [[ $free_space -le $((required_space / 1024)) ]] &&
7051                 skip_env "need $required_space, have $free_space kbytes"
7052
7053         local dd_bs=65536
7054         local dd_count=$((file_size / dd_bs))
7055
7056         # write data into the files
7057         local i
7058         local j
7059         local file
7060
7061         for i in $(seq $NUMFILES); do
7062                 file=$dir/file$i
7063                 yes | dd bs=$dd_bs count=$dd_count of=$file &>/dev/null ||
7064                         error "write data into $file failed"
7065         done
7066         for i in $(seq $NUMDIRS); do
7067                 for j in $(seq $NUMFILES); do
7068                         file=$dir/dir$i/file$j
7069                         yes|dd bs=$dd_bs count=$dd_count of=$file &>/dev/null ||
7070                                 error "write data into $file failed"
7071                 done
7072         done
7073
7074         # $LFS_MIGRATE will fail if hard link migration is unsupported
7075         if [[ $MDS1_VERSION -gt $(version_code 2.5.55) ]]; then
7076                 createmany -l$dir/dir1/file1 $dir/dir1/link 200 ||
7077                         error "creating links to $dir/dir1/file1 failed"
7078         fi
7079
7080         local expected=-1
7081
7082         [[ $OSTCOUNT -gt 1 ]] && expected=$((OSTCOUNT - 1))
7083
7084         # lfs_migrate file
7085         local cmd="$LFS_MIGRATE -y -c $expected $dir/file1"
7086
7087         echo "$cmd"
7088         eval $cmd || error "$cmd failed"
7089
7090         check_stripe_count $dir/file1 $expected
7091
7092         if [ $MDS1_VERSION -ge $(version_code 2.6.90) ];
7093         then
7094                 # lfs_migrate file onto OST 0 if it is on OST 1, or onto
7095                 # OST 1 if it is on OST 0. This file is small enough to
7096                 # be on only one stripe.
7097                 file=$dir/migr_1_ost
7098                 dd bs=$dd_bs count=1 if=/dev/urandom of=$file >/dev/null 2>&1 ||
7099                         error "write data into $file failed"
7100                 local obdidx=$($LFS getstripe -i $file)
7101                 local oldmd5=$(md5sum $file)
7102                 local newobdidx=0
7103
7104                 [[ $obdidx -eq 0 ]] && newobdidx=1
7105                 cmd="$LFS migrate -i $newobdidx $file"
7106                 echo $cmd
7107                 eval $cmd || error "$cmd failed"
7108
7109                 local realobdix=$($LFS getstripe -i $file)
7110                 local newmd5=$(md5sum $file)
7111
7112                 [[ $newobdidx -ne $realobdix ]] &&
7113                         error "new OST is different (was=$obdidx, "\
7114                               "wanted=$newobdidx, got=$realobdix)"
7115                 [[ "$oldmd5" != "$newmd5" ]] &&
7116                         error "md5sum differ: $oldmd5, $newmd5"
7117         fi
7118
7119         # lfs_migrate dir
7120         cmd="$LFS_MIGRATE -y -c $expected $dir/dir1"
7121         echo "$cmd"
7122         eval $cmd || error "$cmd failed"
7123
7124         for j in $(seq $NUMFILES); do
7125                 check_stripe_count $dir/dir1/file$j $expected
7126         done
7127
7128         # lfs_migrate works with lfs find
7129         cmd="$LFS find -stripe_count $OSTCOUNT -type f $dir |
7130              $LFS_MIGRATE -y -c $expected"
7131         echo "$cmd"
7132         eval $cmd || error "$cmd failed"
7133
7134         for i in $(seq 2 $NUMFILES); do
7135                 check_stripe_count $dir/file$i $expected
7136         done
7137         for i in $(seq 2 $NUMDIRS); do
7138                 for j in $(seq $NUMFILES); do
7139                 check_stripe_count $dir/dir$i/file$j $expected
7140                 done
7141         done
7142 }
7143 run_test 56w "check lfs_migrate -c stripe_count works"
7144
7145 test_56wb() {
7146         local file1=$DIR/$tdir/file1
7147         local create_pool=false
7148         local initial_pool=$($LFS getstripe -p $DIR)
7149         local pool_list=()
7150         local pool=""
7151
7152         echo -n "Creating test dir..."
7153         test_mkdir $DIR/$tdir &> /dev/null || error "cannot create dir"
7154         echo "done."
7155
7156         echo -n "Creating test file..."
7157         touch $file1 || error "cannot create file"
7158         echo "done."
7159
7160         echo -n "Detecting existing pools..."
7161         pool_list=($($LFS pool_list $FSNAME | grep "$FSNAME\." | cut -d. -f2))
7162
7163         if [ ${#pool_list[@]} -gt 0 ]; then
7164                 echo "${pool_list[@]}"
7165                 for thispool in "${pool_list[@]}"; do
7166                         if [[ -z "$initial_pool" ||
7167                               "$initial_pool" != "$thispool" ]]; then
7168                                 pool="$thispool"
7169                                 echo "Using existing pool '$pool'"
7170                                 break
7171                         fi
7172                 done
7173         else
7174                 echo "none detected."
7175         fi
7176         if [ -z "$pool" ]; then
7177                 pool=${POOL:-testpool}
7178                 [ "$initial_pool" = "$pool" ] && pool="testpool2"
7179                 echo -n "Creating pool '$pool'..."
7180                 create_pool=true
7181                 pool_add $pool &> /dev/null ||
7182                         error "pool_add failed"
7183                 echo "done."
7184
7185                 echo -n "Adding target to pool..."
7186                 pool_add_targets $pool 0 0 1 &> /dev/null ||
7187                         error "pool_add_targets failed"
7188                 echo "done."
7189         fi
7190
7191         echo -n "Setting pool using -p option..."
7192         $LFS_MIGRATE -y -q --no-rsync -p $pool $file1 &> /dev/null ||
7193                 error "migrate failed rc = $?"
7194         echo "done."
7195
7196         echo -n "Verifying test file is in pool after migrating..."
7197         [ "$($LFS getstripe -p $file1)" = $pool ] ||
7198                 error "file was not migrated to pool $pool"
7199         echo "done."
7200
7201         echo -n "Removing test file from pool '$pool'..."
7202         # "lfs migrate $file" won't remove the file from the pool
7203         # until some striping information is changed.
7204         $LFS migrate -c 1 $file1 &> /dev/null ||
7205                 error "cannot remove from pool"
7206         [ "$($LFS getstripe -p $file1)" ] &&
7207                 error "pool still set"
7208         echo "done."
7209
7210         echo -n "Setting pool using --pool option..."
7211         $LFS_MIGRATE -y -q --no-rsync --pool $pool $file1 &> /dev/null ||
7212                 error "migrate failed rc = $?"
7213         echo "done."
7214
7215         # Clean up
7216         rm -f $file1
7217         if $create_pool; then
7218                 destroy_test_pools 2> /dev/null ||
7219                         error "destroy test pools failed"
7220         fi
7221 }
7222 run_test 56wb "check lfs_migrate pool support"
7223
7224 test_56wc() {
7225         local file1="$DIR/$tdir/file1"
7226         local parent_ssize
7227         local parent_scount
7228         local cur_ssize
7229         local cur_scount
7230         local orig_ssize
7231
7232         echo -n "Creating test dir..."
7233         test_mkdir $DIR/$tdir &> /dev/null || error "cannot create dir"
7234         $LFS setstripe -S 1M -c 1 "$DIR/$tdir" &> /dev/null ||
7235                 error "cannot set stripe by '-S 1M -c 1'"
7236         echo "done"
7237
7238         echo -n "Setting initial stripe for test file..."
7239         $LFS setstripe -S 512K -c 1 "$file1" &> /dev/null ||
7240                 error "cannot set stripe"
7241         cur_ssize=$($LFS getstripe -S "$file1")
7242         [ $cur_ssize -eq 524288 ] || error "setstripe -S $cur_ssize != 524288"
7243         echo "done."
7244
7245         # File currently set to -S 512K -c 1
7246
7247         # Ensure -c and -S options are rejected when -R is set
7248         echo -n "Verifying incompatible options are detected..."
7249         $LFS_MIGRATE -y -R -c 1 "$file1" &> /dev/null &&
7250                 error "incompatible -c and -R options not detected"
7251         $LFS_MIGRATE -y -R -S 1M "$file1" &> /dev/null &&
7252                 error "incompatible -S and -R options not detected"
7253         echo "done."
7254
7255         # Ensure unrecognized options are passed through to 'lfs migrate'
7256         echo -n "Verifying -S option is passed through to lfs migrate..."
7257         $LFS_MIGRATE -y -S 1M "$file1" &> /dev/null ||
7258                 error "migration failed"
7259         cur_ssize=$($LFS getstripe -S "$file1")
7260         [ $cur_ssize -eq 1048576 ] || error "migrate -S $cur_ssize != 1048576"
7261         echo "done."
7262
7263         # File currently set to -S 1M -c 1
7264
7265         # Ensure long options are supported
7266         echo -n "Verifying long options supported..."
7267         $LFS_MIGRATE -y --non-block "$file1" &> /dev/null ||
7268                 error "long option without argument not supported"
7269         $LFS_MIGRATE -y --stripe-size 512K "$file1" &> /dev/null ||
7270                 error "long option with argument not supported"
7271         cur_ssize=$($LFS getstripe -S "$file1")
7272         [ $cur_ssize -eq 524288 ] ||
7273                 error "migrate --stripe-size $cur_ssize != 524288"
7274         echo "done."
7275
7276         # File currently set to -S 512K -c 1
7277
7278         if [ "$OSTCOUNT" -gt 1 ]; then
7279                 echo -n "Verifying explicit stripe count can be set..."
7280                 $LFS_MIGRATE -y -c 2 "$file1" &> /dev/null ||
7281                         error "migrate failed"
7282                 cur_scount=$($LFS getstripe -c "$file1")
7283                 [ $cur_scount -eq 2 ] || error "migrate -c $cur_scount != 2"
7284                 echo "done."
7285         fi
7286
7287         # File currently set to -S 512K -c 1 or -S 512K -c 2
7288
7289         # Ensure parent striping is used if -R is set, and no stripe
7290         # count or size is specified
7291         echo -n "Setting stripe for parent directory..."
7292         $LFS setstripe -S 2M -c 1 "$DIR/$tdir" &> /dev/null ||
7293                 error "cannot set stripe '-S 2M -c 1'"
7294         echo "done."
7295
7296         echo -n "Verifying restripe option uses parent stripe settings..."
7297         parent_ssize=$($LFS getstripe -S $DIR/$tdir 2>/dev/null)
7298         parent_scount=$($LFS getstripe -c $DIR/$tdir 2>/dev/null)
7299         $LFS_MIGRATE -y -R "$file1" &> /dev/null ||
7300                 error "migrate failed"
7301         cur_ssize=$($LFS getstripe -S "$file1")
7302         [ $cur_ssize -eq $parent_ssize ] ||
7303                 error "migrate -R stripe_size $cur_ssize != $parent_ssize"
7304         cur_scount=$($LFS getstripe -c "$file1")
7305         [ $cur_scount -eq $parent_scount ] ||
7306                 error "migrate -R stripe_count $cur_scount != $parent_scount"
7307         echo "done."
7308
7309         # File currently set to -S 1M -c 1
7310
7311         # Ensure striping is preserved if -R is not set, and no stripe
7312         # count or size is specified
7313         echo -n "Verifying striping size preserved when not specified..."
7314         orig_ssize=$($LFS getstripe -S "$file1" 2>/dev/null)
7315         $LFS setstripe -S 2M -c 1 "$DIR/$tdir" &> /dev/null ||
7316                 error "cannot set stripe on parent directory"
7317         $LFS_MIGRATE -y "$file1" &> /dev/null ||
7318                 error "migrate failed"
7319         cur_ssize=$($LFS getstripe -S "$file1")
7320         [ $cur_ssize -eq $orig_ssize ] ||
7321                 error "migrate by default $cur_ssize != $orig_ssize"
7322         echo "done."
7323
7324         # Ensure file name properly detected when final option has no argument
7325         echo -n "Verifying file name properly detected..."
7326         $LFS_MIGRATE -y "$file1" &> /dev/null ||
7327                 error "file name interpreted as option argument"
7328         echo "done."
7329
7330         # Clean up
7331         rm -f "$file1"
7332 }
7333 run_test 56wc "check unrecognized options for lfs_migrate are passed through"
7334
7335 test_56wd() {
7336         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7337
7338         local file1=$DIR/$tdir/file1
7339
7340         echo -n "Creating test dir..."
7341         test_mkdir $DIR/$tdir || error "cannot create dir"
7342         echo "done."
7343
7344         echo -n "Creating test file..."
7345         touch $file1
7346         echo "done."
7347
7348         # Ensure 'lfs migrate' will fail by using a non-existent option,
7349         # and make sure rsync is not called to recover
7350         echo -n "Make sure --no-rsync option works..."
7351         $LFS_MIGRATE -y --no-rsync --invalid-opt $file1 2>&1 |
7352                 grep -q 'refusing to fall back to rsync' ||
7353                 error "rsync was called with --no-rsync set"
7354         echo "done."
7355
7356         # Ensure rsync is called without trying 'lfs migrate' first
7357         echo -n "Make sure --rsync option works..."
7358         $LFS_MIGRATE -y --rsync --invalid-opt $file1 2>&1 |
7359                 grep -q 'falling back to rsync' &&
7360                 error "lfs migrate was called with --rsync set"
7361         echo "done."
7362
7363         echo -n "Make sure --rsync and --no-rsync options are exclusive..."
7364         $LFS_MIGRATE -y --rsync --no-rsync $file1 2>&1 |
7365                 grep -q 'at the same time' ||
7366                 error "--rsync and --no-rsync accepted concurrently"
7367         echo "done."
7368
7369         # Clean up
7370         rm -f $file1
7371 }
7372 run_test 56wd "check lfs_migrate --rsync and --no-rsync work"
7373
7374 test_56we() {
7375         local td=$DIR/$tdir
7376         local tf=$td/$tfile
7377
7378         test_mkdir $td || error "cannot create $td"
7379         touch $tf || error "cannot touch $tf"
7380
7381         echo -n "Make sure --non-direct|-D works..."
7382         $LFS_MIGRATE -y --non-direct -v $tf 2>&1 |
7383                 grep -q "lfs migrate --non-direct" ||
7384                 error "--non-direct option cannot work correctly"
7385         $LFS_MIGRATE -y -D -v $tf 2>&1 |
7386                 grep -q "lfs migrate -D" ||
7387                 error "-D option cannot work correctly"
7388         echo "done."
7389 }
7390 run_test 56we "check lfs_migrate --non-direct|-D support"
7391
7392 test_56x() {
7393         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7394         check_swap_layouts_support
7395
7396         local dir=$DIR/$tdir
7397         local ref1=/etc/passwd
7398         local file1=$dir/file1
7399
7400         test_mkdir $dir || error "creating dir $dir"
7401         $LFS setstripe -c 2 $file1
7402         cp $ref1 $file1
7403         $LFS migrate -c 1 $file1 || error "migrate failed rc = $?"
7404         stripe=$($LFS getstripe -c $file1)
7405         [[ $stripe == 1 ]] || error "stripe of $file1 is $stripe != 1"
7406         cmp $file1 $ref1 || error "content mismatch $file1 differs from $ref1"
7407
7408         # clean up
7409         rm -f $file1
7410 }
7411 run_test 56x "lfs migration support"
7412
7413 test_56xa() {
7414         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7415         check_swap_layouts_support
7416
7417         local dir=$DIR/$tdir/$testnum
7418
7419         test_mkdir -p $dir
7420
7421         local ref1=/etc/passwd
7422         local file1=$dir/file1
7423
7424         $LFS setstripe -c 2 $file1
7425         cp $ref1 $file1
7426         $LFS migrate --block -c 1 $file1 || error "migrate failed rc = $?"
7427
7428         local stripe=$($LFS getstripe -c $file1)
7429
7430         [[ $stripe == 1 ]] || error "stripe of $file1 is $stripe != 1"
7431         cmp $file1 $ref1 || error "content mismatch $file1 differs from $ref1"
7432
7433         # clean up
7434         rm -f $file1
7435 }
7436 run_test 56xa "lfs migration --block support"
7437
7438 check_migrate_links() {
7439         local dir="$1"
7440         local file1="$dir/file1"
7441         local begin="$2"
7442         local count="$3"
7443         local runas="$4"
7444         local total_count=$(($begin + $count - 1))
7445         local symlink_count=10
7446         local uniq_count=10
7447
7448         if [ ! -f "$file1" ]; then
7449                 echo -n "creating initial file..."
7450                 $LFS setstripe -c 1 -S "512k" "$file1" ||
7451                         error "cannot setstripe initial file"
7452                 echo "done"
7453
7454                 echo -n "creating symlinks..."
7455                 for s in $(seq 1 $symlink_count); do
7456                         ln -s "$file1" "$dir/slink$s" ||
7457                                 error "cannot create symlinks"
7458                 done
7459                 echo "done"
7460
7461                 echo -n "creating nonlinked files..."
7462                 createmany -o "$dir/uniq" 1 10 &> /dev/null ||
7463                         error "cannot create nonlinked files"
7464                 echo "done"
7465         fi
7466
7467         # create hard links
7468         if [ ! -f "$dir/file$total_count" ]; then
7469                 echo -n "creating hard links $begin:$total_count..."
7470                 createmany -l"$file1" "$dir/file" "$begin" "$count" &>  \
7471                         /dev/null || error "cannot create hard links"
7472                 echo "done"
7473         fi
7474
7475         echo -n "checking number of hard links listed in xattrs..."
7476         local fid=$($LFS getstripe -F "$file1")
7477         local paths=($($LFS fid2path "$MOUNT" "$fid" 2> /dev/null))
7478
7479         echo "${#paths[*]}"
7480         if [ ${#paths[*]} -lt $total_count -a "$begin" -eq 2  ]; then
7481                         skip "hard link list has unexpected size, skipping test"
7482         fi
7483         if [ ${#paths[*]} -ge $total_count -a "$begin" -ne 2  ]; then
7484                         error "link names should exceed xattrs size"
7485         fi
7486
7487         echo -n "migrating files..."
7488         local migrate_out=$($runas $LFS_MIGRATE -y -S '1m' $dir)
7489         local rc=$?
7490         [ $rc -eq 0 ] || error "migrate failed rc = $rc"
7491         echo "done"
7492
7493         # make sure all links have been properly migrated
7494         echo -n "verifying files..."
7495         fid=$($LFS getstripe -F "$file1") ||
7496                 error "cannot get fid for file $file1"
7497         for i in $(seq 2 $total_count); do
7498                 local fid2=$($LFS getstripe -F $dir/file$i)
7499
7500                 [ "$fid2" == "$fid" ] ||
7501                         error "migrated hard link has mismatched FID"
7502         done
7503
7504         # make sure hard links were properly detected, and migration was
7505         # performed only once for the entire link set; nonlinked files should
7506         # also be migrated
7507         local actual=$(grep -c 'done' <<< "$migrate_out")
7508         local expected=$(($uniq_count + 1))
7509
7510         [ "$actual" -eq  "$expected" ] ||
7511                 error "hard links individually migrated ($actual != $expected)"
7512
7513         # make sure the correct number of hard links are present
7514         local hardlinks=$(stat -c '%h' "$file1")
7515
7516         [ $hardlinks -eq $total_count ] ||
7517                 error "num hard links $hardlinks != $total_count"
7518         echo "done"
7519
7520         return 0
7521 }
7522
7523 test_56xb() {
7524         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
7525                 skip "Need MDS version at least 2.10.55"
7526
7527         local dir="$DIR/$tdir"
7528
7529         test_mkdir "$dir" || error "cannot create dir $dir"
7530
7531         echo "testing lfs migrate mode when all links fit within xattrs"
7532         LFS_MIGRATE_RSYNC_MODE=false check_migrate_links "$dir" 2 99
7533
7534         echo "testing rsync mode when all links fit within xattrs"
7535         LFS_MIGRATE_RSYNC_MODE=true check_migrate_links "$dir" 2 99
7536
7537         echo "testing lfs migrate mode when all links do not fit within xattrs"
7538         LFS_MIGRATE_RSYNC_MODE=false check_migrate_links "$dir" 101 100
7539
7540         echo "testing rsync mode when all links do not fit within xattrs"
7541         LFS_MIGRATE_RSYNC_MODE=true check_migrate_links "$dir" 101 100
7542
7543         chown -R $RUNAS_ID $dir
7544         echo "testing non-root lfs migrate mode when not all links are in xattr"
7545         LFS_MIGRATE_RSYNC_MODE=false check_migrate_links "$dir" 101 100 "$RUNAS"
7546
7547         # clean up
7548         rm -rf $dir
7549 }
7550 run_test 56xb "lfs migration hard link support"
7551
7552 test_56xc() {
7553         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7554
7555         local dir="$DIR/$tdir"
7556
7557         test_mkdir "$dir" || error "cannot create dir $dir"
7558
7559         # Test 1: ensure file < 1 GB is always migrated with 1 stripe
7560         echo -n "Setting initial stripe for 20MB test file..."
7561         $LFS setstripe -c 2 -i 0 "$dir/20mb" ||
7562                 error "cannot setstripe 20MB file"
7563         echo "done"
7564         echo -n "Sizing 20MB test file..."
7565         $TRUNCATE "$dir/20mb" 20971520 || error "cannot create 20MB test file"
7566         echo "done"
7567         echo -n "Verifying small file autostripe count is 1..."
7568         $LFS_MIGRATE -y -A -C 1 "$dir/20mb" ||
7569                 error "cannot migrate 20MB file"
7570         local stripe_count=$($LFS getstripe -c "$dir/20mb") ||
7571                 error "cannot get stripe for $dir/20mb"
7572         [ $stripe_count -eq 1 ] ||
7573                 error "unexpected stripe count $stripe_count for 20MB file"
7574         rm -f "$dir/20mb"
7575         echo "done"
7576
7577         # Test 2: File is small enough to fit within the available space on
7578         # sqrt(size_in_gb) + 1 OSTs but is larger than 1GB.  The file must
7579         # have at least an additional 1KB for each desired stripe for test 3
7580         echo -n "Setting stripe for 1GB test file..."
7581         $LFS setstripe -c 1 -i 0 "$dir/1gb" || error "cannot setstripe 1GB file"
7582         echo "done"
7583         echo -n "Sizing 1GB test file..."
7584         # File size is 1GB + 3KB
7585         $TRUNCATE "$dir/1gb" 1073744896 || error "cannot create 1GB test file"
7586         echo "done"
7587
7588         # need at least 512MB per OST for 1GB file to fit in 2 stripes
7589         local avail=$($LCTL get_param -n llite.$FSNAME*.kbytesavail)
7590         if (( avail > 524288 * OSTCOUNT )); then
7591                 echo -n "Migrating 1GB file..."
7592                 $LFS_MIGRATE -y -A -C 1 "$dir/1gb" ||
7593                         error "cannot migrate 1GB file"
7594                 echo "done"
7595                 echo -n "Verifying autostripe count is sqrt(n) + 1..."
7596                 stripe_count=$($LFS getstripe -c "$dir/1gb") ||
7597                         error "cannot getstripe for 1GB file"
7598                 [ $stripe_count -eq 2 ] ||
7599                         error "unexpected stripe count $stripe_count != 2"
7600                 echo "done"
7601         fi
7602
7603         # Test 3: File is too large to fit within the available space on
7604         # sqrt(n) + 1 OSTs.  Simulate limited available space with -X
7605         if [ $OSTCOUNT -ge 3 ]; then
7606                 # The required available space is calculated as
7607                 # file size (1GB + 3KB) / OST count (3).
7608                 local kb_per_ost=349526
7609
7610                 echo -n "Migrating 1GB file with limit..."
7611                 $LFS_MIGRATE -y -A -C 1 -X $kb_per_ost "$dir/1gb" ||
7612                         error "cannot migrate 1GB file with limit"
7613                 echo "done"
7614
7615                 stripe_count=$($LFS getstripe -c "$dir/1gb")
7616                 echo -n "Verifying 1GB autostripe count with limited space..."
7617                 [ "$stripe_count" -a $stripe_count -ge 3 ] ||
7618                         error "unexpected stripe count $stripe_count (min 3)"
7619                 echo "done"
7620         fi
7621
7622         # clean up
7623         rm -rf $dir
7624 }
7625 run_test 56xc "lfs migration autostripe"
7626
7627 test_56xd() {
7628         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7629
7630         local dir=$DIR/$tdir
7631         local f_mgrt=$dir/$tfile.mgrt
7632         local f_yaml=$dir/$tfile.yaml
7633         local f_copy=$dir/$tfile.copy
7634         local layout_yaml="-E 1M -S 512K -c 1 -E -1 -S 1M -c 2 -i 0"
7635         local layout_copy="-c 2 -S 2M -i 1"
7636         local yamlfile=$dir/yamlfile
7637         local layout_before;
7638         local layout_after;
7639
7640         test_mkdir "$dir" || error "cannot create dir $dir"
7641         $LFS setstripe $layout_yaml $f_yaml ||
7642                 error "cannot setstripe $f_yaml with layout $layout_yaml"
7643         $LFS getstripe --yaml $f_yaml > $yamlfile
7644         $LFS setstripe $layout_copy $f_copy ||
7645                 error "cannot setstripe $f_copy with layout $layout_copy"
7646         touch $f_mgrt
7647         dd if=/dev/zero of=$f_mgrt bs=1M count=4
7648
7649         # 1. test option --yaml
7650         $LFS_MIGRATE -y --yaml $yamlfile $f_mgrt ||
7651                 error "cannot migrate $f_mgrt with --yaml $yamlfile"
7652         layout_before=$(get_layout_param $f_yaml)
7653         layout_after=$(get_layout_param $f_mgrt)
7654         [ "$layout_after" == "$layout_before" ] ||
7655                 error "lfs_migrate --yaml: $layout_after != $layout_before"
7656
7657         # 2. test option --copy
7658         $LFS_MIGRATE -y --copy $f_copy $f_mgrt ||
7659                 error "cannot migrate $f_mgrt with --copy $f_copy"
7660         layout_before=$(get_layout_param $f_copy)
7661         layout_after=$(get_layout_param $f_mgrt)
7662         [ "$layout_after" == "$layout_before" ] ||
7663                 error "lfs_migrate --copy: $layout_after != $layout_before"
7664 }
7665 run_test 56xd "check lfs_migrate --yaml and --copy support"
7666
7667 test_56xe() {
7668         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7669
7670         local dir=$DIR/$tdir
7671         local f_comp=$dir/$tfile
7672         local layout="-E 1M -S 512K -c 1 -E -1 -S 1M -c 2 -i 0"
7673         local layout_before=""
7674         local layout_after=""
7675
7676         test_mkdir "$dir" || error "cannot create dir $dir"
7677         $LFS setstripe $layout $f_comp ||
7678                 error "cannot setstripe $f_comp with layout $layout"
7679         layout_before=$(get_layout_param $f_comp)
7680         dd if=/dev/zero of=$f_comp bs=1M count=4
7681
7682         # 1. migrate a comp layout file by lfs_migrate
7683         $LFS_MIGRATE -y $f_comp || error "cannot migrate $f_comp by lfs_migrate"
7684         layout_after=$(get_layout_param $f_comp)
7685         [ "$layout_before" == "$layout_after" ] ||
7686                 error "lfs_migrate: $layout_before != $layout_after"
7687
7688         # 2. migrate a comp layout file by lfs migrate
7689         $LFS migrate $f_comp || error "cannot migrate $f_comp by lfs migrate"
7690         layout_after=$(get_layout_param $f_comp)
7691         [ "$layout_before" == "$layout_after" ] ||
7692                 error "lfs migrate: $layout_before != $layout_after"
7693 }
7694 run_test 56xe "migrate a composite layout file"
7695
7696 test_56xf() {
7697         [[ $OSTCOUNT -ge 2 ]] || skip_env "needs >= 2 OSTs"
7698
7699         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
7700                 skip "Need server version at least 2.13.53"
7701
7702         local dir=$DIR/$tdir
7703         local f_comp=$dir/$tfile
7704         local layout="-E 1M -c1 -E -1 -c2"
7705         local fid_before=""
7706         local fid_after=""
7707
7708         test_mkdir "$dir" || error "cannot create dir $dir"
7709         $LFS setstripe $layout $f_comp ||
7710                 error "cannot setstripe $f_comp with layout $layout"
7711         fid_before=$($LFS getstripe --fid $f_comp)
7712         dd if=/dev/zero of=$f_comp bs=1M count=4
7713
7714         # 1. migrate a comp layout file to a comp layout
7715         $LFS migrate $f_comp || error "cannot migrate $f_comp by lfs migrate"
7716         fid_after=$($LFS getstripe --fid $f_comp)
7717         [ "$fid_before" == "$fid_after" ] ||
7718                 error "comp-to-comp migrate: $fid_before != $fid_after"
7719
7720         # 2. migrate a comp layout file to a plain layout
7721         $LFS migrate -c2 $f_comp ||
7722                 error "cannot migrate $f_comp by lfs migrate"
7723         fid_after=$($LFS getstripe --fid $f_comp)
7724         [ "$fid_before" == "$fid_after" ] ||
7725                 error "comp-to-plain migrate: $fid_before != $fid_after"
7726
7727         # 3. migrate a plain layout file to a comp layout
7728         $LFS migrate $layout $f_comp ||
7729                 error "cannot migrate $f_comp by lfs migrate"
7730         fid_after=$($LFS getstripe --fid $f_comp)
7731         [ "$fid_before" == "$fid_after" ] ||
7732                 error "plain-to-comp migrate: $fid_before != $fid_after"
7733 }
7734 run_test 56xf "FID is not lost during migration of a composite layout file"
7735
7736 check_file_ost_range() {
7737         local file="$1"
7738         shift
7739         local range="$*"
7740         local -a file_range
7741         local idx
7742
7743         file_range=($($LFS getstripe -y "$file" |
7744                 awk '/l_ost_idx:/ { print $NF }'))
7745
7746         if [[ "${#file_range[@]}" = 0 ]]; then
7747                 echo "No osts found for $file"
7748                 return 1
7749         fi
7750
7751         for idx in "${file_range[@]}"; do
7752                 [[ " $range " =~ " $idx " ]] ||
7753                         return 1
7754         done
7755
7756         return 0
7757 }
7758
7759 sub_test_56xg() {
7760         local stripe_opt="$1"
7761         local pool="$2"
7762         shift 2
7763         local pool_ostidx="$(seq $* | tr '\n' ' ')"
7764
7765         $LFS migrate $stripe_opt -p $pool $DIR/$tfile ||
7766                 error "Fail to migrate $tfile on $pool"
7767         [[ "$($LFS getstripe -p $DIR/$tfile)" = "$pool" ]] ||
7768                 error "$tfile is not in pool $pool"
7769         check_file_ost_range "$DIR/$tfile" $pool_ostidx ||
7770                 error "$tfile osts mismatch with pool $pool (osts $pool_ostidx)"
7771 }
7772
7773 test_56xg() {
7774         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
7775         [[ $OSTCOUNT -ge 2 ]] || skip "needs >= 2 OSTs"
7776         [[ $MDS1_VERSION -gt $(version_code 2.14.52) ]] ||
7777                 skip "Need MDS version newer than 2.14.52"
7778
7779         local -a pool_names=("${TESTNAME}_0" "${TESTNAME}_1" "${TESTNAME}_2")
7780         local -a pool_ranges=("0 0" "1 1" "0 1")
7781
7782         # init pools
7783         for i in "${!pool_names[@]}"; do
7784                 pool_add ${pool_names[$i]} ||
7785                         error "pool_add failed (pool: ${pool_names[$i]})"
7786                 pool_add_targets ${pool_names[$i]} ${pool_ranges[$i]} ||
7787                         error "pool_add_targets failed (pool: ${pool_names[$i]})"
7788         done
7789
7790         # init the file to migrate
7791         $LFS setstripe -c1 -i1 $DIR/$tfile ||
7792                 error "Unable to create $tfile on OST1"
7793         dd if=/dev/urandom of=$DIR/$tfile bs=1M count=4 status=none ||
7794                 error "Unable to write on $tfile"
7795
7796         echo "1. migrate $tfile on pool ${pool_names[0]}"
7797         sub_test_56xg "-c-1" "${pool_names[0]}" ${pool_ranges[0]}
7798
7799         echo "2. migrate $tfile on pool ${pool_names[2]}"
7800         sub_test_56xg "-c-1 -S2M" "${pool_names[2]}" ${pool_ranges[2]}
7801
7802         echo "3. migrate $tfile on pool ${pool_names[1]}"
7803         sub_test_56xg "-n -c-1" "${pool_names[1]}" ${pool_ranges[1]}
7804
7805         echo "4. migrate $tfile on pool ${pool_names[2]} with default stripe parameters"
7806         sub_test_56xg "" "${pool_names[2]}" ${pool_ranges[2]}
7807         echo
7808
7809         # Clean pools
7810         destroy_test_pools ||
7811                 error "pool_destroy failed"
7812 }
7813 run_test 56xg "lfs migrate pool support"
7814
7815 test_56y() {
7816         [ $MDS1_VERSION -lt $(version_code 2.4.53) ] &&
7817                 skip "No HSM $(lustre_build_version $SINGLEMDS) MDS < 2.4.53"
7818
7819         local res=""
7820         local dir=$DIR/$tdir
7821         local f1=$dir/file1
7822         local f2=$dir/file2
7823
7824         test_mkdir -p $dir || error "creating dir $dir"
7825         touch $f1 || error "creating std file $f1"
7826         $MULTIOP $f2 H2c || error "creating released file $f2"
7827
7828         # a directory can be raid0, so ask only for files
7829         res=$($LFS find $dir -L raid0 -type f | wc -l)
7830         [[ $res == 2 ]] || error "search raid0: found $res files != 2"
7831
7832         res=$($LFS find $dir \! -L raid0 -type f | wc -l)
7833         [[ $res == 0 ]] || error "search !raid0: found $res files != 0"
7834
7835         # only files can be released, so no need to force file search
7836         res=$($LFS find $dir -L released)
7837         [[ $res == $f2 ]] || error "search released: found $res != $f2"
7838
7839         res=$($LFS find $dir -type f \! -L released)
7840         [[ $res == $f1 ]] || error "search !released: found $res != $f1"
7841 }
7842 run_test 56y "lfs find -L raid0|released"
7843
7844 test_56z() { # LU-4824
7845         # This checks to make sure 'lfs find' continues after errors
7846         # There are two classes of errors that should be caught:
7847         # - If multiple paths are provided, all should be searched even if one
7848         #   errors out
7849         # - If errors are encountered during the search, it should not terminate
7850         #   early
7851         local dir=$DIR/$tdir
7852         local i
7853
7854         test_mkdir $dir
7855         for i in d{0..9}; do
7856                 test_mkdir $dir/$i
7857                 touch $dir/$i/$tfile
7858         done
7859         $LFS find $DIR/non_existent_dir $dir &&
7860                 error "$LFS find did not return an error"
7861         # Make a directory unsearchable. This should NOT be the last entry in
7862         # directory order.  Arbitrarily pick the 6th entry
7863         chmod 700 $($LFS find $dir -type d | sed '6!d')
7864
7865         $RUNAS $LFS find $DIR/non_existent $dir
7866         local count=$($RUNAS $LFS find $DIR/non_existent $dir | wc -l)
7867
7868         # The user should be able to see 10 directories and 9 files
7869         (( count == 19 )) ||
7870                 error "$LFS find found $count != 19 entries after error"
7871 }
7872 run_test 56z "lfs find should continue after an error"
7873
7874 test_56aa() { # LU-5937
7875         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
7876
7877         local dir=$DIR/$tdir
7878
7879         mkdir $dir
7880         $LFS setdirstripe -c$MDSCOUNT $dir/striped_dir
7881
7882         createmany -o $dir/striped_dir/${tfile}- 1024
7883         local dirs=$($LFS find --size +8k $dir/)
7884
7885         [ -n "$dirs" ] || error "lfs find --size wrong under striped dir"
7886 }
7887 run_test 56aa "lfs find --size under striped dir"
7888
7889 test_56ab() { # LU-10705
7890         test_mkdir $DIR/$tdir
7891         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=8k count=1 seek=2k
7892         dd if=/dev/zero of=$DIR/$tdir/$tfile.2 bs=4k count=1 seek=4k
7893         dd if=/dev/zero of=$DIR/$tdir/$tfile.3 bs=1M count=2 seek=16
7894         # Flush writes to ensure valid blocks.  Need to be more thorough for
7895         # ZFS, since blocks are not allocated/returned to client immediately.
7896         sync_all_data
7897         wait_zfs_commit ost1 2
7898         cancel_lru_locks osc
7899         ls -ls $DIR/$tdir
7900
7901         local files=$($LFS find --size +16M $DIR/$tdir | wc -l)
7902
7903         [[ $files == 3 ]] || error ">16M size files $files isn't 3 as expected"
7904
7905         files=$($LFS find --blocks +1M $DIR/$tdir | wc -l)
7906         [[ $files == 1 ]] || error ">1M blocks files $files isn't 1 as expected"
7907
7908         rm -f $DIR/$tdir/$tfile.[123]
7909 }
7910 run_test 56ab "lfs find --blocks"
7911
7912 # LU-11188
7913 test_56aca() {
7914         local dir="$DIR/$tdir"
7915         local perms=(001 002 003 004 005 006 007
7916                      010 020 030 040 050 060 070
7917                      100 200 300 400 500 600 700
7918                      111 222 333 444 555 666 777)
7919         local perm_minus=(8 8 4 8 4 4 2
7920                           8 8 4 8 4 4 2
7921                           8 8 4 8 4 4 2
7922                           4 4 2 4 2 2 1)
7923         local perm_slash=(8  8 12  8 12 12 14
7924                           8  8 12  8 12 12 14
7925                           8  8 12  8 12 12 14
7926                          16 16 24 16 24 24 28)
7927
7928         test_mkdir "$dir"
7929         for perm in ${perms[*]}; do
7930                 touch "$dir/$tfile.$perm"
7931                 chmod $perm "$dir/$tfile.$perm"
7932         done
7933
7934         for ((i = 0; i < ${#perms[*]}; i++)); do
7935                 local num=$($LFS find $dir -perm ${perms[i]} | wc -l)
7936                 (( $num == 1 )) ||
7937                         error "lfs find -perm ${perms[i]}:"\
7938                               "$num != 1"
7939
7940                 num=$($LFS find $dir -perm -${perms[i]} -type f| wc -l)
7941                 (( $num == ${perm_minus[i]} )) ||
7942                         error "lfs find -perm -${perms[i]}:"\
7943                               "$num != ${perm_minus[i]}"
7944
7945                 num=$($LFS find $dir -perm /${perms[i]} -type f| wc -l)
7946                 (( $num == ${perm_slash[i]} )) ||
7947                         error "lfs find -perm /${perms[i]}:"\
7948                               "$num != ${perm_slash[i]}"
7949         done
7950 }
7951 run_test 56aca "check lfs find -perm with octal representation"
7952
7953 test_56acb() {
7954         local dir=$DIR/$tdir
7955         # p is the permission of write and execute for user, group and other
7956         # without the umask. It is used to test +wx.
7957         local p=$(printf "%o" "$((0333 & ~$(umask)))")
7958         local perms=(1000 000 2000 4000 $p 644 111 110 100 004)
7959         local symbolic=(+t  a+t u+t g+t o+t
7960                         g+s u+s o+s +s o+sr
7961                         o=r,ug+o,u+w
7962                         u+ g+ o+ a+ ugo+
7963                         u- g- o- a- ugo-
7964                         u= g= o= a= ugo=
7965                         o=r,ug+o,u+w u=r,a+u,u+w
7966                         g=r,ugo=g,u+w u+x,+X +X
7967                         u+x,u+X u+X u+x,g+X o+r,+X
7968                         u+x,go+X +wx +rwx)
7969
7970         test_mkdir $dir
7971         for perm in ${perms[*]}; do
7972                 touch "$dir/$tfile.$perm"
7973                 chmod $perm "$dir/$tfile.$perm"
7974         done
7975
7976         for (( i = 0; i < ${#symbolic[*]}; i++ )); do
7977                 local num=$($LFS find $dir -perm ${symbolic[i]} | wc -l)
7978
7979                 (( $num == 1 )) ||
7980                         error "lfs find $dir -perm ${symbolic[i]}: $num != 1"
7981         done
7982 }
7983 run_test 56acb "check lfs find -perm with symbolic representation"
7984
7985 test_56acc() {
7986         local dir=$DIR/$tdir
7987         local tests="17777 787 789 abcd
7988                 ug=uu ug=a ug=gu uo=ou urw
7989                 u+xg+x a=r,u+x,"
7990
7991         test_mkdir $dir
7992         for err in $tests; do
7993                 if $LFS find $dir -perm $err 2>/dev/null; then
7994                         error "lfs find -perm $err: parsing should have failed"
7995                 fi
7996         done
7997 }
7998 run_test 56acc "check parsing error for lfs find -perm"
7999
8000 test_56ba() {
8001         [ $MDS1_VERSION -lt $(version_code 2.10.50) ] &&
8002                 skip "Need MDS version at least 2.10.50"
8003
8004         # Create composite files with one component
8005         local dir=$DIR/$tdir
8006
8007         setup_56 $dir/1Mfiles 5 1 "-S 1M --component-end 1M"
8008         # Create composite files with three components
8009         setup_56 $dir/2Mfiles 5 2 "-E 2M -S 1M -E 4M -E 6M"
8010         # Create non-composite files
8011         createmany -o $dir/${tfile}- 10
8012
8013         local nfiles=$($LFS find --component-end 1M --type f $dir | wc -l)
8014
8015         [[ $nfiles == 10 ]] ||
8016                 error "lfs find -E 1M found $nfiles != 10 files"
8017
8018         nfiles=$($LFS find ! -E 1M --type f $dir | wc -l)
8019         [[ $nfiles == 25 ]] ||
8020                 error "lfs find ! -E 1M found $nfiles != 25 files"
8021
8022         # All files have a component that starts at 0
8023         nfiles=$($LFS find --component-start 0 --type f $dir | wc -l)
8024         [[ $nfiles == 35 ]] ||
8025                 error "lfs find --component-start 0 - $nfiles != 35 files"
8026
8027         nfiles=$($LFS find --component-start 2M --type f $dir | wc -l)
8028         [[ $nfiles == 15 ]] ||
8029                 error "lfs find --component-start 2M - $nfiles != 15 files"
8030
8031         # All files created here have a componenet that does not starts at 2M
8032         nfiles=$($LFS find ! --component-start 2M --type f $dir | wc -l)
8033         [[ $nfiles == 35 ]] ||
8034                 error "lfs find ! --component-start 2M - $nfiles != 35 files"
8035
8036         # Find files with a specified number of components
8037         local nfiles=$($LFS find --component-count 3 --type f $dir | wc -l)
8038         [[ $nfiles == 15 ]] ||
8039                 error "lfs find --component-count 3 - $nfiles != 15 files"
8040
8041         # Remember non-composite files have a component count of zero
8042         local nfiles=$($LFS find --component-count 0 --type f $dir | wc -l)
8043         [[ $nfiles == 10 ]] ||
8044                 error "lfs find --component-count 0 - $nfiles != 10 files"
8045
8046         nfiles=$($LFS find ! --component-count 3 --type f $dir | wc -l)
8047         [[ $nfiles == 20 ]] ||
8048                 error "lfs find ! --component-count 3 - $nfiles != 20 files"
8049
8050         # All files have a flag called "init"
8051         local nfiles=$($LFS find --component-flags init --type f $dir | wc -l)
8052         [[ $nfiles == 35 ]] ||
8053                 error "lfs find --component-flags init - $nfiles != 35 files"
8054
8055         # Multi-component files will have a component not initialized
8056         local nfiles=$($LFS find ! --component-flags init --type f $dir | wc -l)
8057         [[ $nfiles == 15 ]] ||
8058                 error "lfs find !--component-flags init - $nfiles != 15 files"
8059
8060         rm -rf $dir
8061
8062 }
8063 run_test 56ba "test lfs find --component-end, -start, -count, and -flags"
8064
8065 test_56ca() {
8066         [[ $MDS1_VERSION -ge $(version_code 2.10.57) ]] ||
8067                 skip "Need MDS version at least 2.10.57"
8068
8069         local td=$DIR/$tdir
8070         local tf=$td/$tfile
8071         local dir
8072         local nfiles
8073         local cmd
8074         local i
8075         local j
8076
8077         # create mirrored directories and mirrored files
8078         mkdir $td || error "mkdir $td failed"
8079         $LFS mirror create -N3 $td || error "create mirrored dir $td failed"
8080         createmany -o $tf- 10 || error "create $tf- failed"
8081
8082         for i in $(seq 2); do
8083                 dir=$td/dir$i
8084                 mkdir $dir || error "mkdir $dir failed"
8085                 $LFS mirror create -N$((3 + i)) $dir ||
8086                         error "create mirrored dir $dir failed"
8087                 createmany -o $dir/$tfile- 10 ||
8088                         error "create $dir/$tfile- failed"
8089         done
8090
8091         # change the states of some mirrored files
8092         echo foo > $tf-6
8093         for i in $(seq 2); do
8094                 dir=$td/dir$i
8095                 for j in $(seq 4 9); do
8096                         echo foo > $dir/$tfile-$j
8097                 done
8098         done
8099
8100         # find mirrored files with specific mirror count
8101         cmd="$LFS find --mirror-count 3 --type f $td"
8102         nfiles=$($cmd | wc -l)
8103         [[ $nfiles = 10 ]] || error "$cmd: $nfiles != 10 files"
8104
8105         cmd="$LFS find ! --mirror-count 3 --type f $td"
8106         nfiles=$($cmd | wc -l)
8107         [[ $nfiles = 20 ]] || error "$cmd: $nfiles != 20 files"
8108
8109         cmd="$LFS find --mirror-count +2 --type f $td"
8110         nfiles=$($cmd | wc -l)
8111         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
8112
8113         cmd="$LFS find --mirror-count -6 --type f $td"
8114         nfiles=$($cmd | wc -l)
8115         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
8116
8117         # find mirrored files with specific file state
8118         cmd="$LFS find --maxdepth 1 --mirror-state=^ro --type f $td"
8119         [[ $($cmd) = $tf-6 ]] || error "$cmd: didn't return $tf-6"
8120
8121         cmd="$LFS find --mirror-state=ro --type f $td"
8122         nfiles=$($cmd | wc -l)
8123         [[ $nfiles = 17 ]] || error "$cmd: $nfiles != 17 files"
8124
8125         cmd="$LFS find ! --mirror-state=ro --type f $td"
8126         nfiles=$($cmd | wc -l)
8127         [[ $nfiles = 13 ]] || error "$cmd: $nfiles != 13 files"
8128
8129         cmd="$LFS find --mirror-state=wp --type f $td"
8130         nfiles=$($cmd | wc -l)
8131         [[ $nfiles = 13 ]] || error "$cmd: $nfiles != 13 files"
8132
8133         cmd="$LFS find ! --mirror-state=sp --type f $td"
8134         nfiles=$($cmd | wc -l)
8135         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
8136 }
8137 run_test 56ca "check lfs find --mirror-count|-N and --mirror-state"
8138
8139 test_56da() { # LU-14179
8140         local path=$DIR/$tdir
8141
8142         test_mkdir $path
8143         cd $path
8144
8145         local longdir=$(str_repeat 'a' 255)
8146
8147         for i in {1..15}; do
8148                 path=$path/$longdir
8149                 test_mkdir $longdir
8150                 cd $longdir
8151         done
8152
8153         local len=${#path}
8154         local lastdir=$(str_repeat 'a' $((4096 - 1 - $len - 1)))
8155
8156         test_mkdir $lastdir
8157         cd $lastdir
8158         # PATH_MAX-1
8159         (( ${#PWD} == 4095 )) || error "bad PWD length ${#PWD}, expect 4095"
8160
8161         # NAME_MAX
8162         touch $(str_repeat 'f' 255)
8163
8164         $LFS find $DIR/$tdir --type d |& grep "lfs find: error" &&
8165                 error "lfs find reported an error"
8166
8167         rm -rf $DIR/$tdir
8168 }
8169 run_test 56da "test lfs find with long paths"
8170
8171 test_57a() {
8172         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8173         # note test will not do anything if MDS is not local
8174         if [ "$mds1_FSTYPE" != ldiskfs ]; then
8175                 skip_env "ldiskfs only test"
8176         fi
8177         remote_mds_nodsh && skip "remote MDS with nodsh"
8178
8179         local MNTDEV="osd*.*MDT*.mntdev"
8180         DEV=$(do_facet $SINGLEMDS lctl get_param -n $MNTDEV)
8181         [ -z "$DEV" ] && error "can't access $MNTDEV"
8182         for DEV in $(do_facet $SINGLEMDS lctl get_param -n $MNTDEV); do
8183                 do_facet $SINGLEMDS $DUMPE2FS -h $DEV > $TMP/t57a.dump ||
8184                         error "can't access $DEV"
8185                 DEVISIZE=$(awk '/Inode size:/ { print $3 }' $TMP/t57a.dump)
8186                 [[ $DEVISIZE -gt 128 ]] || error "inode size $DEVISIZE"
8187                 rm $TMP/t57a.dump
8188         done
8189 }
8190 run_test 57a "verify MDS filesystem created with large inodes =="
8191
8192 test_57b() {
8193         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8194         if [ "$mds1_FSTYPE" != ldiskfs ]; then
8195                 skip_env "ldiskfs only test"
8196         fi
8197         remote_mds_nodsh && skip "remote MDS with nodsh"
8198
8199         local dir=$DIR/$tdir
8200         local filecount=100
8201         local file1=$dir/f1
8202         local fileN=$dir/f$filecount
8203
8204         rm -rf $dir || error "removing $dir"
8205         test_mkdir -c1 $dir
8206         local mdtidx=$($LFS getstripe -m $dir)
8207         local mdtname=MDT$(printf %04x $mdtidx)
8208         local facet=mds$((mdtidx + 1))
8209
8210         echo "mcreating $filecount files"
8211         createmany -m $dir/f 1 $filecount || error "creating files in $dir"
8212
8213         # verify that files do not have EAs yet
8214         $LFS getstripe $file1 2>&1 | grep -q "no stripe" ||
8215                 error "$file1 has an EA"
8216         $LFS getstripe $fileN 2>&1 | grep -q "no stripe" ||
8217                 error "$fileN has an EA"
8218
8219         sync
8220         sleep 1
8221         df $dir  #make sure we get new statfs data
8222         local mdsfree=$(do_facet $facet \
8223                         lctl get_param -n osd*.*$mdtname.kbytesfree)
8224         local mdcfree=$(lctl get_param -n mdc.*$mdtname-mdc-*.kbytesfree)
8225         local file
8226
8227         echo "opening files to create objects/EAs"
8228         for file in $(seq -f $dir/f%g 1 $filecount); do
8229                 $OPENFILE -f O_RDWR $file > /dev/null 2>&1 ||
8230                         error "opening $file"
8231         done
8232
8233         # verify that files have EAs now
8234         $LFS getstripe $file1 | grep -q "obdidx" || error "$file1 missing EA"
8235         $LFS getstripe $fileN | grep -q "obdidx" || error "$fileN missing EA"
8236
8237         sleep 1  #make sure we get new statfs data
8238         df $dir
8239         local mdsfree2=$(do_facet $facet \
8240                          lctl get_param -n osd*.*$mdtname.kbytesfree)
8241         local mdcfree2=$(lctl get_param -n mdc.*$mdtname-mdc-*.kbytesfree)
8242
8243         if [[ $mdcfree2 -lt $((mdcfree - 16)) ]]; then
8244                 if [ "$mdsfree" != "$mdsfree2" ]; then
8245                         error "MDC before $mdcfree != after $mdcfree2"
8246                 else
8247                         echo "MDC before $mdcfree != after $mdcfree2"
8248                         echo "unable to confirm if MDS has large inodes"
8249                 fi
8250         fi
8251         rm -rf $dir
8252 }
8253 run_test 57b "default LOV EAs are stored inside large inodes ==="
8254
8255 test_58() {
8256         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8257         [ -z "$(which wiretest 2>/dev/null)" ] &&
8258                         skip_env "could not find wiretest"
8259
8260         wiretest
8261 }
8262 run_test 58 "verify cross-platform wire constants =============="
8263
8264 test_59() {
8265         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8266
8267         echo "touch 130 files"
8268         createmany -o $DIR/f59- 130
8269         echo "rm 130 files"
8270         unlinkmany $DIR/f59- 130
8271         sync
8272         # wait for commitment of removal
8273         wait_delete_completed
8274 }
8275 run_test 59 "verify cancellation of llog records async ========="
8276
8277 TEST60_HEAD="test_60 run $RANDOM"
8278 test_60a() {
8279         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8280         remote_mgs_nodsh && skip "remote MGS with nodsh"
8281         do_facet mgs "! which run-llog.sh &> /dev/null" &&
8282                 do_facet mgs "! ls run-llog.sh &> /dev/null" &&
8283                         skip_env "missing subtest run-llog.sh"
8284
8285         log "$TEST60_HEAD - from kernel mode"
8286         do_facet mgs "$LCTL dk > /dev/null"
8287         do_facet mgs "bash run-llog.sh" || error "run-llog.sh failed"
8288         do_facet mgs $LCTL dk > $TMP/$tfile
8289
8290         # LU-6388: test llog_reader
8291         local llog_reader=$(do_facet mgs "which llog_reader 2> /dev/null")
8292         llog_reader=${llog_reader:-$LUSTRE/utils/llog_reader}
8293         [ -z $(do_facet mgs ls -d $llog_reader 2> /dev/null) ] &&
8294                         skip_env "missing llog_reader"
8295         local fstype=$(facet_fstype mgs)
8296         [ $fstype != ldiskfs -a $fstype != zfs ] &&
8297                 skip_env "Only for ldiskfs or zfs type mgs"
8298
8299         local mntpt=$(facet_mntpt mgs)
8300         local mgsdev=$(mgsdevname 1)
8301         local fid_list
8302         local fid
8303         local rec_list
8304         local rec
8305         local rec_type
8306         local obj_file
8307         local path
8308         local seq
8309         local oid
8310         local pass=true
8311
8312         #get fid and record list
8313         fid_list=($(awk '/9_sub.*record/ { print $NF }' $TMP/$tfile |
8314                 tail -n 4))
8315         rec_list=($(awk '/9_sub.*record/ { print $((NF-3)) }' $TMP/$tfile |
8316                 tail -n 4))
8317         #remount mgs as ldiskfs or zfs type
8318         stop mgs || error "stop mgs failed"
8319         mount_fstype mgs || error "remount mgs failed"
8320         for ((i = 0; i < ${#fid_list[@]}; i++)); do
8321                 fid=${fid_list[i]}
8322                 rec=${rec_list[i]}
8323                 seq=$(echo $fid | awk -F ':' '{ print $1 }' | sed -e "s/^0x//g")
8324                 oid=$(echo $fid | awk -F ':' '{ print $2 }' | sed -e "s/^0x//g")
8325                 oid=$((16#$oid))
8326
8327                 case $fstype in
8328                         ldiskfs )
8329                                 obj_file=$mntpt/O/$seq/d$((oid%32))/$oid ;;
8330                         zfs )
8331                                 obj_file=$mntpt/oi.$(($((16#$seq))&127))/$fid ;;
8332                 esac
8333                 echo "obj_file is $obj_file"
8334                 do_facet mgs $llog_reader $obj_file
8335
8336                 rec_type=$(do_facet mgs $llog_reader $obj_file | grep "type=" |
8337                         awk '{ print $3 }' | sed -e "s/^type=//g")
8338                 if [ $rec_type != $rec ]; then
8339                         echo "FAILED test_60a wrong record type $rec_type," \
8340                               "should be $rec"
8341                         pass=false
8342                         break
8343                 fi
8344
8345                 #check obj path if record type is LLOG_LOGID_MAGIC
8346                 if [ "$rec" == "1064553b" ]; then
8347                         path=$(do_facet mgs $llog_reader $obj_file |
8348                                 grep "path=" | awk '{ print $NF }' |
8349                                 sed -e "s/^path=//g")
8350                         if [ $obj_file != $mntpt/$path ]; then
8351                                 echo "FAILED test_60a wrong obj path" \
8352                                       "$montpt/$path, should be $obj_file"
8353                                 pass=false
8354                                 break
8355                         fi
8356                 fi
8357         done
8358         rm -f $TMP/$tfile
8359         #restart mgs before "error", otherwise it will block the next test
8360         stop mgs || error "stop mgs failed"
8361         start mgs $(mgsdevname) $MGS_MOUNT_OPTS || error "start mgs failed"
8362         $pass || error "test failed, see FAILED test_60a messages for specifics"
8363 }
8364 run_test 60a "llog_test run from kernel module and test llog_reader"
8365
8366 test_60b() { # bug 6411
8367         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8368
8369         dmesg > $DIR/$tfile
8370         LLOG_COUNT=$(do_facet mgs dmesg |
8371                      awk "/$TEST60_HEAD/ { marker = 1; from_marker = 0; }
8372                           /llog_[a-z]*.c:[0-9]/ {
8373                                 if (marker)
8374                                         from_marker++
8375                                 from_begin++
8376                           }
8377                           END {
8378                                 if (marker)
8379                                         print from_marker
8380                                 else
8381                                         print from_begin
8382                           }")
8383
8384         [[ $LLOG_COUNT -gt 120 ]] &&
8385                 error "CDEBUG_LIMIT not limiting messages ($LLOG_COUNT)" || true
8386 }
8387 run_test 60b "limit repeated messages from CERROR/CWARN"
8388
8389 test_60c() {
8390         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8391
8392         echo "create 5000 files"
8393         createmany -o $DIR/f60c- 5000
8394 #define OBD_FAIL_MDS_LLOG_CREATE_FAILED  0x137
8395         lctl set_param fail_loc=0x80000137
8396         unlinkmany $DIR/f60c- 5000
8397         lctl set_param fail_loc=0
8398 }
8399 run_test 60c "unlink file when mds full"
8400
8401 test_60d() {
8402         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8403
8404         SAVEPRINTK=$(lctl get_param -n printk)
8405         # verify "lctl mark" is even working"
8406         MESSAGE="test message ID $RANDOM $$"
8407         $LCTL mark "$MESSAGE" || error "$LCTL mark failed"
8408         dmesg | grep -q "$MESSAGE" || error "didn't find debug marker in log"
8409
8410         lctl set_param printk=0 || error "set lnet.printk failed"
8411         lctl get_param -n printk | grep emerg || error "lnet.printk dropped emerg"
8412         MESSAGE="new test message ID $RANDOM $$"
8413         # Assume here that libcfs_debug_mark_buffer() uses D_WARNING
8414         $LCTL mark "$MESSAGE" || error "$LCTL mark failed"
8415         dmesg | grep -q "$MESSAGE" && error "D_WARNING wasn't masked" || true
8416
8417         lctl set_param -n printk="$SAVEPRINTK"
8418 }
8419 run_test 60d "test printk console message masking"
8420
8421 test_60e() {
8422         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8423         remote_mds_nodsh && skip "remote MDS with nodsh"
8424
8425         touch $DIR/$tfile
8426 #define OBD_FAIL_MDS_LLOG_CREATE_FAILED2  0x15b
8427         do_facet mds1 lctl set_param fail_loc=0x15b
8428         rm $DIR/$tfile
8429 }
8430 run_test 60e "no space while new llog is being created"
8431
8432 test_60f() {
8433         local old_path=$($LCTL get_param -n debug_path)
8434
8435         stack_trap "$LCTL set_param debug_path=$old_path"
8436         stack_trap "rm -f $TMP/$tfile*"
8437         rm -f $TMP/$tfile* 2> /dev/null
8438         #define OBD_FAIL_PTLRPC_DUMP_LOG         0x50e
8439         $LCTL set_param debug_path=$TMP/$tfile fail_loc=0x8000050e
8440         test_mkdir $DIR/$tdir
8441         # retry in case the open is cached and not released
8442         for (( i = 0; i < 100 && $(ls $TMP/$tfile* | wc -l) == 0; i++ )); do
8443                 echo $i > $DIR/$tdir/$tfile.$i && cat $DIR/$tdir/$tfile.$i
8444                 sleep 0.1
8445         done
8446         ls $TMP/$tfile*
8447         (( $(ls $TMP/$tfile* | wc -l) > 0 )) || error "$TMP/$tfile not dumped"
8448 }
8449 run_test 60f "change debug_path works"
8450
8451 test_60g() {
8452         local pid
8453         local i
8454
8455         test_mkdir -c $MDSCOUNT $DIR/$tdir
8456
8457         (
8458                 local index=0
8459                 while true; do
8460                         $LFS setdirstripe -i $(($index % $MDSCOUNT)) \
8461                                 -c $MDSCOUNT $DIR/$tdir/subdir$index \
8462                                 2>/dev/null
8463                         mkdir $DIR/$tdir/subdir$index 2>/dev/null
8464                         rmdir $DIR/$tdir/subdir$index 2>/dev/null
8465                         index=$((index + 1))
8466                 done
8467         ) &
8468
8469         pid=$!
8470
8471         for i in {0..100}; do
8472                 # define OBD_FAIL_OSD_TXN_START    0x19a
8473                 local index=$((i % MDSCOUNT + 1))
8474
8475                 do_facet mds$index $LCTL set_param fail_loc=0x8000019a \
8476                         > /dev/null
8477                 sleep 0.01
8478         done
8479
8480         kill -9 $pid
8481
8482         for i in $(seq $MDSCOUNT); do
8483                 do_facet mds$i $LCTL set_param fail_loc=0 > /dev/null
8484         done
8485
8486         mkdir $DIR/$tdir/new || error "mkdir failed"
8487         rmdir $DIR/$tdir/new || error "rmdir failed"
8488
8489         do_facet mds1 $LCTL lfsck_start -M $(facet_svc mds1) -A -C \
8490                 -t namespace
8491         for i in $(seq $MDSCOUNT); do
8492                 wait_update_facet mds$i "$LCTL get_param -n \
8493                         mdd.$(facet_svc mds$i).lfsck_namespace |
8494                         awk '/^status/ { print \\\$2 }'" "completed"
8495         done
8496
8497         ls -R $DIR/$tdir
8498         rm -rf $DIR/$tdir || error "rmdir failed"
8499 }
8500 run_test 60g "transaction abort won't cause MDT hung"
8501
8502 test_60h() {
8503         [ $MDS1_VERSION -le $(version_code 2.12.52) ] &&
8504                 skip "Need MDS version at least 2.12.52"
8505         [ $MDSCOUNT -lt 2 ] && skip "Need at least 2 MDTs"
8506
8507         local f
8508
8509         #define OBD_FAIL_MDS_STRIPE_CREATE       0x188
8510         #define OBD_FAIL_MDS_STRIPE_FID          0x189
8511         for fail_loc in 0x80000188 0x80000189; do
8512                 do_facet mds1 "$LCTL set_param fail_loc=$fail_loc"
8513                 $LFS mkdir -c $MDSCOUNT -i 0 $DIR/$tdir-$fail_loc ||
8514                         error "mkdir $dir-$fail_loc failed"
8515                 for i in {0..10}; do
8516                         # create may fail on missing stripe
8517                         echo $i > $DIR/$tdir-$fail_loc/$i
8518                 done
8519                 $LFS getdirstripe $DIR/$tdir-$fail_loc ||
8520                         error "getdirstripe $tdir-$fail_loc failed"
8521                 $LFS migrate -m 1 $DIR/$tdir-$fail_loc ||
8522                         error "migrate $tdir-$fail_loc failed"
8523                 $LFS getdirstripe $DIR/$tdir-$fail_loc ||
8524                         error "getdirstripe $tdir-$fail_loc failed"
8525                 pushd $DIR/$tdir-$fail_loc
8526                 for f in *; do
8527                         echo $f | cmp $f - || error "$f data mismatch"
8528                 done
8529                 popd
8530                 rm -rf $DIR/$tdir-$fail_loc
8531         done
8532 }
8533 run_test 60h "striped directory with missing stripes can be accessed"
8534
8535 function t60i_load() {
8536         mkdir $DIR/$tdir
8537         #define OBD_FAIL_LLOG_PAUSE_AFTER_PAD               0x131c
8538         $LCTL set_param fail_loc=0x131c fail_val=1
8539         for ((i=0; i<5000; i++)); do
8540                 touch $DIR/$tdir/f$i
8541         done
8542 }
8543
8544 test_60i() {
8545         changelog_register || error "changelog_register failed"
8546         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
8547         changelog_users $SINGLEMDS | grep -q $cl_user ||
8548                 error "User $cl_user not found in changelog_users"
8549         changelog_chmask "ALL"
8550         t60i_load &
8551         local PID=$!
8552         for((i=0; i<100; i++)); do
8553                 changelog_dump >/dev/null ||
8554                         error "can't read changelog"
8555         done
8556         kill $PID
8557         wait $PID
8558         changelog_deregister || error "changelog_deregister failed"
8559         $LCTL set_param fail_loc=0
8560 }
8561 run_test 60i "llog: new record vs reader race"
8562
8563 test_61a() {
8564         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8565
8566         f="$DIR/f61"
8567         dd if=/dev/zero of=$f bs=$PAGE_SIZE count=1 || error "dd $f failed"
8568         cancel_lru_locks osc
8569         $MULTIOP $f OSMWUc || error "$MULTIOP $f failed"
8570         sync
8571 }
8572 run_test 61a "mmap() writes don't make sync hang ================"
8573
8574 test_61b() {
8575         mmap_mknod_test $DIR/$tfile || error "mmap_mknod_test failed"
8576 }
8577 run_test 61b "mmap() of unstriped file is successful"
8578
8579 # bug 2330 - insufficient obd_match error checking causes LBUG
8580 test_62() {
8581         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8582
8583         f="$DIR/f62"
8584         echo foo > $f
8585         cancel_lru_locks osc
8586         lctl set_param fail_loc=0x405
8587         cat $f && error "cat succeeded, expect -EIO"
8588         lctl set_param fail_loc=0
8589 }
8590 # This test is now irrelevant (as of bug 10718 inclusion), we no longer
8591 # match every page all of the time.
8592 #run_test 62 "verify obd_match failure doesn't LBUG (should -EIO)"
8593
8594 # bug 2319 - oig_wait() interrupted causes crash because of invalid waitq.
8595 # Though this test is irrelevant anymore, it helped to reveal some
8596 # other grant bugs (LU-4482), let's keep it.
8597 test_63a() {   # was test_63
8598         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8599
8600         MAX_DIRTY_MB=$(lctl get_param -n osc.*.max_dirty_mb | head -n 1)
8601
8602         for i in `seq 10` ; do
8603                 dd if=/dev/zero of=$DIR/f63 bs=8k &
8604                 sleep 5
8605                 kill $!
8606                 sleep 1
8607         done
8608
8609         rm -f $DIR/f63 || true
8610 }
8611 run_test 63a "Verify oig_wait interruption does not crash ======="
8612
8613 # bug 2248 - async write errors didn't return to application on sync
8614 # bug 3677 - async write errors left page locked
8615 test_63b() {
8616         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8617
8618         debugsave
8619         lctl set_param debug=-1
8620
8621         # ensure we have a grant to do async writes
8622         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1
8623         rm $DIR/$tfile
8624
8625         sync    # sync lest earlier test intercept the fail_loc
8626
8627         #define OBD_FAIL_OSC_BRW_PREP_REQ        0x406
8628         lctl set_param fail_loc=0x80000406
8629         $MULTIOP $DIR/$tfile Owy && \
8630                 error "sync didn't return ENOMEM"
8631         sync; sleep 2; sync     # do a real sync this time to flush page
8632         lctl get_param -n llite.*.dump_page_cache | grep locked && \
8633                 error "locked page left in cache after async error" || true
8634         debugrestore
8635 }
8636 run_test 63b "async write errors should be returned to fsync ==="
8637
8638 test_64a () {
8639         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8640
8641         lfs df $DIR
8642         lctl get_param osc.*[oO][sS][cC][_-]*.cur* | grep "=[1-9]"
8643 }
8644 run_test 64a "verify filter grant calculations (in kernel) ====="
8645
8646 test_64b () {
8647         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8648
8649         bash oos.sh $MOUNT || error "oos.sh failed: $?"
8650 }
8651 run_test 64b "check out-of-space detection on client"
8652
8653 test_64c() {
8654         $LCTL set_param osc.*OST0000-osc-[^mM]*.cur_grant_bytes=0
8655 }
8656 run_test 64c "verify grant shrink"
8657
8658 import_param() {
8659         local tgt=$1
8660         local param=$2
8661
8662         $LCTL get_param osc.$tgt.import | awk "/$param/ { print \$2 }"
8663 }
8664
8665 # this does exactly what osc_request.c:osc_announce_cached() does in
8666 # order to calculate max amount of grants to ask from server
8667 want_grant() {
8668         local tgt=$1
8669
8670         local nrpages=$($LCTL get_param -n osc.$tgt.max_pages_per_rpc)
8671         local rpc_in_flight=$($LCTL get_param -n osc.$tgt.max_rpcs_in_flight)
8672
8673         ((rpc_in_flight++));
8674         nrpages=$((nrpages * rpc_in_flight))
8675
8676         local dirty_max_pages=$($LCTL get_param -n osc.$tgt.max_dirty_mb)
8677
8678         dirty_max_pages=$((dirty_max_pages * 1024 * 1024 / PAGE_SIZE))
8679
8680         [[ $dirty_max_pages -gt $nrpages ]] && nrpages=$dirty_max_pages
8681         local undirty=$((nrpages * PAGE_SIZE))
8682
8683         local max_extent_pages
8684         max_extent_pages=$(import_param $tgt grant_max_extent_size)
8685         max_extent_pages=$((max_extent_pages / PAGE_SIZE))
8686         local nrextents=$(((nrpages + max_extent_pages - 1) / max_extent_pages))
8687         local grant_extent_tax
8688         grant_extent_tax=$(import_param $tgt grant_extent_tax)
8689
8690         undirty=$((undirty + nrextents * grant_extent_tax))
8691
8692         echo $undirty
8693 }
8694
8695 # this is size of unit for grant allocation. It should be equal to
8696 # what tgt_grant.c:tgt_grant_chunk() calculates
8697 grant_chunk() {
8698         local tgt=$1
8699         local max_brw_size
8700         local grant_extent_tax
8701
8702         max_brw_size=$(import_param $tgt max_brw_size)
8703
8704         grant_extent_tax=$(import_param $tgt grant_extent_tax)
8705
8706         echo $(((max_brw_size + grant_extent_tax) * 2))
8707 }
8708
8709 test_64d() {
8710         [ $OST1_VERSION -ge $(version_code 2.10.56) ] ||
8711                 skip "OST < 2.10.55 doesn't limit grants enough"
8712
8713         local tgt=$($LCTL dl | awk '/OST0000-osc-[^mM]/ { print $4 }')
8714
8715         [[ "$($LCTL get_param osc.${tgt}.import)" =~ "grant_param" ]] ||
8716                 skip "no grant_param connect flag"
8717
8718         local olddebug="$($LCTL get_param -n debug 2> /dev/null)"
8719
8720         $LCTL set_param -n -n debug="$OLDDEBUG" || true
8721         stack_trap "$LCTL set_param -n debug='$olddebug'" EXIT
8722
8723
8724         local max_cur_granted=$(($(want_grant $tgt) + $(grant_chunk $tgt)))
8725         stack_trap "rm -f $DIR/$tfile && wait_delete_completed" EXIT
8726
8727         $LFS setstripe $DIR/$tfile -i 0 -c 1
8728         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1000 &
8729         ddpid=$!
8730
8731         while kill -0 $ddpid; do
8732                 local cur_grant=$($LCTL get_param -n osc.$tgt.cur_grant_bytes)
8733
8734                 if [[ $cur_grant -gt $max_cur_granted ]]; then
8735                         kill $ddpid
8736                         error "cur_grant $cur_grant > $max_cur_granted"
8737                 fi
8738
8739                 sleep 1
8740         done
8741 }
8742 run_test 64d "check grant limit exceed"
8743
8744 check_grants() {
8745         local tgt=$1
8746         local expected=$2
8747         local msg=$3
8748         local cur_grants=$($LCTL get_param -n osc.$tgt.cur_grant_bytes)
8749
8750         ((cur_grants == expected)) ||
8751                 error "$msg: grants mismatch: $cur_grants, expected $expected"
8752 }
8753
8754 round_up_p2() {
8755         echo $((($1 + $2 - 1) & ~($2 - 1)))
8756 }
8757
8758 test_64e() {
8759         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8760         [ $OST1_VERSION -ge $(version_code 2.11.56) ] ||
8761                 skip "Need OSS version at least 2.11.56"
8762
8763         # Remount client to reset grant
8764         remount_client $MOUNT || error "failed to remount client"
8765         local osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
8766
8767         local init_grants=$(import_param $osc_tgt initial_grant)
8768
8769         check_grants $osc_tgt $init_grants "init grants"
8770
8771         local extent_tax=$(import_param $osc_tgt grant_extent_tax)
8772         local max_brw_size=$(import_param $osc_tgt max_brw_size)
8773         local gbs=$(import_param $osc_tgt grant_block_size)
8774
8775         # write random number of bytes from max_brw_size / 4 to max_brw_size
8776         local write_bytes=$(shuf -i $((max_brw_size / 4))-$max_brw_size -n 1)
8777         # align for direct io
8778         write_bytes=$(round_up_p2 $write_bytes PAGE_SIZE)
8779         # round to grant consumption unit
8780         local wb_round_up=$(round_up_p2 $write_bytes gbs)
8781
8782         local grants=$((wb_round_up + extent_tax))
8783
8784         $LFS setstripe -c 1 -i 0 $DIR/$tfile  || error "lfs setstripe failed"
8785
8786         # define OBD_FAIL_TGT_NO_GRANT 0x725
8787         # make the server not grant more back
8788         do_facet ost1 $LCTL set_param fail_loc=0x725
8789         dd if=/dev/zero of=$DIR/$tfile bs=$write_bytes count=1 oflag=direct
8790
8791         do_facet ost1 $LCTL set_param fail_loc=0
8792
8793         check_grants $osc_tgt $((init_grants - grants)) "dio w/o grant alloc"
8794
8795         rm -f $DIR/$tfile || error "rm failed"
8796
8797         # Remount client to reset grant
8798         remount_client $MOUNT || error "failed to remount client"
8799         osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
8800
8801         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "lfs setstripe failed"
8802
8803         # define OBD_FAIL_TGT_NO_GRANT 0x725
8804         # make the server not grant more back
8805         do_facet ost1 $LCTL set_param fail_loc=0x725
8806         $MULTIOP $DIR/$tfile "oO_WRONLY:w${write_bytes}yc"
8807         do_facet ost1 $LCTL set_param fail_loc=0
8808
8809         check_grants $osc_tgt $((init_grants - grants)) "buf io w/o grant alloc"
8810 }
8811 run_test 64e "check grant consumption (no grant allocation)"
8812
8813 test_64f() {
8814         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8815
8816         # Remount client to reset grant
8817         remount_client $MOUNT || error "failed to remount client"
8818         local osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
8819
8820         local init_grants=$(import_param $osc_tgt initial_grant)
8821         local extent_tax=$(import_param $osc_tgt grant_extent_tax)
8822         local max_brw_size=$(import_param $osc_tgt max_brw_size)
8823         local gbs=$(import_param $osc_tgt grant_block_size)
8824         local chunk=$(grant_chunk $osc_tgt)
8825
8826         # write random number of bytes from max_brw_size / 4 to max_brw_size
8827         local write_bytes=$(shuf -i $((max_brw_size / 4))-$max_brw_size -n 1)
8828         # align for direct io
8829         write_bytes=$(round_up_p2 $write_bytes PAGE_SIZE)
8830         # round to grant consumption unit
8831         local wb_round_up=$(round_up_p2 $write_bytes gbs)
8832
8833         local grants=$((wb_round_up + extent_tax))
8834
8835         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "lfs setstripe failed"
8836         dd if=/dev/zero of=$DIR/$tfile bs=$write_bytes count=1 oflag=direct ||
8837                 error "error writing to $DIR/$tfile"
8838
8839         check_grants $osc_tgt $((init_grants - grants + chunk)) \
8840                 "direct io with grant allocation"
8841
8842         rm -f $DIR/$tfile || error "rm failed"
8843
8844         # Remount client to reset grant
8845         remount_client $MOUNT || error "failed to remount client"
8846         osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
8847
8848         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "lfs setstripe failed"
8849
8850         local cmd="oO_WRONLY:w${write_bytes}_yc"
8851
8852         $MULTIOP $DIR/$tfile $cmd &
8853         MULTIPID=$!
8854         sleep 1
8855
8856         check_grants $osc_tgt $((init_grants - grants)) \
8857                 "buffered io, not write rpc"
8858
8859         kill -USR1 $MULTIPID
8860         wait
8861
8862         check_grants $osc_tgt $((init_grants - grants + chunk)) \
8863                 "buffered io, one RPC"
8864 }
8865 run_test 64f "check grant consumption (with grant allocation)"
8866
8867 test_64g() {
8868         #[ $MDS1_VERSION -lt $(version_code 2.14.54) ] &&
8869         #       skip "Need MDS version at least 2.14.54"
8870
8871         local mdts=$(comma_list $(mdts_nodes))
8872
8873         local old=$($LCTL get_param mdc.$FSNAME-*.grant_shrink_interval |
8874                         tr '\n' ' ')
8875         stack_trap "$LCTL set_param $old"
8876
8877         # generate dirty pages and increase dirty granted on MDT
8878         stack_trap "rm -f $DIR/$tfile-*"
8879         for (( i = 0; i < 10; i++)); do
8880                 $LFS setstripe -E 1M -L mdt $DIR/$tfile-$i ||
8881                         error "can't set stripe"
8882                 dd if=/dev/zero of=$DIR/$tfile-$i bs=128k count=1 ||
8883                         error "can't dd"
8884                 $LFS getstripe $DIR/$tfile-$i | grep -q pattern.*mdt || {
8885                         $LFS getstripe $DIR/$tfile-$i
8886                         error "not DoM file"
8887                 }
8888         done
8889
8890         # flush dirty pages
8891         sync
8892
8893         # wait until grant shrink reset grant dirty on MDTs
8894         for ((i = 0; i < 120; i++)); do
8895                 grant_dirty=$(do_nodes $mdts $LCTL get_param -n  mdt.*.tot_dirty |
8896                         awk '{sum=sum+$1} END {print sum}')
8897                 vm_dirty=$(awk '/Dirty:/{print $2}' /proc/meminfo)
8898                 echo "$grant_dirty grants, $vm_dirty pages"
8899                 (( grant_dirty + vm_dirty == 0 )) && break
8900                 (( i == 3 )) && sync &&
8901                         $LCTL set_param mdc.$FSNAME-*.grant_shrink_interval=5
8902                 sleep 1
8903         done
8904
8905         grant_dirty=$(do_nodes $mdts $LCTL get_param -n  mdt.*.tot_dirty |
8906                 awk '{sum=sum+$1} END {print sum}')
8907         (( grant_dirty == 0 )) || error "$grant_dirty on MDT"
8908 }
8909 run_test 64g "grant shrink on MDT"
8910
8911 test_64h() {
8912         local instance=$($LFS getname -i $DIR)
8913         local osc_tgt="$FSNAME-OST0000-osc-$instance"
8914         local num_exps=$(do_facet ost1 \
8915             $LCTL get_param -n obdfilter.*OST0000*.num_exports)
8916         local max_brw_size=$(import_param $osc_tgt max_brw_size)
8917         local avail=$($LCTL get_param -n osc.*OST0000-osc-$instance.kbytesavail)
8918         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
8919
8920         # 10MiB is for file to be written, max_brw_size * 16 *
8921         # num_exps is space reserve so that tgt_grant_shrink() decided
8922         # to not shrink
8923         local expect=$((max_brw_size * 16 * num_exps + 10 * 1048576))
8924         (( avail * 1024 < expect )) &&
8925                 skip "need $expect bytes on ost1, have $(( avail * 1024 )) only"
8926
8927         save_lustre_params client "osc.*OST0000*.grant_shrink" > $p
8928         save_lustre_params client "osc.*OST0000*.grant_shrink_interval" >> $p
8929         stack_trap "restore_lustre_params < $p; rm -f $save" EXIT
8930         $LCTL set_param osc.*OST0000*.grant_shrink=1
8931         $LCTL set_param osc.*OST0000*.grant_shrink_interval=10
8932
8933         $LFS setstripe -c 1 -i 0 $DIR/$tfile
8934         dd if=/dev/zero of=$DIR/$tfile bs=1M count=10 oflag=sync
8935
8936         # drop cache so that coming read would do rpc
8937         cancel_lru_locks osc
8938
8939         # shrink interval is set to 10, pause for 7 seconds so that
8940         # grant thread did not wake up yet but coming read entered
8941         # shrink mode for rpc (osc_should_shrink_grant())
8942         sleep 7
8943
8944         declare -a cur_grant_bytes
8945         declare -a tot_granted
8946         cur_grant_bytes[0]=$($LCTL get_param -n osc.*OST0000*.cur_grant_bytes)
8947         tot_granted[0]=$(do_facet ost1 \
8948             $LCTL get_param -n obdfilter.*OST0000*.tot_granted)
8949
8950         dd if=$DIR/$tfile bs=4K count=1 of=/dev/null
8951
8952         cur_grant_bytes[1]=$($LCTL get_param -n osc.*OST0000*.cur_grant_bytes)
8953         tot_granted[1]=$(do_facet ost1 \
8954             $LCTL get_param -n obdfilter.*OST0000*.tot_granted)
8955
8956         # grant change should be equal on both sides
8957         (( cur_grant_bytes[0] - cur_grant_bytes[1] ==
8958                 tot_granted[0] - tot_granted[1])) ||
8959                 error "grant change mismatch, "                                \
8960                         "server: ${tot_granted[0]} to ${tot_granted[1]}, "     \
8961                         "client: ${cur_grant_bytes[0]} to ${cur_grant_bytes[1]}"
8962 }
8963 run_test 64h "grant shrink on read"
8964
8965 test_64i() {
8966         (( $OST1_VERSION >= $(version_code 2.14.55) )) ||
8967                 skip "need OST at least 2.14.55 to avoid grant shrink on replay"
8968
8969         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8970         remote_ost_nodsh && skip "remote OSTs with nodsh"
8971
8972         $LFS setstripe -c 1 -i 0 $DIR/$tfile
8973
8974         dd if=/dev/zero of=$DIR/$tfile bs=1M count=64
8975
8976         # lustre-ffff9fc75e850800 /mnt/lustre -> ffff9fc75e850800
8977         local instance=$($LFS getname -i $DIR)
8978
8979         local osc_tgt="$FSNAME-OST0000-osc-$instance"
8980         local cgb=$($LCTL get_param -n osc.$osc_tgt.cur_grant_bytes)
8981
8982         # shrink grants and simulate rpc loss
8983         #define OBD_FAIL_PTLRPC_DROP_REQ_OPC     0x513
8984         do_facet ost1 "$LCTL set_param fail_loc=0x80000513 fail_val=17"
8985         $LCTL set_param osc.$osc_tgt.cur_grant_bytes=$((cgb/2))B
8986
8987         fail ost1
8988
8989         dd if=/dev/zero of=$DIR/$tfile oflag=append bs=1M count=8 conv=notrunc
8990
8991         local testid=$(echo $TESTNAME | tr '_' ' ')
8992
8993         do_facet ost1 dmesg | tac | sed "/$testid/,$ d" |
8994                 grep "GRANT, real grant" &&
8995                 error "client has more grants then it owns" || true
8996 }
8997 run_test 64i "shrink on reconnect"
8998
8999 # bug 1414 - set/get directories' stripe info
9000 test_65a() {
9001         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9002
9003         test_mkdir $DIR/$tdir
9004         touch $DIR/$tdir/f1
9005         $LVERIFY $DIR/$tdir $DIR/$tdir/f1 || error "lverify failed"
9006 }
9007 run_test 65a "directory with no stripe info"
9008
9009 test_65b() {
9010         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9011
9012         test_mkdir $DIR/$tdir
9013         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
9014
9015         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
9016                                                 error "setstripe"
9017         touch $DIR/$tdir/f2
9018         $LVERIFY $DIR/$tdir $DIR/$tdir/f2 || error "lverify failed"
9019 }
9020 run_test 65b "directory setstripe -S stripe_size*2 -i 0 -c 1"
9021
9022 test_65c() {
9023         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9024         [ $OSTCOUNT -lt 2 ] && skip_env "need at least 2 OSTs"
9025
9026         test_mkdir $DIR/$tdir
9027         local stripesize=$($LFS getstripe -S $DIR/$tdir)
9028
9029         $LFS setstripe -S $((stripesize * 4)) -i 1 \
9030                 -c $((OSTCOUNT - 1)) $DIR/$tdir || error "setstripe"
9031         touch $DIR/$tdir/f3
9032         $LVERIFY $DIR/$tdir $DIR/$tdir/f3 || error "lverify failed"
9033 }
9034 run_test 65c "directory setstripe -S stripe_size*4 -i 1 -c $((OSTCOUNT-1))"
9035
9036 test_65d() {
9037         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9038
9039         test_mkdir $DIR/$tdir
9040         local STRIPECOUNT=$($LFS getstripe -c $DIR/$tdir)
9041         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
9042
9043         if [[ $STRIPECOUNT -le 0 ]]; then
9044                 sc=1
9045         elif [[ $STRIPECOUNT -gt $LOV_MAX_STRIPE_COUNT ]]; then
9046                 [[ $OSTCOUNT -gt $LOV_MAX_STRIPE_COUNT ]] &&
9047                         sc=$LOV_MAX_STRIPE_COUNT || sc=$(($OSTCOUNT - 1))
9048         else
9049                 sc=$(($STRIPECOUNT - 1))
9050         fi
9051         $LFS setstripe -S $STRIPESIZE -c $sc $DIR/$tdir || error "setstripe"
9052         touch $DIR/$tdir/f4 $DIR/$tdir/f5
9053         $LVERIFY $DIR/$tdir $DIR/$tdir/f4 $DIR/$tdir/f5 ||
9054                 error "lverify failed"
9055 }
9056 run_test 65d "directory setstripe -S stripe_size -c stripe_count"
9057
9058 test_65e() {
9059         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9060
9061         test_mkdir $DIR/$tdir
9062
9063         $LFS setstripe $DIR/$tdir || error "setstripe"
9064         $LFS getstripe -v $DIR/$tdir | grep "Default" ||
9065                                         error "no stripe info failed"
9066         touch $DIR/$tdir/f6
9067         $LVERIFY $DIR/$tdir $DIR/$tdir/f6 || error "lverify failed"
9068 }
9069 run_test 65e "directory setstripe defaults"
9070
9071 test_65f() {
9072         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9073
9074         test_mkdir $DIR/${tdir}f
9075         $RUNAS $LFS setstripe $DIR/${tdir}f &&
9076                 error "setstripe succeeded" || true
9077 }
9078 run_test 65f "dir setstripe permission (should return error) ==="
9079
9080 test_65g() {
9081         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9082
9083         test_mkdir $DIR/$tdir
9084         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
9085
9086         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
9087                 error "setstripe -S failed"
9088         $LFS setstripe -d $DIR/$tdir || error "setstripe -d failed"
9089         $LFS getstripe -v $DIR/$tdir | grep "Default" ||
9090                 error "delete default stripe failed"
9091 }
9092 run_test 65g "directory setstripe -d"
9093
9094 test_65h() {
9095         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9096
9097         test_mkdir $DIR/$tdir
9098         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
9099
9100         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
9101                 error "setstripe -S failed"
9102         test_mkdir $DIR/$tdir/dd1
9103         [ $($LFS getstripe -c $DIR/$tdir) = $($LFS getstripe -c $DIR/$tdir/dd1) ] ||
9104                 error "stripe info inherit failed"
9105 }
9106 run_test 65h "directory stripe info inherit ===================="
9107
9108 test_65i() {
9109         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9110
9111         save_layout_restore_at_exit $MOUNT
9112
9113         # bug6367: set non-default striping on root directory
9114         $LFS setstripe -S 65536 -c -1 $MOUNT || error "error setting stripe"
9115
9116         # bug12836: getstripe on -1 default directory striping
9117         $LFS getstripe $MOUNT || error "getstripe $MOUNT failed"
9118
9119         # bug12836: getstripe -v on -1 default directory striping
9120         $LFS getstripe -v $MOUNT || error "getstripe -v $MOUNT failed"
9121
9122         # bug12836: new find on -1 default directory striping
9123         $LFS find -mtime -1 $MOUNT > /dev/null || error "find $MOUNT failed"
9124 }
9125 run_test 65i "various tests to set root directory striping"
9126
9127 test_65j() { # bug6367
9128         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9129
9130         sync; sleep 1
9131
9132         # if we aren't already remounting for each test, do so for this test
9133         if [ "$I_MOUNTED" = "yes" ]; then
9134                 cleanup || error "failed to unmount"
9135                 setup
9136         fi
9137
9138         save_layout_restore_at_exit $MOUNT
9139
9140         $LFS setstripe -d $MOUNT || error "setstripe failed"
9141 }
9142 run_test 65j "set default striping on root directory (bug 6367)="
9143
9144 cleanup_65k() {
9145         rm -rf $DIR/$tdir
9146         wait_delete_completed
9147         do_facet $SINGLEMDS "lctl set_param -n \
9148                 osp.$ost*MDT0000.max_create_count=$max_count"
9149         do_facet $SINGLEMDS "lctl set_param -n \
9150                 osp.$ost*MDT0000.create_count=$count"
9151         do_facet $SINGLEMDS lctl --device  %$INACTIVE_OSC activate
9152         echo $INACTIVE_OSC "is Activate"
9153
9154         wait_osc_import_state mds ost$(( ostnum + 1 )) FULL
9155 }
9156
9157 test_65k() { # bug11679
9158         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9159         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
9160         remote_mds_nodsh && skip "remote MDS with nodsh"
9161
9162         local disable_precreate=true
9163         [ $MDS1_VERSION -le $(version_code 2.8.54) ] &&
9164                 disable_precreate=false
9165
9166         echo "Check OST status: "
9167         local MDS_OSCS=$(do_facet $SINGLEMDS lctl dl |
9168                 awk '/[oO][sS][cC].*md[ts]/ { print $4 }')
9169
9170         for OSC in $MDS_OSCS; do
9171                 echo $OSC "is active"
9172                 do_facet $SINGLEMDS lctl --device %$OSC activate
9173         done
9174
9175         for INACTIVE_OSC in $MDS_OSCS; do
9176                 local ost=$(osc_to_ost $INACTIVE_OSC)
9177                 local ostnum=$(do_facet $SINGLEMDS lctl get_param -n \
9178                                lov.*md*.target_obd |
9179                                awk -F: /$ost/'{ print $1 }' | head -n 1)
9180
9181                 mkdir -p $DIR/$tdir
9182                 $LFS setstripe -i $ostnum -c 1 $DIR/$tdir
9183                 createmany -o $DIR/$tdir/$tfile.$ostnum. 1000
9184
9185                 echo "Deactivate: " $INACTIVE_OSC
9186                 do_facet $SINGLEMDS lctl --device %$INACTIVE_OSC deactivate
9187
9188                 local count=$(do_facet $SINGLEMDS "lctl get_param -n \
9189                               osp.$ost*MDT0000.create_count")
9190                 local max_count=$(do_facet $SINGLEMDS "lctl get_param -n \
9191                                   osp.$ost*MDT0000.max_create_count")
9192                 $disable_precreate &&
9193                         do_facet $SINGLEMDS "lctl set_param -n \
9194                                 osp.$ost*MDT0000.max_create_count=0"
9195
9196                 for idx in $(seq 0 $((OSTCOUNT - 1))); do
9197                         [ -f $DIR/$tdir/$idx ] && continue
9198                         echo "$LFS setstripe -i $idx -c 1 $DIR/$tdir/$idx"
9199                         $LFS setstripe -i $idx -c 1 $DIR/$tdir/$idx ||
9200                                 { cleanup_65k;
9201                                   error "setstripe $idx should succeed"; }
9202                         rm -f $DIR/$tdir/$idx || error "rm $idx failed"
9203                 done
9204                 unlinkmany $DIR/$tdir/$tfile.$ostnum. 1000
9205                 rmdir $DIR/$tdir
9206
9207                 do_facet $SINGLEMDS "lctl set_param -n \
9208                         osp.$ost*MDT0000.max_create_count=$max_count"
9209                 do_facet $SINGLEMDS "lctl set_param -n \
9210                         osp.$ost*MDT0000.create_count=$count"
9211                 do_facet $SINGLEMDS lctl --device  %$INACTIVE_OSC activate
9212                 echo $INACTIVE_OSC "is Activate"
9213
9214                 wait_osc_import_state mds ost$(( ostnum + 1 )) FULL
9215         done
9216 }
9217 run_test 65k "validate manual striping works properly with deactivated OSCs"
9218
9219 test_65l() { # bug 12836
9220         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9221
9222         test_mkdir -p $DIR/$tdir/test_dir
9223         $LFS setstripe -c -1 $DIR/$tdir/test_dir
9224         $LFS find -mtime -1 $DIR/$tdir >/dev/null
9225 }
9226 run_test 65l "lfs find on -1 stripe dir ========================"
9227
9228 test_65m() {
9229         local layout=$(save_layout $MOUNT)
9230         $RUNAS $LFS setstripe -c 2 $MOUNT && {
9231                 restore_layout $MOUNT $layout
9232                 error "setstripe should fail by non-root users"
9233         }
9234         true
9235 }
9236 run_test 65m "normal user can't set filesystem default stripe"
9237
9238 test_65n() {
9239         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
9240         [[ $MDS1_VERSION -ge $(version_code 2.12.50) ]] ||
9241                 skip "Need MDS version at least 2.12.50"
9242         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
9243
9244         [[ $OSTCOUNT -ge 2 ]] || skip_env "needs >= 2 OSTs"
9245         which getfattr > /dev/null 2>&1 || skip_env "no getfattr command"
9246         which setfattr > /dev/null 2>&1 || skip_env "no setfattr command"
9247
9248         save_layout_restore_at_exit $MOUNT
9249
9250         # new subdirectory under root directory should not inherit
9251         # the default layout from root
9252         local dir1=$MOUNT/$tdir-1
9253         mkdir $dir1 || error "mkdir $dir1 failed"
9254         ! getfattr -n trusted.lov $dir1 &> /dev/null ||
9255                 error "$dir1 shouldn't have LOV EA"
9256
9257         # delete the default layout on root directory
9258         $LFS setstripe -d $MOUNT || error "delete root default layout failed"
9259
9260         local dir2=$MOUNT/$tdir-2
9261         mkdir $dir2 || error "mkdir $dir2 failed"
9262         ! getfattr -n trusted.lov $dir2 &> /dev/null ||
9263                 error "$dir2 shouldn't have LOV EA"
9264
9265         # set a new striping pattern on root directory
9266         local def_stripe_size=$($LFS getstripe -S $MOUNT)
9267         local new_def_stripe_size=$((def_stripe_size * 2))
9268         $LFS setstripe -S $new_def_stripe_size $MOUNT ||
9269                 error "set stripe size on $MOUNT failed"
9270
9271         # new file created in $dir2 should inherit the new stripe size from
9272         # the filesystem default
9273         local file2=$dir2/$tfile-2
9274         touch $file2 || error "touch $file2 failed"
9275
9276         local file2_stripe_size=$($LFS getstripe -S $file2)
9277         [[ $file2_stripe_size -eq $new_def_stripe_size ]] ||
9278         {
9279                 echo "file2_stripe_size: '$file2_stripe_size'"
9280                 echo "new_def_stripe_size: '$new_def_stripe_size'"
9281                 error "$file2 didn't inherit stripe size $new_def_stripe_size"
9282         }
9283
9284         local dir3=$MOUNT/$tdir-3
9285         mkdir $dir3 || error "mkdir $dir3 failed"
9286         # $dir3 shouldn't have LOV EA, but "lfs getstripe -d $dir3" should show
9287         # the root layout, which is the actual default layout that will be used
9288         # when new files are created in $dir3.
9289         local dir3_layout=$(get_layout_param $dir3)
9290         local root_dir_layout=$(get_layout_param $MOUNT)
9291         [[ "$dir3_layout" = "$root_dir_layout" ]] ||
9292         {
9293                 echo "dir3_layout: '$dir3_layout'"
9294                 echo "root_dir_layout: '$root_dir_layout'"
9295                 error "$dir3 should show the default layout from $MOUNT"
9296         }
9297
9298         # set OST pool on root directory
9299         local pool=$TESTNAME
9300         pool_add $pool || error "add $pool failed"
9301         pool_add_targets $pool 0 $((OSTCOUNT - 1)) 1 ||
9302                 error "add targets to $pool failed"
9303
9304         $LFS setstripe -p $pool $MOUNT ||
9305                 error "set OST pool on $MOUNT failed"
9306
9307         # new file created in $dir3 should inherit the pool from
9308         # the filesystem default
9309         local file3=$dir3/$tfile-3
9310         touch $file3 || error "touch $file3 failed"
9311
9312         local file3_pool=$($LFS getstripe -p $file3)
9313         [[ "$file3_pool" = "$pool" ]] ||
9314                 error "$file3 ('$file3_pool') didn't inherit OST pool '$pool'"
9315
9316         local dir4=$MOUNT/$tdir-4
9317         mkdir $dir4 || error "mkdir $dir4 failed"
9318         local dir4_layout=$(get_layout_param $dir4)
9319         root_dir_layout=$(get_layout_param $MOUNT)
9320         echo "$LFS getstripe -d $dir4"
9321         $LFS getstripe -d $dir4
9322         echo "$LFS getstripe -d $MOUNT"
9323         $LFS getstripe -d $MOUNT
9324         [[ "$dir4_layout" = "$root_dir_layout" ]] ||
9325         {
9326                 echo "dir4_layout: '$dir4_layout'"
9327                 echo "root_dir_layout: '$root_dir_layout'"
9328                 error "$dir4 should show the default layout from $MOUNT"
9329         }
9330
9331         # new file created in $dir4 should inherit the pool from
9332         # the filesystem default
9333         local file4=$dir4/$tfile-4
9334         touch $file4 || error "touch $file4 failed"
9335
9336         local file4_pool=$($LFS getstripe -p $file4)
9337         [[ "$file4_pool" = "$pool" ]] ||
9338                 error "$file4 ('$file4_pool') didn't inherit OST pool $pool"
9339
9340         # new subdirectory under non-root directory should inherit
9341         # the default layout from its parent directory
9342         $LFS setstripe -S $new_def_stripe_size -p $pool $dir4 ||
9343                 error "set directory layout on $dir4 failed"
9344
9345         local dir5=$dir4/$tdir-5
9346         mkdir $dir5 || error "mkdir $dir5 failed"
9347
9348         dir4_layout=$(get_layout_param $dir4)
9349         local dir5_layout=$(get_layout_param $dir5)
9350         [[ "$dir4_layout" = "$dir5_layout" ]] ||
9351         {
9352                 echo "dir4_layout: '$dir4_layout'"
9353                 echo "dir5_layout: '$dir5_layout'"
9354                 error "$dir5 should inherit the default layout from $dir4"
9355         }
9356
9357         # though subdir under ROOT doesn't inherit default layout, but
9358         # its sub dir/file should be created with default layout.
9359         [[ $MDSCOUNT -ge 2 ]] || skip_env "needs >= 2 MDTs"
9360         [[ $MDS1_VERSION -ge $(version_code 2.12.59) ]] ||
9361                 skip "Need MDS version at least 2.12.59"
9362
9363         local default_lmv_count=$($LFS getdirstripe -D -c $MOUNT)
9364         local default_lmv_index=$($LFS getdirstripe -D -i $MOUNT)
9365         local default_lmv_hash=$($LFS getdirstripe -D -H $MOUNT)
9366
9367         if [ $default_lmv_hash == "none" ]; then
9368                 stack_trap "$LFS setdirstripe -D -d $MOUNT" EXIT
9369         else
9370                 stack_trap "$LFS setdirstripe -D -i $default_lmv_index \
9371                         -c $default_lmv_count -H $default_lmv_hash $MOUNT" EXIT
9372         fi
9373
9374         $LFS setdirstripe -D -c 2 $MOUNT ||
9375                 error "setdirstripe -D -c 2 failed"
9376         mkdir $MOUNT/$tdir-6 || error "mkdir $tdir-6 failed"
9377         local lmv_count=$($LFS getdirstripe -c $MOUNT/$tdir-6)
9378         [ $lmv_count -eq 2 ] || error "$tdir-6 stripe count $lmv_count"
9379 }
9380 run_test 65n "don't inherit default layout from root for new subdirectories"
9381
9382 # bug 2543 - update blocks count on client
9383 test_66() {
9384         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9385
9386         COUNT=${COUNT:-8}
9387         dd if=/dev/zero of=$DIR/f66 bs=1k count=$COUNT
9388         sync; sync_all_data; sync; sync_all_data
9389         cancel_lru_locks osc
9390         BLOCKS=`ls -s $DIR/f66 | awk '{ print $1 }'`
9391         [ $BLOCKS -ge $COUNT ] || error "$DIR/f66 blocks $BLOCKS < $COUNT"
9392 }
9393 run_test 66 "update inode blocks count on client ==============="
9394
9395 meminfo() {
9396         awk '($1 == "'$1':") { print $2 }' /proc/meminfo
9397 }
9398
9399 swap_used() {
9400         swapon -s | awk '($1 == "'$1'") { print $4 }'
9401 }
9402
9403 # bug5265, obdfilter oa2dentry return -ENOENT
9404 # #define OBD_FAIL_SRV_ENOENT 0x217
9405 test_69() {
9406         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9407         remote_ost_nodsh && skip "remote OST with nodsh"
9408
9409         f="$DIR/$tfile"
9410         $LFS setstripe -c 1 -i 0 $f
9411
9412         $DIRECTIO write ${f}.2 0 1 || error "directio write error"
9413
9414         do_facet ost1 lctl set_param fail_loc=0x217
9415         $TRUNCATE $f 1 # vmtruncate() will ignore truncate() error.
9416         $DIRECTIO write $f 0 2 && error "write succeeded, expect -ENOENT"
9417
9418         do_facet ost1 lctl set_param fail_loc=0
9419         $DIRECTIO write $f 0 2 || error "write error"
9420
9421         cancel_lru_locks osc
9422         $DIRECTIO read $f 0 1 || error "read error"
9423
9424         do_facet ost1 lctl set_param fail_loc=0x217
9425         $DIRECTIO read $f 1 1 && error "read succeeded, expect -ENOENT"
9426
9427         do_facet ost1 lctl set_param fail_loc=0
9428         rm -f $f
9429 }
9430 run_test 69 "verify oa2dentry return -ENOENT doesn't LBUG ======"
9431
9432 test_71() {
9433         test_mkdir $DIR/$tdir
9434         $LFS setdirstripe -D -c$MDSCOUNT $DIR/$tdir
9435         bash rundbench -C -D $DIR/$tdir 2 || error "dbench failed!"
9436 }
9437 run_test 71 "Running dbench on lustre (don't segment fault) ===="
9438
9439 test_72a() { # bug 5695 - Test that on 2.6 remove_suid works properly
9440         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9441         [ "$RUNAS_ID" = "$UID" ] &&
9442                 skip_env "RUNAS_ID = UID = $UID -- skipping"
9443         # Check that testing environment is properly set up. Skip if not
9444         FAIL_ON_ERROR=false check_runas_id_ret $RUNAS_ID $RUNAS_GID $RUNAS ||
9445                 skip_env "User $RUNAS_ID does not exist - skipping"
9446
9447         touch $DIR/$tfile
9448         chmod 777 $DIR/$tfile
9449         chmod ug+s $DIR/$tfile
9450         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=512 count=1 ||
9451                 error "$RUNAS dd $DIR/$tfile failed"
9452         # See if we are still setuid/sgid
9453         [ -u $DIR/$tfile ] || [ -g $DIR/$tfile ] &&
9454                 error "S/gid is not dropped on write"
9455         # Now test that MDS is updated too
9456         cancel_lru_locks mdc
9457         [ -u $DIR/$tfile ] || [ -g $DIR/$tfile ] &&
9458                 error "S/gid is not dropped on MDS"
9459         rm -f $DIR/$tfile
9460 }
9461 run_test 72a "Test that remove suid works properly (bug5695) ===="
9462
9463 test_72b() { # bug 24226 -- keep mode setting when size is not changing
9464         local perm
9465
9466         [ "$RUNAS_ID" = "$UID" ] &&
9467                 skip_env "RUNAS_ID = UID = $UID -- skipping"
9468         [ "$RUNAS_ID" -eq 0 ] &&
9469                 skip_env "RUNAS_ID = 0 -- skipping"
9470         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9471         # Check that testing environment is properly set up. Skip if not
9472         FAIL_ON_ERROR=false check_runas_id_ret $RUNAS_ID $RUNAS_ID $RUNAS ||
9473                 skip_env "User $RUNAS_ID does not exist - skipping"
9474
9475         touch $DIR/${tfile}-f{g,u}
9476         test_mkdir $DIR/${tfile}-dg
9477         test_mkdir $DIR/${tfile}-du
9478         chmod 770 $DIR/${tfile}-{f,d}{g,u}
9479         chmod g+s $DIR/${tfile}-{f,d}g
9480         chmod u+s $DIR/${tfile}-{f,d}u
9481         for perm in 777 2777 4777; do
9482                 $RUNAS chmod $perm $DIR/${tfile}-fg && error "S/gid file allowed improper chmod to $perm"
9483                 $RUNAS chmod $perm $DIR/${tfile}-fu && error "S/uid file allowed improper chmod to $perm"
9484                 $RUNAS chmod $perm $DIR/${tfile}-dg && error "S/gid dir allowed improper chmod to $perm"
9485                 $RUNAS chmod $perm $DIR/${tfile}-du && error "S/uid dir allowed improper chmod to $perm"
9486         done
9487         true
9488 }
9489 run_test 72b "Test that we keep mode setting if without file data changed (bug 24226)"
9490
9491 # bug 3462 - multiple simultaneous MDC requests
9492 test_73() {
9493         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9494
9495         test_mkdir $DIR/d73-1
9496         test_mkdir $DIR/d73-2
9497         multiop_bg_pause $DIR/d73-1/f73-1 O_c || return 1
9498         pid1=$!
9499
9500         lctl set_param fail_loc=0x80000129
9501         $MULTIOP $DIR/d73-1/f73-2 Oc &
9502         sleep 1
9503         lctl set_param fail_loc=0
9504
9505         $MULTIOP $DIR/d73-2/f73-3 Oc &
9506         pid3=$!
9507
9508         kill -USR1 $pid1
9509         wait $pid1 || return 1
9510
9511         sleep 25
9512
9513         $CHECKSTAT -t file $DIR/d73-1/f73-1 || return 4
9514         $CHECKSTAT -t file $DIR/d73-1/f73-2 || return 5
9515         $CHECKSTAT -t file $DIR/d73-2/f73-3 || return 6
9516
9517         rm -rf $DIR/d73-*
9518 }
9519 run_test 73 "multiple MDC requests (should not deadlock)"
9520
9521 test_74a() { # bug 6149, 6184
9522         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9523
9524         touch $DIR/f74a
9525         #define OBD_FAIL_LDLM_ENQUEUE_OLD_EXPORT 0x30e
9526         #
9527         # very important to OR with OBD_FAIL_ONCE (0x80000000) -- otherwise it
9528         # will spin in a tight reconnection loop
9529         $LCTL set_param fail_loc=0x8000030e
9530         # get any lock that won't be difficult - lookup works.
9531         ls $DIR/f74a
9532         $LCTL set_param fail_loc=0
9533         rm -f $DIR/f74a
9534         true
9535 }
9536 run_test 74a "ldlm_enqueue freed-export error path, ls (shouldn't LBUG)"
9537
9538 test_74b() { # bug 13310
9539         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9540
9541         #define OBD_FAIL_LDLM_ENQUEUE_OLD_EXPORT 0x30e
9542         #
9543         # very important to OR with OBD_FAIL_ONCE (0x80000000) -- otherwise it
9544         # will spin in a tight reconnection loop
9545         $LCTL set_param fail_loc=0x8000030e
9546         # get a "difficult" lock
9547         touch $DIR/f74b
9548         $LCTL set_param fail_loc=0
9549         rm -f $DIR/f74b
9550         true
9551 }
9552 run_test 74b "ldlm_enqueue freed-export error path, touch (shouldn't LBUG)"
9553
9554 test_74c() {
9555         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9556
9557         #define OBD_FAIL_LDLM_NEW_LOCK
9558         $LCTL set_param fail_loc=0x319
9559         touch $DIR/$tfile && error "touch successful"
9560         $LCTL set_param fail_loc=0
9561         true
9562 }
9563 run_test 74c "ldlm_lock_create error path, (shouldn't LBUG)"
9564
9565 slab_lic=/sys/kernel/slab/lustre_inode_cache
9566 num_objects() {
9567         [ -f $slab_lic/shrink ] && echo 1 > $slab_lic/shrink
9568         [ -f $slab_lic/objects ] && awk '{ print $1 }' $slab_lic/objects ||
9569                 awk '/lustre_inode_cache/ { print $2; exit }' /proc/slabinfo
9570 }
9571
9572 test_76a() { # Now for b=20433, added originally in b=1443
9573         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9574
9575         cancel_lru_locks osc
9576         # there may be some slab objects cached per core
9577         local cpus=$(getconf _NPROCESSORS_ONLN 2>/dev/null)
9578         local before=$(num_objects)
9579         local count=$((512 * cpus))
9580         [ "$SLOW" = "no" ] && count=$((128 * cpus))
9581         local margin=$((count / 10))
9582         if [[ -f $slab_lic/aliases ]]; then
9583                 local aliases=$(cat $slab_lic/aliases)
9584                 (( aliases > 0 )) && margin=$((margin * aliases))
9585         fi
9586
9587         echo "before slab objects: $before"
9588         for i in $(seq $count); do
9589                 touch $DIR/$tfile
9590                 rm -f $DIR/$tfile
9591         done
9592         cancel_lru_locks osc
9593         local after=$(num_objects)
9594         echo "created: $count, after slab objects: $after"
9595         # shared slab counts are not very accurate, allow significant margin
9596         # the main goal is that the cache growth is not permanently > $count
9597         while (( after > before + margin )); do
9598                 sleep 1
9599                 after=$(num_objects)
9600                 wait=$((wait + 1))
9601                 (( wait % 5 == 0 )) && echo "wait $wait seconds objects: $after"
9602                 if (( wait > 60 )); then
9603                         error "inode slab grew from $before+$margin to $after"
9604                 fi
9605         done
9606 }
9607 run_test 76a "confirm clients recycle inodes properly ===="
9608
9609 test_76b() {
9610         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9611         [ $CLIENT_VERSION -ge $(version_code 2.13.55) ] || skip "not supported"
9612
9613         local count=512
9614         local before=$(num_objects)
9615
9616         for i in $(seq $count); do
9617                 mkdir $DIR/$tdir
9618                 rmdir $DIR/$tdir
9619         done
9620
9621         local after=$(num_objects)
9622         local wait=0
9623
9624         while (( after > before )); do
9625                 sleep 1
9626                 after=$(num_objects)
9627                 wait=$((wait + 1))
9628                 (( wait % 5 == 0 )) && echo "wait $wait seconds objects: $after"
9629                 if (( wait > 60 )); then
9630                         error "inode slab grew from $before to $after"
9631                 fi
9632         done
9633
9634         echo "slab objects before: $before, after: $after"
9635 }
9636 run_test 76b "confirm clients recycle directory inodes properly ===="
9637
9638 export ORIG_CSUM=""
9639 set_checksums()
9640 {
9641         # Note: in sptlrpc modes which enable its own bulk checksum, the
9642         # original crc32_le bulk checksum will be automatically disabled,
9643         # and the OBD_FAIL_OSC_CHECKSUM_SEND/OBD_FAIL_OSC_CHECKSUM_RECEIVE
9644         # will be checked by sptlrpc code against sptlrpc bulk checksum.
9645         # In this case set_checksums() will not be no-op, because sptlrpc
9646         # bulk checksum will be enabled all through the test.
9647
9648         [ "$ORIG_CSUM" ] || ORIG_CSUM=`lctl get_param -n osc.*.checksums | head -n1`
9649         lctl set_param -n osc.*.checksums $1
9650         return 0
9651 }
9652
9653 export ORIG_CSUM_TYPE="`lctl get_param -n osc.*osc-[^mM]*.checksum_type |
9654                         sed 's/.*\[\(.*\)\].*/\1/g' | head -n1`"
9655 CKSUM_TYPES=${CKSUM_TYPES:-$(lctl get_param -n osc.*osc-[^mM]*.checksum_type |
9656                              tr -d [] | head -n1)}
9657 set_checksum_type()
9658 {
9659         lctl set_param -n osc.*osc-[^mM]*.checksum_type $1
9660         rc=$?
9661         log "set checksum type to $1, rc = $rc"
9662         return $rc
9663 }
9664
9665 get_osc_checksum_type()
9666 {
9667         # arugment 1: OST name, like OST0000
9668         ost=$1
9669         checksum_type=$(lctl get_param -n osc.*${ost}-osc-[^mM]*.checksum_type |
9670                         sed 's/.*\[\(.*\)\].*/\1/g')
9671         rc=$?
9672         [ $rc -ne 0 ] && error "failed to get checksum type of $ost, rc = $rc, output = $checksum_type"
9673         echo $checksum_type
9674 }
9675
9676 F77_TMP=$TMP/f77-temp
9677 F77SZ=8
9678 setup_f77() {
9679         dd if=/dev/urandom of=$F77_TMP bs=1M count=$F77SZ || \
9680                 error "error writing to $F77_TMP"
9681 }
9682
9683 test_77a() { # bug 10889
9684         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9685         $GSS && skip_env "could not run with gss"
9686
9687         [ ! -f $F77_TMP ] && setup_f77
9688         set_checksums 1
9689         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ || error "dd error"
9690         set_checksums 0
9691         rm -f $DIR/$tfile
9692 }
9693 run_test 77a "normal checksum read/write operation"
9694
9695 test_77b() { # bug 10889
9696         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9697         $GSS && skip_env "could not run with gss"
9698
9699         [ ! -f $F77_TMP ] && setup_f77
9700         #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
9701         $LCTL set_param fail_loc=0x80000409
9702         set_checksums 1
9703
9704         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ conv=sync ||
9705                 error "dd error: $?"
9706         $LCTL set_param fail_loc=0
9707
9708         for algo in $CKSUM_TYPES; do
9709                 cancel_lru_locks osc
9710                 set_checksum_type $algo
9711                 #define OBD_FAIL_OSC_CHECKSUM_RECEIVE    0x408
9712                 $LCTL set_param fail_loc=0x80000408
9713                 cmp $F77_TMP $DIR/$tfile || error "file compare failed"
9714                 $LCTL set_param fail_loc=0
9715         done
9716         set_checksums 0
9717         set_checksum_type $ORIG_CSUM_TYPE
9718         rm -f $DIR/$tfile
9719 }
9720 run_test 77b "checksum error on client write, read"
9721
9722 cleanup_77c() {
9723         trap 0
9724         set_checksums 0
9725         $LCTL set_param osc.*osc-[^mM]*.checksum_dump=0
9726         $check_ost &&
9727                 do_facet ost1 $LCTL set_param obdfilter.*-OST*.checksum_dump=0
9728         [ -n "$osc_file_prefix" ] && rm -f ${osc_file_prefix}*
9729         $check_ost && [ -n "$ost_file_prefix" ] &&
9730                 do_facet ost1 rm -f ${ost_file_prefix}\*
9731 }
9732
9733 test_77c() {
9734         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9735         $GSS && skip_env "could not run with gss"
9736         remote_ost_nodsh && skip "remote OST with nodsh"
9737
9738         local bad1
9739         local osc_file_prefix
9740         local osc_file
9741         local check_ost=false
9742         local ost_file_prefix
9743         local ost_file
9744         local orig_cksum
9745         local dump_cksum
9746         local fid
9747
9748         # ensure corruption will occur on first OSS/OST
9749         $LFS setstripe -i 0 $DIR/$tfile
9750
9751         [ ! -f $F77_TMP ] && setup_f77
9752         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ conv=sync ||
9753                 error "dd write error: $?"
9754         fid=$($LFS path2fid $DIR/$tfile)
9755
9756         if [ $OST1_VERSION -ge $(version_code 2.9.57) ]
9757         then
9758                 check_ost=true
9759                 ost_file_prefix=$(do_facet ost1 $LCTL get_param -n debug_path)
9760                 ost_file_prefix=${ost_file_prefix}-checksum_dump-ost-\\${fid}
9761         else
9762                 echo "OSS do not support bulk pages dump upon error"
9763         fi
9764
9765         osc_file_prefix=$($LCTL get_param -n debug_path)
9766         osc_file_prefix=${osc_file_prefix}-checksum_dump-osc-\\${fid}
9767
9768         trap cleanup_77c EXIT
9769
9770         set_checksums 1
9771         # enable bulk pages dump upon error on Client
9772         $LCTL set_param osc.*osc-[^mM]*.checksum_dump=1
9773         # enable bulk pages dump upon error on OSS
9774         $check_ost &&
9775                 do_facet ost1 $LCTL set_param obdfilter.*-OST*.checksum_dump=1
9776
9777         # flush Client cache to allow next read to reach OSS
9778         cancel_lru_locks osc
9779
9780         #define OBD_FAIL_OSC_CHECKSUM_RECEIVE       0x408
9781         $LCTL set_param fail_loc=0x80000408
9782         dd if=$DIR/$tfile of=/dev/null bs=1M || error "dd read error: $?"
9783         $LCTL set_param fail_loc=0
9784
9785         rm -f $DIR/$tfile
9786
9787         # check cksum dump on Client
9788         osc_file=$(ls ${osc_file_prefix}*)
9789         [ -n "$osc_file" ] || error "no checksum dump file on Client"
9790         # OBD_FAIL_OSC_CHECKSUM_RECEIVE corrupts with "bad1" at start of file
9791         bad1=$(dd if=$osc_file bs=1 count=4 2>/dev/null) || error "dd error: $?"
9792         [ $bad1 == "bad1" ] || error "unexpected corrupt pattern"
9793         orig_cksum=$(dd if=$F77_TMP bs=1 skip=4 count=1048572 2>/dev/null |
9794                      cksum)
9795         dump_cksum=$(dd if=$osc_file bs=1 skip=4 2>/dev/null | cksum)
9796         [[ "$orig_cksum" == "$dump_cksum" ]] ||
9797                 error "dump content does not match on Client"
9798
9799         $check_ost || skip "No need to check cksum dump on OSS"
9800
9801         # check cksum dump on OSS
9802         ost_file=$(do_facet ost1 ls ${ost_file_prefix}\*)
9803         [ -n "$ost_file" ] || error "no checksum dump file on OSS"
9804         orig_cksum=$(dd if=$F77_TMP bs=1048576 count=1 2>/dev/null | cksum)
9805         dump_cksum=$(do_facet ost1 dd if=$ost_file 2>/dev/null \| cksum)
9806         [[ "$orig_cksum" == "$dump_cksum" ]] ||
9807                 error "dump content does not match on OSS"
9808
9809         cleanup_77c
9810 }
9811 run_test 77c "checksum error on client read with debug"
9812
9813 test_77d() { # bug 10889
9814         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9815         $GSS && skip_env "could not run with gss"
9816
9817         stack_trap "rm -f $DIR/$tfile"
9818         #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
9819         $LCTL set_param fail_loc=0x80000409
9820         set_checksums 1
9821         $DIRECTIO write $DIR/$tfile 0 $F77SZ $((1024 * 1024)) ||
9822                 error "direct write: rc=$?"
9823         $LCTL set_param fail_loc=0
9824         set_checksums 0
9825
9826         #define OBD_FAIL_OSC_CHECKSUM_RECEIVE    0x408
9827         $LCTL set_param fail_loc=0x80000408
9828         set_checksums 1
9829         cancel_lru_locks osc
9830         $DIRECTIO read $DIR/$tfile 0 $F77SZ $((1024 * 1024)) ||
9831                 error "direct read: rc=$?"
9832         $LCTL set_param fail_loc=0
9833         set_checksums 0
9834 }
9835 run_test 77d "checksum error on OST direct write, read"
9836
9837 test_77f() { # bug 10889
9838         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9839         $GSS && skip_env "could not run with gss"
9840
9841         set_checksums 1
9842         stack_trap "rm -f $DIR/$tfile"
9843         for algo in $CKSUM_TYPES; do
9844                 cancel_lru_locks osc
9845                 set_checksum_type $algo
9846                 #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
9847                 $LCTL set_param fail_loc=0x409
9848                 $DIRECTIO write $DIR/$tfile 0 $F77SZ $((1024 * 1024)) &&
9849                         error "direct write succeeded"
9850                 $LCTL set_param fail_loc=0
9851         done
9852         set_checksum_type $ORIG_CSUM_TYPE
9853         set_checksums 0
9854 }
9855 run_test 77f "repeat checksum error on write (expect error)"
9856
9857 test_77g() { # bug 10889
9858         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9859         $GSS && skip_env "could not run with gss"
9860         remote_ost_nodsh && skip "remote OST with nodsh"
9861
9862         [ ! -f $F77_TMP ] && setup_f77
9863
9864         local file=$DIR/$tfile
9865         stack_trap "rm -f $file" EXIT
9866
9867         $LFS setstripe -c 1 -i 0 $file
9868         #define OBD_FAIL_OST_CHECKSUM_RECEIVE       0x21a
9869         do_facet ost1 lctl set_param fail_loc=0x8000021a
9870         set_checksums 1
9871         dd if=$F77_TMP of=$file bs=1M count=$F77SZ ||
9872                 error "write error: rc=$?"
9873         do_facet ost1 lctl set_param fail_loc=0
9874         set_checksums 0
9875
9876         cancel_lru_locks osc
9877         #define OBD_FAIL_OST_CHECKSUM_SEND          0x21b
9878         do_facet ost1 lctl set_param fail_loc=0x8000021b
9879         set_checksums 1
9880         cmp $F77_TMP $file || error "file compare failed"
9881         do_facet ost1 lctl set_param fail_loc=0
9882         set_checksums 0
9883 }
9884 run_test 77g "checksum error on OST write, read"
9885
9886 test_77k() { # LU-10906
9887         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9888         $GSS && skip_env "could not run with gss"
9889
9890         local cksum_param="osc.$FSNAME*.checksums"
9891         local get_checksum="$LCTL get_param -n $cksum_param | head -n1"
9892         local checksum
9893         local i
9894
9895         [ "$ORIG_CSUM" ] || ORIG_CSUM=$(eval $get_checksum)
9896         stack_trap "wait_update $HOSTNAME '$get_checksum' $ORIG_CSUM || true"
9897         stack_trap "do_facet mgs $LCTL set_param -P $cksum_param=$ORIG_CSUM"
9898
9899         for i in 0 1; do
9900                 do_facet mgs $LCTL set_param -P $cksum_param=$i ||
9901                         error "failed to set checksum=$i on MGS"
9902                 wait_update $HOSTNAME "$get_checksum" $i
9903                 #remount
9904                 echo "remount client, checksum should be $i"
9905                 remount_client $MOUNT || error "failed to remount client"
9906                 checksum=$(eval $get_checksum)
9907                 [ $checksum -eq $i ] || error "checksum($checksum) != $i"
9908         done
9909         # remove persistent param to avoid races with checksum mountopt below
9910         do_facet mgs $LCTL set_param -P -d $cksum_param ||
9911                 error "failed to delete checksum on MGS"
9912
9913         for opt in "checksum" "nochecksum"; do
9914                 #remount with mount option
9915                 echo "remount client with option $opt, checksum should be $i"
9916                 umount_client $MOUNT || error "failed to umount client"
9917                 mount_client $MOUNT "$MOUNT_OPTS,$opt" ||
9918                         error "failed to mount client with option '$opt'"
9919                 checksum=$(eval $get_checksum)
9920                 [ $checksum -eq $i ] || error "checksum($checksum) != $i"
9921                 i=$((i - 1))
9922         done
9923
9924         remount_client $MOUNT || error "failed to remount client"
9925 }
9926 run_test 77k "enable/disable checksum correctly"
9927
9928 test_77l() {
9929         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9930         $GSS && skip_env "could not run with gss"
9931
9932         set_checksums 1
9933         stack_trap "set_checksums $ORIG_CSUM" EXIT
9934         stack_trap "set_checksum_type $ORIG_CSUM_TYPE" EXIT
9935
9936         set_checksum_type invalid && error "unexpected success of invalid checksum type"
9937
9938         $LFS setstripe -c 1 -i 0 $DIR/$tfile
9939         for algo in $CKSUM_TYPES; do
9940                 set_checksum_type $algo || error "fail to set checksum type $algo"
9941                 osc_algo=$(get_osc_checksum_type OST0000)
9942                 [ "$osc_algo" != "$algo" ] && error "checksum type is $osc_algo after setting it to $algo"
9943
9944                 # no locks, no reqs to let the connection idle
9945                 cancel_lru_locks osc
9946                 lru_resize_disable osc
9947                 wait_osc_import_state client ost1 IDLE
9948
9949                 # ensure ost1 is connected
9950                 stat $DIR/$tfile >/dev/null || error "can't stat"
9951                 wait_osc_import_state client ost1 FULL
9952
9953                 osc_algo=$(get_osc_checksum_type OST0000)
9954                 [ "$osc_algo" != "$algo" ] && error "checksum type changed from $algo to $osc_algo after reconnection"
9955         done
9956         return 0
9957 }
9958 run_test 77l "preferred checksum type is remembered after reconnected"
9959
9960 [ "$ORIG_CSUM" ] && set_checksums $ORIG_CSUM || true
9961 rm -f $F77_TMP
9962 unset F77_TMP
9963
9964 test_77m() {
9965         (( $CLIENT_VERSION >= $(version_code 2.14.52) )) ||
9966                 skip "Need at least version 2.14.52"
9967         local param=checksum_speed
9968
9969         $LCTL get_param $param || error "reading $param failed"
9970
9971         csum_speeds=$($LCTL get_param -n $param)
9972
9973         [[ "$csum_speeds" =~ "adler32" && "$csum_speeds" =~ "crc32" ]] ||
9974                 error "known checksum types are missing"
9975 }
9976 run_test 77m "Verify checksum_speed is correctly read"
9977
9978 check_filefrag_77n() {
9979         local nr_ext=0
9980         local starts=()
9981         local ends=()
9982
9983         while read extidx a b start end rest; do
9984                 if [[ "${extidx}" =~ ^[0-9]+: ]]; then
9985                         nr_ext=$(( $nr_ext + 1 ))
9986                         starts+=( ${start%..} )
9987                         ends+=( ${end%:} )
9988                 fi
9989         done < <( filefrag -sv $1 )
9990
9991         [[ $nr_ext -eq 2 ]] && [[ "${starts[-1]}" == $(( ${ends[0]} + 1 )) ]] && return 0
9992         return 1
9993 }
9994
9995 test_77n() {
9996         [[ "$CKSUM_TYPES" =~ t10 ]] || skip "no T10 checksum support on osc"
9997
9998         touch $DIR/$tfile
9999         $TRUNCATE $DIR/$tfile 0
10000         dd if=/dev/urandom of=$DIR/$tfile bs=4k conv=notrunc count=1 seek=0
10001         dd if=/dev/urandom of=$DIR/$tfile bs=4k conv=notrunc count=1 seek=2
10002         check_filefrag_77n $DIR/$tfile ||
10003                 skip "$tfile blocks not contiguous around hole"
10004
10005         set_checksums 1
10006         stack_trap "set_checksums $ORIG_CSUM" EXIT
10007         stack_trap "set_checksum_type $ORIG_CSUM_TYPE" EXIT
10008         stack_trap "rm -f $DIR/$tfile"
10009
10010         for algo in $CKSUM_TYPES; do
10011                 if [[ "$algo" =~ ^t10 ]]; then
10012                         set_checksum_type $algo ||
10013                                 error "fail to set checksum type $algo"
10014                         dd if=$DIR/$tfile of=/dev/null bs=12k count=1 iflag=direct ||
10015                                 error "fail to read $tfile with $algo"
10016                 fi
10017         done
10018         rm -f $DIR/$tfile
10019         return 0
10020 }
10021 run_test 77n "Verify read from a hole inside contiguous blocks with T10PI"
10022
10023 test_77o() {
10024         (( $CLIENT_VERSION >= $(version_code 2.14.54) )) ||
10025                 skip "Need at least version 2.14.54"
10026         local ofd=obdfilter
10027         local mdt=mdt
10028
10029         # print OST checksum_type
10030         echo "$ofd.$FSNAME-*.checksum_type:"
10031         do_nodes $(comma_list $(osts_nodes)) \
10032                 $LCTL get_param -n $ofd.$FSNAME-*.checksum_type
10033
10034         # print MDT checksum_type
10035         echo "$mdt.$FSNAME-*.checksum_type:"
10036         do_nodes $(comma_list $(mdts_nodes)) \
10037                 $LCTL get_param -n $mdt.$FSNAME-*.checksum_type
10038
10039         local o_count=$(do_nodes $(comma_list $(osts_nodes)) \
10040                    $LCTL get_param -n $ofd.$FSNAME-*.checksum_type | wc -l)
10041
10042         (( $o_count == $OSTCOUNT )) ||
10043                 error "found $o_count checksums, not \$MDSCOUNT=$OSTCOUNT"
10044
10045         local m_count=$(do_nodes $(comma_list $(mdts_nodes)) \
10046                    $LCTL get_param -n $mdt.$FSNAME-*.checksum_type | wc -l)
10047
10048         (( $m_count == $MDSCOUNT )) ||
10049                 error "found $m_count checksums, not \$MDSCOUNT=$MDSCOUNT"
10050 }
10051 run_test 77o "Verify checksum_type for server (mdt and ofd(obdfilter))"
10052
10053 cleanup_test_78() {
10054         trap 0
10055         rm -f $DIR/$tfile
10056 }
10057
10058 test_78() { # bug 10901
10059         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10060         remote_ost || skip_env "local OST"
10061
10062         NSEQ=5
10063         F78SIZE=$(($(awk '/MemFree:/ { print $2 }' /proc/meminfo) / 1024))
10064         echo "MemFree: $F78SIZE, Max file size: $MAXFREE"
10065         MEMTOTAL=$(($(awk '/MemTotal:/ { print $2 }' /proc/meminfo) / 1024))
10066         echo "MemTotal: $MEMTOTAL"
10067
10068         # reserve 256MB of memory for the kernel and other running processes,
10069         # and then take 1/2 of the remaining memory for the read/write buffers.
10070         if [ $MEMTOTAL -gt 512 ] ;then
10071                 MEMTOTAL=$(((MEMTOTAL - 256 ) / 2))
10072         else
10073                 # for those poor memory-starved high-end clusters...
10074                 MEMTOTAL=$((MEMTOTAL / 2))
10075         fi
10076         echo "Mem to use for directio: $MEMTOTAL"
10077
10078         [[ $F78SIZE -gt $MEMTOTAL ]] && F78SIZE=$MEMTOTAL
10079         [[ $F78SIZE -gt 512 ]] && F78SIZE=512
10080         [[ $F78SIZE -gt $((MAXFREE / 1024)) ]] && F78SIZE=$((MAXFREE / 1024))
10081         SMALLESTOST=$($LFS df $DIR | grep OST | awk '{ print $4 }' | sort -n |
10082                 head -n1)
10083         echo "Smallest OST: $SMALLESTOST"
10084         [[ $SMALLESTOST -lt 10240 ]] &&
10085                 skip "too small OSTSIZE, useless to run large O_DIRECT test"
10086
10087         trap cleanup_test_78 EXIT
10088
10089         [[ $F78SIZE -gt $((SMALLESTOST * $OSTCOUNT / 1024 - 80)) ]] &&
10090                 F78SIZE=$((SMALLESTOST * $OSTCOUNT / 1024 - 80))
10091
10092         [ "$SLOW" = "no" ] && NSEQ=1 && [ $F78SIZE -gt 32 ] && F78SIZE=32
10093         echo "File size: $F78SIZE"
10094         $LFS setstripe -c $OSTCOUNT $DIR/$tfile || error "setstripe failed"
10095         for i in $(seq 1 $NSEQ); do
10096                 FSIZE=$(($F78SIZE / ($NSEQ - $i + 1)))
10097                 echo directIO rdwr round $i of $NSEQ
10098                 $DIRECTIO rdwr $DIR/$tfile 0 $FSIZE 1048576||error "rdwr failed"
10099         done
10100
10101         cleanup_test_78
10102 }
10103 run_test 78 "handle large O_DIRECT writes correctly ============"
10104
10105 test_79() { # bug 12743
10106         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10107
10108         wait_delete_completed
10109
10110         BKTOTAL=$(calc_osc_kbytes kbytestotal)
10111         BKFREE=$(calc_osc_kbytes kbytesfree)
10112         BKAVAIL=$(calc_osc_kbytes kbytesavail)
10113
10114         STRING=`df -P $MOUNT | tail -n 1 | awk '{print $2","$3","$4}'`
10115         DFTOTAL=`echo $STRING | cut -d, -f1`
10116         DFUSED=`echo $STRING  | cut -d, -f2`
10117         DFAVAIL=`echo $STRING | cut -d, -f3`
10118         DFFREE=$(($DFTOTAL - $DFUSED))
10119
10120         ALLOWANCE=$((64 * $OSTCOUNT))
10121
10122         if [ $DFTOTAL -lt $(($BKTOTAL - $ALLOWANCE)) ] ||
10123            [ $DFTOTAL -gt $(($BKTOTAL + $ALLOWANCE)) ] ; then
10124                 error "df total($DFTOTAL) mismatch OST total($BKTOTAL)"
10125         fi
10126         if [ $DFFREE -lt $(($BKFREE - $ALLOWANCE)) ] ||
10127            [ $DFFREE -gt $(($BKFREE + $ALLOWANCE)) ] ; then
10128                 error "df free($DFFREE) mismatch OST free($BKFREE)"
10129         fi
10130         if [ $DFAVAIL -lt $(($BKAVAIL - $ALLOWANCE)) ] ||
10131            [ $DFAVAIL -gt $(($BKAVAIL + $ALLOWANCE)) ] ; then
10132                 error "df avail($DFAVAIL) mismatch OST avail($BKAVAIL)"
10133         fi
10134 }
10135 run_test 79 "df report consistency check ======================="
10136
10137 test_80() { # bug 10718
10138         remote_ost_nodsh && skip "remote OST with nodsh"
10139         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10140
10141         # relax strong synchronous semantics for slow backends like ZFS
10142         if [ "$ost1_FSTYPE" != "ldiskfs" ]; then
10143                 local soc="obdfilter.*.sync_lock_cancel"
10144                 local save=$(do_facet ost1 $LCTL get_param -n $soc | head -n1)
10145
10146                 # "sync_on_lock_cancel" was broken by v2_11_55_0-26-g7059644e9a
10147                 if [ -z "$save" ]; then
10148                         soc="obdfilter.*.sync_on_lock_cancel"
10149                         save=$(do_facet ost1 $LCTL get_param -n $soc | head -n1)
10150                 fi
10151
10152                 if [ "$save" != "never" ]; then
10153                         local hosts=$(comma_list $(osts_nodes))
10154
10155                         do_nodes $hosts $LCTL set_param $soc=never
10156                         stack_trap "do_nodes $hosts $LCTL set_param $soc=$save"
10157                 fi
10158         fi
10159
10160         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=1M
10161         sync; sleep 1; sync
10162         local before=$(date +%s)
10163         cancel_lru_locks osc
10164         local after=$(date +%s)
10165         local diff=$((after - before))
10166         [ $diff -le 1 ] || error "elapsed for 1M@1T = $diff"
10167
10168         rm -f $DIR/$tfile
10169 }
10170 run_test 80 "Page eviction is equally fast at high offsets too"
10171
10172 test_81a() { # LU-456
10173         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10174         remote_ost_nodsh && skip "remote OST with nodsh"
10175
10176         # define OBD_FAIL_OST_MAPBLK_ENOSPC    0x228
10177         # MUST OR with the OBD_FAIL_ONCE (0x80000000)
10178         do_facet ost1 lctl set_param fail_loc=0x80000228
10179
10180         # write should trigger a retry and success
10181         $LFS setstripe -i 0 -c 1 $DIR/$tfile
10182         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
10183         RC=$?
10184         if [ $RC -ne 0 ] ; then
10185                 error "write should success, but failed for $RC"
10186         fi
10187 }
10188 run_test 81a "OST should retry write when get -ENOSPC ==============="
10189
10190 test_81b() { # LU-456
10191         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10192         remote_ost_nodsh && skip "remote OST with nodsh"
10193
10194         # define OBD_FAIL_OST_MAPBLK_ENOSPC    0x228
10195         # Don't OR with the OBD_FAIL_ONCE (0x80000000)
10196         do_facet ost1 lctl set_param fail_loc=0x228
10197
10198         # write should retry several times and return -ENOSPC finally
10199         $LFS setstripe -i 0 -c 1 $DIR/$tfile
10200         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
10201         RC=$?
10202         ENOSPC=28
10203         if [ $RC -ne $ENOSPC ] ; then
10204                 error "dd should fail for -ENOSPC, but succeed."
10205         fi
10206 }
10207 run_test 81b "OST should return -ENOSPC when retry still fails ======="
10208
10209 test_99() {
10210         [ -z "$(which cvs 2>/dev/null)" ] && skip_env "could not find cvs"
10211
10212         test_mkdir $DIR/$tdir.cvsroot
10213         chown $RUNAS_ID $DIR/$tdir.cvsroot
10214
10215         cd $TMP
10216         $RUNAS cvs -d $DIR/$tdir.cvsroot init || error "cvs init failed"
10217
10218         cd /etc/init.d
10219         # some versions of cvs import exit(1) when asked to import links or
10220         # files they can't read.  ignore those files.
10221         local toignore=$(find . -type l -printf '-I %f\n' -o \
10222                          ! -perm /4 -printf '-I %f\n')
10223         $RUNAS cvs -d $DIR/$tdir.cvsroot import -m "nomesg" $toignore \
10224                 $tdir.reposname vtag rtag
10225
10226         cd $DIR
10227         test_mkdir $DIR/$tdir.reposname
10228         chown $RUNAS_ID $DIR/$tdir.reposname
10229         $RUNAS cvs -d $DIR/$tdir.cvsroot co $tdir.reposname
10230
10231         cd $DIR/$tdir.reposname
10232         $RUNAS touch foo99
10233         $RUNAS cvs add -m 'addmsg' foo99
10234         $RUNAS cvs update
10235         $RUNAS cvs commit -m 'nomsg' foo99
10236         rm -fr $DIR/$tdir.cvsroot
10237 }
10238 run_test 99 "cvs strange file/directory operations"
10239
10240 test_100() {
10241         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10242         [[ "$NETTYPE" =~ tcp ]] ||
10243                 skip_env "TCP secure port test, not useful for NETTYPE=$NETTYPE"
10244         remote_ost_nodsh && skip "remote OST with nodsh"
10245         remote_mds_nodsh && skip "remote MDS with nodsh"
10246         remote_servers ||
10247                 skip "useless for local single node setup"
10248
10249         netstat -tna | ( rc=1; while read PROT SND RCV LOCAL REMOTE STAT; do
10250                 [ "$PROT" != "tcp" ] && continue
10251                 RPORT=$(echo $REMOTE | cut -d: -f2)
10252                 [ "$RPORT" != "$ACCEPTOR_PORT" ] && continue
10253
10254                 rc=0
10255                 LPORT=`echo $LOCAL | cut -d: -f2`
10256                 if [ $LPORT -ge 1024 ]; then
10257                         echo "bad: $PROT $SND $RCV $LOCAL $REMOTE $STAT"
10258                         netstat -tna
10259                         error_exit "local: $LPORT > 1024, remote: $RPORT"
10260                 fi
10261         done
10262         [ "$rc" = 0 ] || error_exit "privileged port not found" )
10263 }
10264 run_test 100 "check local port using privileged port ==========="
10265
10266 function get_named_value()
10267 {
10268     local tag=$1
10269
10270     grep -w "$tag" | sed "s/^$tag  *\([0-9]*\)  *.*/\1/"
10271 }
10272
10273 export CACHE_MAX=$($LCTL get_param -n llite.*.max_cached_mb |
10274                    awk '/^max_cached_mb/ { print $2 }')
10275
10276 cleanup_101a() {
10277         $LCTL set_param -n llite.*.max_cached_mb $CACHE_MAX
10278         trap 0
10279 }
10280
10281 test_101a() {
10282         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10283
10284         local s
10285         local discard
10286         local nreads=10000
10287         local cache_limit=32
10288
10289         $LCTL set_param -n osc.*-osc*.rpc_stats=0
10290         trap cleanup_101a EXIT
10291         $LCTL set_param -n llite.*.read_ahead_stats=0
10292         $LCTL set_param -n llite.*.max_cached_mb=$cache_limit
10293
10294         #
10295         # randomly read 10000 of 64K chunks from file 3x 32MB in size
10296         #
10297         echo "nreads: $nreads file size: $((cache_limit * 3))MB"
10298         $READS -f $DIR/$tfile -s$((cache_limit * 3192 * 1024)) -b65536 -C -n$nreads -t 180
10299
10300         discard=0
10301         for s in $($LCTL get_param -n llite.*.read_ahead_stats |
10302                    get_named_value 'read.but.discarded'); do
10303                         discard=$(($discard + $s))
10304         done
10305         cleanup_101a
10306
10307         $LCTL get_param osc.*-osc*.rpc_stats
10308         $LCTL get_param llite.*.read_ahead_stats
10309
10310         # Discard is generally zero, but sometimes a few random reads line up
10311         # and trigger larger readahead, which is wasted & leads to discards.
10312         if [[ $(($discard)) -gt $nreads ]]; then
10313                 error "too many ($discard) discarded pages"
10314         fi
10315         rm -f $DIR/$tfile || true
10316 }
10317 run_test 101a "check read-ahead for random reads"
10318
10319 setup_test101bc() {
10320         test_mkdir $DIR/$tdir
10321         local ssize=$1
10322         local FILE_LENGTH=$2
10323         STRIPE_OFFSET=0
10324
10325         local FILE_SIZE_MB=$((FILE_LENGTH / ssize))
10326
10327         local list=$(comma_list $(osts_nodes))
10328         set_osd_param $list '' read_cache_enable 0
10329         set_osd_param $list '' writethrough_cache_enable 0
10330
10331         trap cleanup_test101bc EXIT
10332         # prepare the read-ahead file
10333         $LFS setstripe -S $ssize -i $STRIPE_OFFSET -c $OSTCOUNT $DIR/$tfile
10334
10335         dd if=/dev/zero of=$DIR/$tfile bs=$ssize \
10336                                 count=$FILE_SIZE_MB 2> /dev/null
10337
10338 }
10339
10340 cleanup_test101bc() {
10341         trap 0
10342         rm -rf $DIR/$tdir
10343         rm -f $DIR/$tfile
10344
10345         local list=$(comma_list $(osts_nodes))
10346         set_osd_param $list '' read_cache_enable 1
10347         set_osd_param $list '' writethrough_cache_enable 1
10348 }
10349
10350 calc_total() {
10351         awk 'BEGIN{total=0}; {total+=$1}; END{print total}'
10352 }
10353
10354 ra_check_101() {
10355         local READ_SIZE=$1
10356         local STRIPE_SIZE=$2
10357         local FILE_LENGTH=$3
10358         local RA_INC=1048576
10359         local STRIDE_LENGTH=$((STRIPE_SIZE/READ_SIZE))
10360         local discard_limit=$((((STRIDE_LENGTH - 1)*3/(STRIDE_LENGTH*OSTCOUNT))* \
10361                              (STRIDE_LENGTH*OSTCOUNT - STRIDE_LENGTH)))
10362         DISCARD=$($LCTL get_param -n llite.*.read_ahead_stats |
10363                   get_named_value 'read.but.discarded' | calc_total)
10364         if [[ $DISCARD -gt $discard_limit ]]; then
10365                 $LCTL get_param llite.*.read_ahead_stats
10366                 error "Too many ($DISCARD) discarded pages with size (${READ_SIZE})"
10367         else
10368                 echo "Read-ahead success for size ${READ_SIZE}"
10369         fi
10370 }
10371
10372 test_101b() {
10373         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10374         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
10375
10376         local STRIPE_SIZE=1048576
10377         local STRIDE_SIZE=$((STRIPE_SIZE*OSTCOUNT))
10378
10379         if [ $SLOW == "yes" ]; then
10380                 local FILE_LENGTH=$((STRIDE_SIZE * 64))
10381         else
10382                 local FILE_LENGTH=$((STRIDE_SIZE * 8))
10383         fi
10384
10385         local ITERATION=$((FILE_LENGTH / STRIDE_SIZE))
10386
10387         # prepare the read-ahead file
10388         setup_test101bc $STRIPE_SIZE $FILE_LENGTH
10389         cancel_lru_locks osc
10390         for BIDX in 2 4 8 16 32 64 128 256
10391         do
10392                 local BSIZE=$((BIDX*4096))
10393                 local READ_COUNT=$((STRIPE_SIZE/BSIZE))
10394                 local STRIDE_LENGTH=$((STRIDE_SIZE/BSIZE))
10395                 local OFFSET=$((STRIPE_SIZE/BSIZE*(OSTCOUNT - 1)))
10396                 $LCTL set_param -n llite.*.read_ahead_stats=0
10397                 $READS -f $DIR/$tfile  -l $STRIDE_LENGTH -o $OFFSET \
10398                               -s $FILE_LENGTH -b $STRIPE_SIZE -a $READ_COUNT -n $ITERATION
10399                 cancel_lru_locks osc
10400                 ra_check_101 $BSIZE $STRIPE_SIZE $FILE_LENGTH
10401         done
10402         cleanup_test101bc
10403         true
10404 }
10405 run_test 101b "check stride-io mode read-ahead ================="
10406
10407 test_101c() {
10408         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10409
10410         local STRIPE_SIZE=1048576
10411         local FILE_LENGTH=$((STRIPE_SIZE*100))
10412         local nreads=10000
10413         local rsize=65536
10414         local osc_rpc_stats
10415
10416         setup_test101bc $STRIPE_SIZE $FILE_LENGTH
10417
10418         cancel_lru_locks osc
10419         $LCTL set_param osc.*.rpc_stats=0
10420         $READS -f $DIR/$tfile -s$FILE_LENGTH -b$rsize -n$nreads -t 180
10421         $LCTL get_param osc.*.rpc_stats
10422         for osc_rpc_stats in $($LCTL get_param -N osc.*.rpc_stats); do
10423                 local stats=$($LCTL get_param -n $osc_rpc_stats)
10424                 local lines=$(echo "$stats" | awk 'END {print NR;}')
10425                 local size
10426
10427                 if [ $lines -le 20 ]; then
10428                         echo "continue debug"
10429                         continue
10430                 fi
10431                 for size in 1 2 4 8; do
10432                         local rpc=$(echo "$stats" |
10433                                     awk '($1 == "'$size':") {print $2; exit; }')
10434                         [ $rpc != 0 ] && ((size * PAGE_SIZE < rsize)) &&
10435                                 error "Small $((size*PAGE_SIZE)) read IO $rpc!"
10436                 done
10437                 echo "$osc_rpc_stats check passed!"
10438         done
10439         cleanup_test101bc
10440         true
10441 }
10442 run_test 101c "check stripe_size aligned read-ahead"
10443
10444 test_101d() {
10445         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10446
10447         local file=$DIR/$tfile
10448         local sz_MB=${FILESIZE_101d:-80}
10449         local ra_MB=${READAHEAD_MB:-40}
10450
10451         local free_MB=$(($(df -P $DIR | tail -n 1 | awk '{ print $4 }') / 1024))
10452         [ $free_MB -lt $sz_MB ] &&
10453                 skip "Need free space ${sz_MB}M, have ${free_MB}M"
10454
10455         echo "Create test file $file size ${sz_MB}M, ${free_MB}M free"
10456         $LFS setstripe -c -1 $file || error "setstripe failed"
10457
10458         dd if=/dev/zero of=$file bs=1M count=$sz_MB || error "dd failed"
10459         echo Cancel LRU locks on lustre client to flush the client cache
10460         cancel_lru_locks osc
10461
10462         echo Disable read-ahead
10463         local old_RA=$($LCTL get_param -n llite.*.max_read_ahead_mb | head -n 1)
10464         $LCTL set_param -n llite.*.max_read_ahead_mb=0
10465         stack_trap "$LCTL set_param -n llite.*.max_read_ahead_mb=$old_RA" EXIT
10466         $LCTL get_param -n llite.*.max_read_ahead_mb
10467
10468         echo "Reading the test file $file with read-ahead disabled"
10469         local sz_KB=$((sz_MB * 1024 / 4))
10470         # 10485760 bytes transferred in 0.000938 secs (11179579337 bytes/sec)
10471         # 104857600 bytes (105 MB) copied, 0.00876352 s, 12.0 GB/s
10472         local raOFF=$(LANG=C dd if=$file of=/dev/null bs=4k count=$sz_KB |&
10473                       sed -e '/records/d' -e 's/.* \([0-9]*\.[0-9]*\) *s.*/\1/')
10474
10475         echo "Cancel LRU locks on lustre client to flush the client cache"
10476         cancel_lru_locks osc
10477         echo Enable read-ahead with ${ra_MB}MB
10478         $LCTL set_param -n llite.*.max_read_ahead_mb=$ra_MB
10479
10480         echo "Reading the test file $file with read-ahead enabled"
10481         local raON=$(LANG=C dd if=$file of=/dev/null bs=4k count=$sz_KB |&
10482                      sed -e '/records/d' -e 's/.* \([0-9]*\.[0-9]*\) *s.*/\1/')
10483
10484         echo "read-ahead disabled time read $raOFF"
10485         echo "read-ahead enabled time read $raON"
10486
10487         rm -f $file
10488         wait_delete_completed
10489
10490         # use awk for this check instead of bash because it handles decimals
10491         awk "{ exit !($raOFF < 1.0 || $raOFF > $raON) }" <<<"ignore_me" ||
10492                 error "readahead ${raON}s > no-readahead ${raOFF}s ${sz_MB}M"
10493 }
10494 run_test 101d "file read with and without read-ahead enabled"
10495
10496 test_101e() {
10497         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10498
10499         local file=$DIR/$tfile
10500         local size_KB=500  #KB
10501         local count=100
10502         local bsize=1024
10503
10504         local free_KB=$(df -P $DIR | tail -n 1 | awk '{ print $4 }')
10505         local need_KB=$((count * size_KB))
10506         [[ $free_KB -le $need_KB ]] &&
10507                 skip_env "Need free space $need_KB, have $free_KB"
10508
10509         echo "Creating $count ${size_KB}K test files"
10510         for ((i = 0; i < $count; i++)); do
10511                 dd if=/dev/zero of=$file.$i bs=$bsize count=$size_KB 2>/dev/null
10512         done
10513
10514         echo "Cancel LRU locks on lustre client to flush the client cache"
10515         cancel_lru_locks $OSC
10516
10517         echo "Reset readahead stats"
10518         $LCTL set_param -n llite.*.read_ahead_stats=0
10519
10520         for ((i = 0; i < $count; i++)); do
10521                 dd if=$file.$i of=/dev/null bs=$bsize count=$size_KB 2>/dev/null
10522         done
10523
10524         $LCTL get_param llite.*.max_cached_mb
10525         $LCTL get_param llite.*.read_ahead_stats
10526         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
10527                      get_named_value 'misses' | calc_total)
10528
10529         for ((i = 0; i < $count; i++)); do
10530                 rm -rf $file.$i 2>/dev/null
10531         done
10532
10533         #10000 means 20% reads are missing in readahead
10534         [[ $miss -lt 10000 ]] ||  error "misses too much for small reads"
10535 }
10536 run_test 101e "check read-ahead for small read(1k) for small files(500k)"
10537
10538 test_101f() {
10539         which iozone || skip_env "no iozone installed"
10540
10541         local old_debug=$($LCTL get_param debug)
10542         old_debug=${old_debug#*=}
10543         $LCTL set_param debug="reada mmap"
10544
10545         # create a test file
10546         iozone -i 0 -+n -r 1m -s 128m -w -f $DIR/$tfile > /dev/null 2>&1
10547
10548         echo Cancel LRU locks on lustre client to flush the client cache
10549         cancel_lru_locks osc
10550
10551         echo Reset readahead stats
10552         $LCTL set_param -n llite.*.read_ahead_stats=0
10553
10554         echo mmap read the file with small block size
10555         iozone -i 1 -u 1 -l 1 -+n -r 32k -s 128m -B -f $DIR/$tfile \
10556                 > /dev/null 2>&1
10557
10558         echo checking missing pages
10559         $LCTL get_param llite.*.read_ahead_stats
10560         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
10561                         get_named_value 'misses' | calc_total)
10562
10563         $LCTL set_param debug="$old_debug"
10564         [ $miss -lt 3 ] || error "misses too much pages ('$miss')!"
10565         rm -f $DIR/$tfile
10566 }
10567 run_test 101f "check mmap read performance"
10568
10569 test_101g_brw_size_test() {
10570         local mb=$1
10571         local pages=$((mb * 1048576 / PAGE_SIZE))
10572         local file=$DIR/$tfile
10573
10574         $LCTL set_param osc.*.max_pages_per_rpc=${mb}M ||
10575                 { error "unable to set max_pages_per_rpc=${mb}M"; return 1; }
10576         for mp in $($LCTL get_param -n osc.*.max_pages_per_rpc); do
10577                 [ $mp -ne $pages ] && error "max_pages_per_rpc $mp != $pages" &&
10578                         return 2
10579         done
10580
10581         stack_trap "rm -f $file" EXIT
10582         $LCTL set_param -n osc.*.rpc_stats=0
10583
10584         # 10 RPCs should be enough for the test
10585         local count=10
10586         dd if=/dev/zero of=$file bs=${mb}M count=$count ||
10587                 { error "dd write ${mb} MB blocks failed"; return 3; }
10588         cancel_lru_locks osc
10589         dd of=/dev/null if=$file bs=${mb}M count=$count ||
10590                 { error "dd write ${mb} MB blocks failed"; return 4; }
10591
10592         # calculate number of full-sized read and write RPCs
10593         rpcs=($($LCTL get_param -n 'osc.*.rpc_stats' |
10594                 sed -n '/pages per rpc/,/^$/p' |
10595                 awk '/'$pages':/ { reads += $2; writes += $6 }; \
10596                 END { print reads,writes }'))
10597         # allow one extra full-sized read RPC for async readahead
10598         [[ ${rpcs[0]} == $count || ${rpcs[0]} == $((count + 1)) ]] ||
10599                 { error "${rpcs[0]} != $count read RPCs"; return 5; }
10600         [[ ${rpcs[1]} == $count ]] ||
10601                 { error "${rpcs[1]} != $count write RPCs"; return 6; }
10602 }
10603
10604 test_101g() {
10605         remote_ost_nodsh && skip "remote OST with nodsh"
10606
10607         local rpcs
10608         local osts=$(get_facets OST)
10609         local list=$(comma_list $(osts_nodes))
10610         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
10611         local brw_size="obdfilter.*.brw_size"
10612
10613         $LFS setstripe -i 0 -c 1 $DIR/$tfile
10614
10615         local orig_mb=$(do_facet ost1 $LCTL get_param -n $brw_size | head -n 1)
10616
10617         if { [ $OST1_VERSION -ge $(version_code 2.8.52) ] ||
10618                 { [ $OST1_VERSION -ge $(version_code 2.7.17) ] &&
10619                   [ $OST1_VERSION -lt $(version_code 2.7.50) ]; }; } &&
10620            { [ $CLIENT_VERSION -ge $(version_code 2.8.52) ] ||
10621                 { [ $CLIENT_VERSION -ge $(version_code 2.7.17) ] &&
10622                   [ $CLIENT_VERSION -lt $(version_code 2.7.50) ]; }; }; then
10623
10624                 [ $OST1_VERSION -ge $(version_code 2.9.52) ] &&
10625                         suffix="M"
10626
10627                 if [[ $orig_mb -lt 16 ]]; then
10628                         save_lustre_params $osts "$brw_size" > $p
10629                         do_nodes $list $LCTL set_param -n $brw_size=16$suffix ||
10630                                 error "set 16MB RPC size failed"
10631
10632                         echo "remount client to enable new RPC size"
10633                         remount_client $MOUNT || error "remount_client failed"
10634                 fi
10635
10636                 test_101g_brw_size_test 16 || error "16MB RPC test failed"
10637                 # should be able to set brw_size=12, but no rpc_stats for that
10638                 test_101g_brw_size_test 8 || error "8MB RPC test failed"
10639         fi
10640
10641         test_101g_brw_size_test 4 || error "4MB RPC test failed"
10642
10643         if [[ $orig_mb -lt 16 ]]; then
10644                 restore_lustre_params < $p
10645                 remount_client $MOUNT || error "remount_client restore failed"
10646         fi
10647
10648         rm -f $p $DIR/$tfile
10649 }
10650 run_test 101g "Big bulk(4/16 MiB) readahead"
10651
10652 test_101h() {
10653         $LFS setstripe -i 0 -c 1 $DIR/$tfile
10654
10655         dd if=/dev/zero of=$DIR/$tfile bs=1M count=70 ||
10656                 error "dd 70M file failed"
10657         echo Cancel LRU locks on lustre client to flush the client cache
10658         cancel_lru_locks osc
10659
10660         echo "Reset readahead stats"
10661         $LCTL set_param -n llite.*.read_ahead_stats 0
10662
10663         echo "Read 10M of data but cross 64M bundary"
10664         dd if=$DIR/$tfile of=/dev/null bs=10M skip=6 count=1
10665         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
10666                      get_named_value 'misses' | calc_total)
10667         [ $miss -eq 1 ] || error "expected miss 1 but got $miss"
10668         rm -f $p $DIR/$tfile
10669 }
10670 run_test 101h "Readahead should cover current read window"
10671
10672 test_101i() {
10673         dd if=/dev/zero of=$DIR/$tfile bs=1M count=10 ||
10674                 error "dd 10M file failed"
10675
10676         local max_per_file_mb=$($LCTL get_param -n \
10677                 llite.*.max_read_ahead_per_file_mb 2>/dev/null)
10678         cancel_lru_locks osc
10679         stack_trap "$LCTL set_param llite.*.max_read_ahead_per_file_mb=$max_per_file_mb"
10680         $LCTL set_param llite.*.max_read_ahead_per_file_mb=1 ||
10681                 error "set max_read_ahead_per_file_mb to 1 failed"
10682
10683         echo "Reset readahead stats"
10684         $LCTL set_param llite.*.read_ahead_stats=0
10685
10686         dd if=$DIR/$tfile of=/dev/null bs=2M
10687
10688         $LCTL get_param llite.*.read_ahead_stats
10689         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
10690                      awk '/misses/ { print $2 }')
10691         [ $miss -eq 5 ] || error "expected misses 5 but got $miss"
10692         rm -f $DIR/$tfile
10693 }
10694 run_test 101i "allow current readahead to exceed reservation"
10695
10696 test_101j() {
10697         $LFS setstripe -i 0 -c 1 $DIR/$tfile ||
10698                 error "setstripe $DIR/$tfile failed"
10699         local file_size=$((1048576 * 16))
10700         local old_ra=$($LCTL get_param -n llite.*.max_read_ahead_mb | head -n 1)
10701         stack_trap "$LCTL set_param -n llite.*.max_read_ahead_mb $old_ra" EXIT
10702
10703         echo Disable read-ahead
10704         $LCTL set_param -n llite.*.max_read_ahead_mb=0
10705
10706         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$(($file_size / 1048576))
10707         for blk in $PAGE_SIZE 1048576 $file_size; do
10708                 cancel_lru_locks osc
10709                 echo "Reset readahead stats"
10710                 $LCTL set_param -n llite.*.read_ahead_stats=0
10711                 local count=$(($file_size / $blk))
10712                 dd if=$DIR/$tfile bs=$blk count=$count of=/dev/null
10713                 local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
10714                              get_named_value 'failed.to.fast.read' | calc_total)
10715                 $LCTL get_param -n llite.*.read_ahead_stats
10716                 [ $miss -eq $count ] || error "expected $count got $miss"
10717         done
10718
10719         rm -f $p $DIR/$tfile
10720 }
10721 run_test 101j "A complete read block should be submitted when no RA"
10722
10723 setup_test102() {
10724         test_mkdir $DIR/$tdir
10725         chown $RUNAS_ID $DIR/$tdir
10726         STRIPE_SIZE=65536
10727         STRIPE_OFFSET=1
10728         STRIPE_COUNT=$OSTCOUNT
10729         [[ $OSTCOUNT -gt 4 ]] && STRIPE_COUNT=4
10730
10731         trap cleanup_test102 EXIT
10732         cd $DIR
10733         $1 $LFS setstripe -S $STRIPE_SIZE -i $STRIPE_OFFSET -c $STRIPE_COUNT $tdir
10734         cd $DIR/$tdir
10735         for num in 1 2 3 4; do
10736                 for count in $(seq 1 $STRIPE_COUNT); do
10737                         for idx in $(seq 0 $[$STRIPE_COUNT - 1]); do
10738                                 local size=`expr $STRIPE_SIZE \* $num`
10739                                 local file=file"$num-$idx-$count"
10740                                 $1 $LFS setstripe -S $size -i $idx -c $count $file
10741                         done
10742                 done
10743         done
10744
10745         cd $DIR
10746         $1 tar cf $TMP/f102.tar $tdir --xattrs
10747 }
10748
10749 cleanup_test102() {
10750         trap 0
10751         rm -f $TMP/f102.tar
10752         rm -rf $DIR/d0.sanity/d102
10753 }
10754
10755 test_102a() {
10756         [ "$UID" != 0 ] && skip "must run as root"
10757         [ -z "$(lctl get_param -n mdc.*-mdc-*.connect_flags | grep xattr)" ] &&
10758                 skip_env "must have user_xattr"
10759
10760         [ -z "$(which setfattr 2>/dev/null)" ] &&
10761                 skip_env "could not find setfattr"
10762
10763         local testfile=$DIR/$tfile
10764
10765         touch $testfile
10766         echo "set/get xattr..."
10767         setfattr -n trusted.name1 -v value1 $testfile ||
10768                 error "setfattr -n trusted.name1=value1 $testfile failed"
10769         getfattr -n trusted.name1 $testfile 2> /dev/null |
10770           grep "trusted.name1=.value1" ||
10771                 error "$testfile missing trusted.name1=value1"
10772
10773         setfattr -n user.author1 -v author1 $testfile ||
10774                 error "setfattr -n user.author1=author1 $testfile failed"
10775         getfattr -n user.author1 $testfile 2> /dev/null |
10776           grep "user.author1=.author1" ||
10777                 error "$testfile missing trusted.author1=author1"
10778
10779         echo "listxattr..."
10780         setfattr -n trusted.name2 -v value2 $testfile ||
10781                 error "$testfile unable to set trusted.name2"
10782         setfattr -n trusted.name3 -v value3 $testfile ||
10783                 error "$testfile unable to set trusted.name3"
10784         [ $(getfattr -d -m "^trusted" $testfile 2> /dev/null |
10785             grep "trusted.name" | wc -l) -eq 3 ] ||
10786                 error "$testfile missing 3 trusted.name xattrs"
10787
10788         setfattr -n user.author2 -v author2 $testfile ||
10789                 error "$testfile unable to set user.author2"
10790         setfattr -n user.author3 -v author3 $testfile ||
10791                 error "$testfile unable to set user.author3"
10792         [ $(getfattr -d -m "^user" $testfile 2> /dev/null |
10793             grep "user.author" | wc -l) -eq 3 ] ||
10794                 error "$testfile missing 3 user.author xattrs"
10795
10796         echo "remove xattr..."
10797         setfattr -x trusted.name1 $testfile ||
10798                 error "$testfile error deleting trusted.name1"
10799         getfattr -d -m trusted $testfile 2> /dev/null | grep "trusted.name1" &&
10800                 error "$testfile did not delete trusted.name1 xattr"
10801
10802         setfattr -x user.author1 $testfile ||
10803                 error "$testfile error deleting user.author1"
10804         echo "set lustre special xattr ..."
10805         $LFS setstripe -c1 $testfile
10806         local lovea=$(getfattr -n "trusted.lov" -e hex $testfile |
10807                 awk -F "=" '/trusted.lov/ { print $2 }' )
10808         setfattr -n "trusted.lov" -v $lovea $testfile ||
10809                 error "$testfile doesn't ignore setting trusted.lov again"
10810         setfattr -n "trusted.lov" -v "invalid_value" $testfile &&
10811                 error "$testfile allow setting invalid trusted.lov"
10812         rm -f $testfile
10813 }
10814 run_test 102a "user xattr test =================================="
10815
10816 check_102b_layout() {
10817         local layout="$*"
10818         local testfile=$DIR/$tfile
10819
10820         echo "test layout '$layout'"
10821         $LFS setstripe $layout $testfile || error "setstripe failed"
10822         $LFS getstripe -y $testfile
10823
10824         echo "get/set/list trusted.lov xattr ..." # b=10930
10825         local value=$(getfattr -n trusted.lov -e hex $testfile | grep trusted)
10826         [[ "$value" =~ "trusted.lov" ]] ||
10827                 error "can't get trusted.lov from $testfile"
10828         local stripe_count_orig=$($LFS getstripe -c $testfile) ||
10829                 error "getstripe failed"
10830
10831         $MCREATE $testfile.2 || error "mcreate $testfile.2 failed"
10832
10833         value=$(cut -d= -f2 <<<$value)
10834         # LU-13168: truncated xattr should fail if short lov_user_md header
10835         [ $CLIENT_VERSION -lt $(version_code 2.13.53) ] &&
10836                 lens="${#value}" || lens="$(seq 4 2 ${#value})"
10837         for len in $lens; do
10838                 echo "setfattr $len $testfile.2"
10839                 setfattr -n trusted.lov -v ${value:0:$len} $testfile.2 &&
10840                         [ $len -lt 66 ] && error "short xattr len=$len worked"
10841         done
10842         local stripe_size=$($LFS getstripe -S $testfile.2)
10843         local stripe_count=$($LFS getstripe -c $testfile.2)
10844         [[ $stripe_size -eq 65536 ]] ||
10845                 error "stripe size $stripe_size != 65536"
10846         [[ $stripe_count -eq $stripe_count_orig ]] ||
10847                 error "stripe count $stripe_count != $stripe_count_orig"
10848         rm $testfile $testfile.2
10849 }
10850
10851 test_102b() {
10852         [ -z "$(which setfattr 2>/dev/null)" ] &&
10853                 skip_env "could not find setfattr"
10854         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
10855
10856         # check plain layout
10857         check_102b_layout -S 65536 -i 1 -c $OSTCOUNT
10858
10859         # and also check composite layout
10860         check_102b_layout -E 1M -S 65536 -i 1 -c $OSTCOUNT -Eeof -S4M
10861
10862 }
10863 run_test 102b "getfattr/setfattr for trusted.lov EAs"
10864
10865 test_102c() {
10866         [ -z "$(which setfattr 2>/dev/null)" ] &&
10867                 skip_env "could not find setfattr"
10868         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
10869
10870         # b10930: get/set/list lustre.lov xattr
10871         echo "get/set/list lustre.lov xattr ..."
10872         test_mkdir $DIR/$tdir
10873         chown $RUNAS_ID $DIR/$tdir
10874         local testfile=$DIR/$tdir/$tfile
10875         $RUNAS $LFS setstripe -S 65536 -i 1 -c $OSTCOUNT $testfile ||
10876                 error "setstripe failed"
10877         local STRIPECOUNT=$($RUNAS $LFS getstripe -c $testfile) ||
10878                 error "getstripe failed"
10879         $RUNAS getfattr -d -m "^lustre" $testfile 2> /dev/null | \
10880         grep "lustre.lov" || error "can't get lustre.lov from $testfile"
10881
10882         local testfile2=${testfile}2
10883         local value=`getfattr -n lustre.lov $testfile 2> /dev/null | \
10884                      grep "lustre.lov" |sed -e 's/[^=]\+=//'  `
10885
10886         $RUNAS $MCREATE $testfile2
10887         $RUNAS setfattr -n lustre.lov -v $value $testfile2
10888         local stripe_size=$($RUNAS $LFS getstripe -S $testfile2)
10889         local stripe_count=$($RUNAS $LFS getstripe -c $testfile2)
10890         [ $stripe_size -eq 65536 ] || error "stripe size $stripe_size != 65536"
10891         [ $stripe_count -eq $STRIPECOUNT ] ||
10892                 error "stripe count $stripe_count != $STRIPECOUNT"
10893 }
10894 run_test 102c "non-root getfattr/setfattr for lustre.lov EAs ==========="
10895
10896 compare_stripe_info1() {
10897         local stripe_index_all_zero=true
10898
10899         for num in 1 2 3 4; do
10900                 for count in $(seq 1 $STRIPE_COUNT); do
10901                         for offset in $(seq 0 $[$STRIPE_COUNT - 1]); do
10902                                 local size=$((STRIPE_SIZE * num))
10903                                 local file=file"$num-$offset-$count"
10904                                 stripe_size=$($LFS getstripe -S $PWD/$file)
10905                                 [[ $stripe_size -ne $size ]] &&
10906                                     error "$file: size $stripe_size != $size"
10907                                 stripe_count=$($LFS getstripe -c $PWD/$file)
10908                                 # allow fewer stripes to be created, ORI-601
10909                                 [[ $stripe_count -lt $(((3 * count + 3) / 4)) ]] &&
10910                                     error "$file: count $stripe_count != $count"
10911                                 stripe_index=$($LFS getstripe -i $PWD/$file)
10912                                 [[ $stripe_index -ne 0 ]] &&
10913                                         stripe_index_all_zero=false
10914                         done
10915                 done
10916         done
10917         $stripe_index_all_zero &&
10918                 error "all files are being extracted starting from OST index 0"
10919         return 0
10920 }
10921
10922 have_xattrs_include() {
10923         tar --help | grep -q xattrs-include &&
10924                 echo --xattrs-include="lustre.*"
10925 }
10926
10927 test_102d() {
10928         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10929         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
10930
10931         XINC=$(have_xattrs_include)
10932         setup_test102
10933         tar xf $TMP/f102.tar -C $DIR/$tdir --xattrs $XINC
10934         cd $DIR/$tdir/$tdir
10935         compare_stripe_info1
10936 }
10937 run_test 102d "tar restore stripe info from tarfile,not keep osts"
10938
10939 test_102f() {
10940         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10941         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
10942
10943         XINC=$(have_xattrs_include)
10944         setup_test102
10945         test_mkdir $DIR/$tdir.restore
10946         cd $DIR
10947         tar cf - --xattrs $tdir | tar xf - \
10948                 -C $DIR/$tdir.restore --xattrs $XINC
10949         cd $DIR/$tdir.restore/$tdir
10950         compare_stripe_info1
10951 }
10952 run_test 102f "tar copy files, not keep osts"
10953
10954 grow_xattr() {
10955         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep xattr)" ] &&
10956                 skip "must have user_xattr"
10957         [ -z "$(which setfattr 2>/dev/null)" ] &&
10958                 skip_env "could not find setfattr"
10959         [ -z "$(which getfattr 2>/dev/null)" ] &&
10960                 skip_env "could not find getfattr"
10961
10962         local xsize=${1:-1024}  # in bytes
10963         local file=$DIR/$tfile
10964         local value="$(generate_string $xsize)"
10965         local xbig=trusted.big
10966         local toobig=$2
10967
10968         touch $file
10969         log "save $xbig on $file"
10970         if [ -z "$toobig" ]
10971         then
10972                 setfattr -n $xbig -v $value $file ||
10973                         error "saving $xbig on $file failed"
10974         else
10975                 setfattr -n $xbig -v $value $file &&
10976                         error "saving $xbig on $file succeeded"
10977                 return 0
10978         fi
10979
10980         local orig=$(get_xattr_value $xbig $file)
10981         [[ "$orig" != "$value" ]] && error "$xbig different after saving $xbig"
10982
10983         local xsml=trusted.sml
10984         log "save $xsml on $file"
10985         setfattr -n $xsml -v val $file || error "saving $xsml on $file failed"
10986
10987         local new=$(get_xattr_value $xbig $file)
10988         [[ "$new" != "$orig" ]] && error "$xbig different after saving $xsml"
10989
10990         log "grow $xsml on $file"
10991         setfattr -n $xsml -v "$value" $file ||
10992                 error "growing $xsml on $file failed"
10993
10994         new=$(get_xattr_value $xbig $file)
10995         [[ "$new" != "$orig" ]] && error "$xbig different after growing $xsml"
10996         log "$xbig still valid after growing $xsml"
10997
10998         rm -f $file
10999 }
11000
11001 test_102h() { # bug 15777
11002         grow_xattr 1024
11003 }
11004 run_test 102h "grow xattr from inside inode to external block"
11005
11006 test_102ha() {
11007         large_xattr_enabled || skip_env "ea_inode feature disabled"
11008
11009         echo "setting xattr of max xattr size: $(max_xattr_size)"
11010         grow_xattr $(max_xattr_size)
11011
11012         echo "setting xattr of > max xattr size: $(max_xattr_size) + 10"
11013         echo "This should fail:"
11014         grow_xattr $(($(max_xattr_size) + 10)) 1
11015 }
11016 run_test 102ha "grow xattr from inside inode to external inode"
11017
11018 test_102i() { # bug 17038
11019         [ -z "$(which getfattr 2>/dev/null)" ] &&
11020                 skip "could not find getfattr"
11021
11022         touch $DIR/$tfile
11023         ln -s $DIR/$tfile $DIR/${tfile}link
11024         getfattr -n trusted.lov $DIR/$tfile ||
11025                 error "lgetxattr on $DIR/$tfile failed"
11026         getfattr -h -n trusted.lov $DIR/${tfile}link 2>&1 |
11027                 grep -i "no such attr" ||
11028                 error "error for lgetxattr on $DIR/${tfile}link is not ENODATA"
11029         rm -f $DIR/$tfile $DIR/${tfile}link
11030 }
11031 run_test 102i "lgetxattr test on symbolic link ============"
11032
11033 test_102j() {
11034         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11035         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11036
11037         XINC=$(have_xattrs_include)
11038         setup_test102 "$RUNAS"
11039         chown $RUNAS_ID $DIR/$tdir
11040         $RUNAS tar xf $TMP/f102.tar -C $DIR/$tdir --xattrs $XINC
11041         cd $DIR/$tdir/$tdir
11042         compare_stripe_info1 "$RUNAS"
11043 }
11044 run_test 102j "non-root tar restore stripe info from tarfile, not keep osts ==="
11045
11046 test_102k() {
11047         [ -z "$(which setfattr 2>/dev/null)" ] &&
11048                 skip "could not find setfattr"
11049
11050         touch $DIR/$tfile
11051         # b22187 just check that does not crash for regular file.
11052         setfattr -n trusted.lov $DIR/$tfile
11053         # b22187 'setfattr -n trusted.lov' should remove LOV EA for directories
11054         local test_kdir=$DIR/$tdir
11055         test_mkdir $test_kdir
11056         local default_size=$($LFS getstripe -S $test_kdir)
11057         local default_count=$($LFS getstripe -c $test_kdir)
11058         local default_offset=$($LFS getstripe -i $test_kdir)
11059         $LFS setstripe -S 65536 -i 0 -c $OSTCOUNT $test_kdir ||
11060                 error 'dir setstripe failed'
11061         setfattr -n trusted.lov $test_kdir
11062         local stripe_size=$($LFS getstripe -S $test_kdir)
11063         local stripe_count=$($LFS getstripe -c $test_kdir)
11064         local stripe_offset=$($LFS getstripe -i $test_kdir)
11065         [ $stripe_size -eq $default_size ] ||
11066                 error "stripe size $stripe_size != $default_size"
11067         [ $stripe_count -eq $default_count ] ||
11068                 error "stripe count $stripe_count != $default_count"
11069         [ $stripe_offset -eq $default_offset ] ||
11070                 error "stripe offset $stripe_offset != $default_offset"
11071         rm -rf $DIR/$tfile $test_kdir
11072 }
11073 run_test 102k "setfattr without parameter of value shouldn't cause a crash"
11074
11075 test_102l() {
11076         [ -z "$(which getfattr 2>/dev/null)" ] &&
11077                 skip "could not find getfattr"
11078
11079         # LU-532 trusted. xattr is invisible to non-root
11080         local testfile=$DIR/$tfile
11081
11082         touch $testfile
11083
11084         echo "listxattr as user..."
11085         chown $RUNAS_ID $testfile
11086         $RUNAS getfattr -d -m '.*' $testfile 2>&1 |
11087             grep -q "trusted" &&
11088                 error "$testfile trusted xattrs are user visible"
11089
11090         return 0;
11091 }
11092 run_test 102l "listxattr size test =================================="
11093
11094 test_102m() { # LU-3403 llite: error of listxattr when buffer is small
11095         local path=$DIR/$tfile
11096         touch $path
11097
11098         listxattr_size_check $path || error "listattr_size_check $path failed"
11099 }
11100 run_test 102m "Ensure listxattr fails on small bufffer ========"
11101
11102 cleanup_test102
11103
11104 getxattr() { # getxattr path name
11105         # Return the base64 encoding of the value of xattr name on path.
11106         local path=$1
11107         local name=$2
11108
11109         # # getfattr --absolute-names --encoding=base64 --name=trusted.lov $path
11110         # file: $path
11111         # trusted.lov=0s0AvRCwEAAAAGAAAAAAAAAAAEAAACAAAAAAAQAAEAA...AAAAAAAAA=
11112         #
11113         # We print just 0s0AvRCwEAAAAGAAAAAAAAAAAEAAACAAAAAAAQAAEAA...AAAAAAAAA=
11114
11115         getfattr --absolute-names --encoding=base64 --name=$name $path |
11116                 awk -F= -v name=$name '$1 == name {
11117                         print substr($0, index($0, "=") + 1);
11118         }'
11119 }
11120
11121 test_102n() { # LU-4101 mdt: protect internal xattrs
11122         [ -z "$(which setfattr 2>/dev/null)" ] &&
11123                 skip "could not find setfattr"
11124         if [ $MDS1_VERSION -lt $(version_code 2.5.50) ]
11125         then
11126                 skip "MDT < 2.5.50 allows setxattr on internal trusted xattrs"
11127         fi
11128
11129         local file0=$DIR/$tfile.0
11130         local file1=$DIR/$tfile.1
11131         local xattr0=$TMP/$tfile.0
11132         local xattr1=$TMP/$tfile.1
11133         local namelist="lov lma lmv link fid version som hsm"
11134         local name
11135         local value
11136
11137         rm -rf $file0 $file1 $xattr0 $xattr1
11138         touch $file0 $file1
11139
11140         # Get 'before' xattrs of $file1.
11141         getfattr --absolute-names --dump --match=- $file1 > $xattr0
11142
11143         [ $MDS1_VERSION -lt $(version_code 2.8.53) ] &&
11144                 namelist+=" lfsck_namespace"
11145         for name in $namelist; do
11146                 # Try to copy xattr from $file0 to $file1.
11147                 value=$(getxattr $file0 trusted.$name 2> /dev/null)
11148
11149                 setfattr --name=trusted.$name --value="$value" $file1 ||
11150                         error "setxattr 'trusted.$name' failed"
11151
11152                 # Try to set a garbage xattr.
11153                 value=0sVGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIGl0c2VsZi4=
11154
11155                 if [[ x$name == "xlov" ]]; then
11156                         setfattr --name=trusted.lov --value="$value" $file1 &&
11157                         error "setxattr invalid 'trusted.lov' success"
11158                 else
11159                         setfattr --name=trusted.$name --value="$value" $file1 ||
11160                                 error "setxattr invalid 'trusted.$name' failed"
11161                 fi
11162
11163                 # Try to remove the xattr from $file1. We don't care if this
11164                 # appears to succeed or fail, we just don't want there to be
11165                 # any changes or crashes.
11166                 setfattr --remove=$trusted.$name $file1 2> /dev/null
11167         done
11168
11169         if [ $MDS1_VERSION -gt $(version_code 2.6.50) ]
11170         then
11171                 name="lfsck_ns"
11172                 # Try to copy xattr from $file0 to $file1.
11173                 value=$(getxattr $file0 trusted.$name 2> /dev/null)
11174
11175                 setfattr --name=trusted.$name --value="$value" $file1 ||
11176                         error "setxattr 'trusted.$name' failed"
11177
11178                 # Try to set a garbage xattr.
11179                 value=0sVGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIGl0c2VsZi4=
11180
11181                 setfattr --name=trusted.$name --value="$value" $file1 ||
11182                         error "setxattr 'trusted.$name' failed"
11183
11184                 # Try to remove the xattr from $file1. We don't care if this
11185                 # appears to succeed or fail, we just don't want there to be
11186                 # any changes or crashes.
11187                 setfattr --remove=$trusted.$name $file1 2> /dev/null
11188         fi
11189
11190         # Get 'after' xattrs of file1.
11191         getfattr --absolute-names --dump --match=- $file1 > $xattr1
11192
11193         if ! diff $xattr0 $xattr1; then
11194                 error "before and after xattrs of '$file1' differ"
11195         fi
11196
11197         rm -rf $file0 $file1 $xattr0 $xattr1
11198
11199         return 0
11200 }
11201 run_test 102n "silently ignore setxattr on internal trusted xattrs"
11202
11203 test_102p() { # LU-4703 setxattr did not check ownership
11204         [ $MDS1_VERSION -lt $(version_code 2.5.56) ] &&
11205                 skip "MDS needs to be at least 2.5.56"
11206
11207         local testfile=$DIR/$tfile
11208
11209         touch $testfile
11210
11211         echo "setfacl as user..."
11212         $RUNAS setfacl -m "u:$RUNAS_ID:rwx" $testfile
11213         [ $? -ne 0 ] || error "setfacl by $RUNAS_ID was allowed on $testfile"
11214
11215         echo "setfattr as user..."
11216         setfacl -m "u:$RUNAS_ID:---" $testfile
11217         $RUNAS setfattr -x system.posix_acl_access $testfile
11218         [ $? -ne 0 ] || error "setfattr by $RUNAS_ID was allowed on $testfile"
11219 }
11220 run_test 102p "check setxattr(2) correctly fails without permission"
11221
11222 test_102q() {
11223         [ $MDS1_VERSION -lt $(version_code 2.6.92) ] &&
11224                 skip "MDS needs to be at least 2.6.92"
11225
11226         orphan_linkea_check $DIR/$tfile || error "orphan_linkea_check"
11227 }
11228 run_test 102q "flistxattr should not return trusted.link EAs for orphans"
11229
11230 test_102r() {
11231         [ $MDS1_VERSION -lt $(version_code 2.6.93) ] &&
11232                 skip "MDS needs to be at least 2.6.93"
11233
11234         touch $DIR/$tfile || error "touch"
11235         setfattr -n user.$(basename $tfile) $DIR/$tfile || error "setfattr"
11236         getfattr -n user.$(basename $tfile) $DIR/$tfile || error "getfattr"
11237         rm $DIR/$tfile || error "rm"
11238
11239         #normal directory
11240         mkdir -p $DIR/$tdir || error "mkdir"
11241         setfattr -n user.$(basename $tdir) $DIR/$tdir || error "setfattr dir"
11242         getfattr -n user.$(basename $tdir) $DIR/$tdir || error "getfattr dir"
11243         setfattr -x user.$(basename $tdir) $DIR/$tdir ||
11244                 error "$testfile error deleting user.author1"
11245         getfattr -d -m user.$(basename $tdir) 2> /dev/null |
11246                 grep "user.$(basename $tdir)" &&
11247                 error "$tdir did not delete user.$(basename $tdir)"
11248         rmdir $DIR/$tdir || error "rmdir"
11249
11250         #striped directory
11251         test_mkdir $DIR/$tdir
11252         setfattr -n user.$(basename $tdir) $DIR/$tdir || error "setfattr dir"
11253         getfattr -n user.$(basename $tdir) $DIR/$tdir || error "getfattr dir"
11254         setfattr -x user.$(basename $tdir) $DIR/$tdir ||
11255                 error "$testfile error deleting user.author1"
11256         getfattr -d -m user.$(basename $tdir) 2> /dev/null |
11257                 grep "user.$(basename $tdir)" &&
11258                 error "$tdir did not delete user.$(basename $tdir)"
11259         rmdir $DIR/$tdir || error "rm striped dir"
11260 }
11261 run_test 102r "set EAs with empty values"
11262
11263 test_102s() {
11264         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
11265                 skip "MDS needs to be at least 2.11.52"
11266
11267         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
11268
11269         save_lustre_params client "llite.*.xattr_cache" > $save
11270
11271         for cache in 0 1; do
11272                 lctl set_param llite.*.xattr_cache=$cache
11273
11274                 rm -f $DIR/$tfile
11275                 touch $DIR/$tfile || error "touch"
11276                 for prefix in lustre security system trusted user; do
11277                         # Note getxattr() may fail with 'Operation not
11278                         # supported' or 'No such attribute' depending
11279                         # on prefix and cache.
11280                         getfattr -n $prefix.n102s $DIR/$tfile &&
11281                                 error "getxattr '$prefix.n102s' should fail (cache = $cache)"
11282                 done
11283         done
11284
11285         restore_lustre_params < $save
11286 }
11287 run_test 102s "getting nonexistent xattrs should fail"
11288
11289 test_102t() {
11290         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
11291                 skip "MDS needs to be at least 2.11.52"
11292
11293         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
11294
11295         save_lustre_params client "llite.*.xattr_cache" > $save
11296
11297         for cache in 0 1; do
11298                 lctl set_param llite.*.xattr_cache=$cache
11299
11300                 for buf_size in 0 256; do
11301                         rm -f $DIR/$tfile
11302                         touch $DIR/$tfile || error "touch"
11303                         setfattr -n user.multiop $DIR/$tfile
11304                         $MULTIOP $DIR/$tfile oa$buf_size ||
11305                                 error "cannot get zero length xattr value (buf_size = $buf_size)"
11306                 done
11307         done
11308
11309         restore_lustre_params < $save
11310 }
11311 run_test 102t "zero length xattr values handled correctly"
11312
11313 run_acl_subtest()
11314 {
11315     $LUSTRE/tests/acl/run $LUSTRE/tests/acl/$1.test
11316     return $?
11317 }
11318
11319 test_103a() {
11320         [ "$UID" != 0 ] && skip "must run as root"
11321         $GSS && skip_env "could not run under gss"
11322         [ -z "$(lctl get_param -n mdc.*-mdc-*.connect_flags | grep acl)" ] &&
11323                 skip_env "must have acl enabled"
11324         [ -z "$(which setfacl 2>/dev/null)" ] &&
11325                 skip_env "could not find setfacl"
11326         remote_mds_nodsh && skip "remote MDS with nodsh"
11327
11328         gpasswd -a daemon bin                           # LU-5641
11329         do_facet $SINGLEMDS gpasswd -a daemon bin       # LU-5641
11330
11331         declare -a identity_old
11332
11333         for num in $(seq $MDSCOUNT); do
11334                 switch_identity $num true || identity_old[$num]=$?
11335         done
11336
11337         SAVE_UMASK=$(umask)
11338         umask 0022
11339         mkdir -p $DIR/$tdir
11340         cd $DIR/$tdir
11341
11342         echo "performing cp ..."
11343         run_acl_subtest cp || error "run_acl_subtest cp failed"
11344         echo "performing getfacl-noacl..."
11345         run_acl_subtest getfacl-noacl || error "getfacl-noacl test failed"
11346         echo "performing misc..."
11347         run_acl_subtest misc || error  "misc test failed"
11348         echo "performing permissions..."
11349         run_acl_subtest permissions || error "permissions failed"
11350         # LU-1482 mdd: Setting xattr are properly checked with and without ACLs
11351         if [ $MDS1_VERSION -gt $(version_code 2.8.55) ] ||
11352                 { [ $MDS1_VERSION -lt $(version_code 2.6) ] &&
11353                         [ $MDS1_VERSION -ge $(version_code 2.5.29) ]; }
11354         then
11355                 echo "performing permissions xattr..."
11356                 run_acl_subtest permissions_xattr ||
11357                         error "permissions_xattr failed"
11358         fi
11359         echo "performing setfacl..."
11360         run_acl_subtest setfacl || error  "setfacl test failed"
11361
11362         # inheritance test got from HP
11363         echo "performing inheritance..."
11364         cp $LUSTRE/tests/acl/make-tree . || error "cannot copy make-tree"
11365         chmod +x make-tree || error "chmod +x failed"
11366         run_acl_subtest inheritance || error "inheritance test failed"
11367         rm -f make-tree
11368
11369         echo "LU-974 ignore umask when acl is enabled..."
11370         run_acl_subtest 974 || error "LU-974 umask test failed"
11371         if [ $MDSCOUNT -ge 2 ]; then
11372                 run_acl_subtest 974_remote ||
11373                         error "LU-974 umask test failed under remote dir"
11374         fi
11375
11376         echo "LU-2561 newly created file is same size as directory..."
11377         if [ "$mds1_FSTYPE" != "zfs" ]; then
11378                 run_acl_subtest 2561 || error "LU-2561 test failed"
11379         else
11380                 run_acl_subtest 2561_zfs || error "LU-2561 zfs test failed"
11381         fi
11382
11383         run_acl_subtest 4924 || error "LU-4924 test failed"
11384
11385         cd $SAVE_PWD
11386         umask $SAVE_UMASK
11387
11388         for num in $(seq $MDSCOUNT); do
11389                 if [ "${identity_old[$num]}" = 1 ]; then
11390                         switch_identity $num false || identity_old[$num]=$?
11391                 fi
11392         done
11393 }
11394 run_test 103a "acl test"
11395
11396 test_103b() {
11397         declare -a pids
11398         local U
11399
11400         for U in {0..511}; do
11401                 {
11402                 local O=$(printf "%04o" $U)
11403
11404                 umask $(printf "%04o" $((511 ^ $O)))
11405                 $LFS setstripe -c 1 $DIR/$tfile.s$O
11406                 local S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.s$O))
11407
11408                 (( $S == ($O & 0666) )) ||
11409                         error "lfs setstripe $DIR/$tfile.s$O '$S' != '$O'"
11410
11411                 $LFS setstripe -E16M -c 1 -E1G -S4M $DIR/$tfile.p$O
11412                 S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.p$O))
11413                 (( $S == ($O & 0666) )) ||
11414                         error "lfs setstripe -E $DIR/$tfile.p$O '$S' != '$O'"
11415
11416                 $LFS setstripe -N2 -c 1 $DIR/$tfile.m$O
11417                 S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.m$O))
11418                 (( $S == ($O & 0666) )) ||
11419                         error "lfs setstripe -N2 $DIR/$tfile.m$O '$S' != '$O'"
11420                 rm -f $DIR/$tfile.[smp]$0
11421                 } &
11422                 local pid=$!
11423
11424                 # limit the concurrently running threads to 64. LU-11878
11425                 local idx=$((U % 64))
11426                 [ -z "${pids[idx]}" ] || wait ${pids[idx]}
11427                 pids[idx]=$pid
11428         done
11429         wait
11430 }
11431 run_test 103b "umask lfs setstripe"
11432
11433 test_103c() {
11434         mkdir -p $DIR/$tdir
11435         cp -rp $DIR/$tdir $DIR/$tdir.bak
11436
11437         [ -n "$(getfattr -d -m. $DIR/$tdir | grep posix_acl_default)" ] &&
11438                 error "$DIR/$tdir shouldn't contain default ACL"
11439         [ -n "$(getfattr -d -m. $DIR/$tdir.bak | grep posix_acl_default)" ] &&
11440                 error "$DIR/$tdir.bak shouldn't contain default ACL"
11441         true
11442 }
11443 run_test 103c "'cp -rp' won't set empty acl"
11444
11445 test_103e() {
11446         local numacl
11447         local fileacl
11448         local saved_debug=$($LCTL get_param -n debug)
11449
11450         (( $MDS1_VERSION >= $(version_code 2.14.0) )) ||
11451                 skip "MDS needs to be at least 2.14.0"
11452
11453         large_xattr_enabled || skip_env "ea_inode feature disabled"
11454
11455         mkdir -p $DIR/$tdir
11456         # add big LOV EA to cause reply buffer overflow earlier
11457         $LFS setstripe -C 1000 $DIR/$tdir
11458         lctl set_param mdc.*-mdc*.stats=clear
11459
11460         $LCTL set_param debug=0
11461         stack_trap "$LCTL set_param debug=\"$saved_debug\"" EXIT
11462         stack_trap "$LCTL get_param mdc.*-mdc*.stats" EXIT
11463
11464         # add a large number of default ACLs (expect 8000+ for 2.13+)
11465         for U in {2..7000}; do
11466                 setfacl -d -m user:$U:rwx $DIR/$tdir ||
11467                         error "Able to add just $U default ACLs"
11468         done
11469         numacl=$(getfacl $DIR/$tdir |& grep -c "default:user")
11470         echo "$numacl default ACLs created"
11471
11472         stat $DIR/$tdir || error "Cannot stat directory"
11473         # check file creation
11474         touch $DIR/$tdir/$tfile ||
11475                 error "failed to create $tfile with $numacl default ACLs"
11476         stat $DIR/$tdir/$tfile  || error "Cannot stat file"
11477         fileacl=$(getfacl $DIR/$tdir/$tfile |& grep -c "user:")
11478         echo "$fileacl ACLs were inherited"
11479         (( $fileacl == $numacl )) ||
11480                 error "Not all default ACLs were inherited: $numacl != $fileacl"
11481         # check that new ACLs creation adds new ACLs to inherited ACLs
11482         setfacl -m user:19000:rwx $DIR/$tdir/$tfile ||
11483                 error "Cannot set new ACL"
11484         numacl=$((numacl + 1))
11485         fileacl=$(getfacl $DIR/$tdir/$tfile |& grep -c "user:")
11486         (( $fileacl == $numacl )) ||
11487                 error "failed to add new ACL: $fileacl != $numacl as expected"
11488         # adds more ACLs to a file to reach their maximum at 8000+
11489         numacl=0
11490         for U in {20000..25000}; do
11491                 setfacl -m user:$U:rwx $DIR/$tdir/$tfile || break
11492                 numacl=$((numacl + 1))
11493         done
11494         echo "Added $numacl more ACLs to the file"
11495         fileacl=$(getfacl $DIR/$tdir/$tfile |& grep -c "user:")
11496         echo "Total $fileacl ACLs in file"
11497         stat $DIR/$tdir/$tfile > /dev/null || error "Cannot stat file"
11498         rm -f $DIR/$tdir/$tfile || error "Cannot remove file"
11499         rmdir $DIR/$tdir || error "Cannot remove directory"
11500 }
11501 run_test 103e "inheritance of big amount of default ACLs"
11502
11503 test_103f() {
11504         (( $MDS1_VERSION >= $(version_code 2.14.51) )) ||
11505                 skip "MDS needs to be at least 2.14.51"
11506
11507         large_xattr_enabled || skip_env "ea_inode feature disabled"
11508
11509         # enable changelog to consume more internal MDD buffers
11510         changelog_register
11511
11512         mkdir -p $DIR/$tdir
11513         # add big LOV EA
11514         $LFS setstripe -C 1000 $DIR/$tdir
11515         setfacl -d -m user:$U:rwx $DIR/$tdir || error "Cannot add default ACLs"
11516         mkdir $DIR/$tdir/inherited || error "failed to create subdirectory"
11517         rmdir $DIR/$tdir/inherited || error "Cannot remove subdirectory"
11518         rmdir $DIR/$tdir || error "Cannot remove directory"
11519 }
11520 run_test 103f "changelog doesn't interfere with default ACLs buffers"
11521
11522 test_104a() {
11523         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11524
11525         touch $DIR/$tfile
11526         lfs df || error "lfs df failed"
11527         lfs df -ih || error "lfs df -ih failed"
11528         lfs df -h $DIR || error "lfs df -h $DIR failed"
11529         lfs df -i $DIR || error "lfs df -i $DIR failed"
11530         lfs df $DIR/$tfile || error "lfs df $DIR/$tfile failed"
11531         lfs df -ih $DIR/$tfile || error "lfs df -ih $DIR/$tfile failed"
11532
11533         local OSC=$(lctl dl | grep OST0000-osc-[^M] | awk '{ print $4 }')
11534         lctl --device %$OSC deactivate
11535         lfs df || error "lfs df with deactivated OSC failed"
11536         lctl --device %$OSC activate
11537         # wait the osc back to normal
11538         wait_osc_import_ready client ost
11539
11540         lfs df || error "lfs df with reactivated OSC failed"
11541         rm -f $DIR/$tfile
11542 }
11543 run_test 104a "lfs df [-ih] [path] test ========================="
11544
11545 test_104b() {
11546         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11547         [ $RUNAS_ID -eq $UID ] &&
11548                 skip_env "RUNAS_ID = UID = $UID -- skipping"
11549
11550         denied_cnt=$(($($RUNAS $LFS check servers 2>&1 |
11551                         grep "Permission denied" | wc -l)))
11552         if [ $denied_cnt -ne 0 ]; then
11553                 error "lfs check servers test failed"
11554         fi
11555 }
11556 run_test 104b "$RUNAS lfs check servers test ===================="
11557
11558 #
11559 # Verify $1 is within range of $2.
11560 # Success when $1 is within range. That is, when $1 is >= 2% of $2 and
11561 # $1 is <= 2% of $2. Else Fail.
11562 #
11563 value_in_range() {
11564         # Strip all units (M, G, T)
11565         actual=$(echo $1 | tr -d A-Z)
11566         expect=$(echo $2 | tr -d A-Z)
11567
11568         expect_lo=$(($expect * 98 / 100)) # 2% below
11569         expect_hi=$(($expect * 102 / 100)) # 2% above
11570
11571         # permit 2% drift above and below
11572         (( $actual >= $expect_lo && $actual <= $expect_hi ))
11573 }
11574
11575 test_104c() {
11576         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11577         [ "$ost1_FSTYPE" == "zfs" ] || skip "zfs only test"
11578
11579         local ost_param="osd-zfs.$FSNAME-OST0000."
11580         local mdt_param="osd-zfs.$FSNAME-MDT0000."
11581         local ofacets=$(get_facets OST)
11582         local mfacets=$(get_facets MDS)
11583         local saved_ost_blocks=
11584         local saved_mdt_blocks=
11585
11586         echo "Before recordsize change"
11587         lfs_df=($($LFS df -h | grep "filesystem_summary:"))
11588         df=($(df -h | grep "/mnt/lustre"$))
11589
11590         # For checking.
11591         echo "lfs output : ${lfs_df[*]}"
11592         echo "df  output : ${df[*]}"
11593
11594         for facet in ${ofacets//,/ }; do
11595                 if [ -z $saved_ost_blocks ]; then
11596                         saved_ost_blocks=$(do_facet $facet \
11597                                 lctl get_param -n $ost_param.blocksize)
11598                         echo "OST Blocksize: $saved_ost_blocks"
11599                 fi
11600                 ost=$(do_facet $facet lctl get_param -n $ost_param.mntdev)
11601                 do_facet $facet zfs set recordsize=32768 $ost
11602         done
11603
11604         # BS too small. Sufficient for functional testing.
11605         for facet in ${mfacets//,/ }; do
11606                 if [ -z $saved_mdt_blocks ]; then
11607                         saved_mdt_blocks=$(do_facet $facet \
11608                                 lctl get_param -n $mdt_param.blocksize)
11609                         echo "MDT Blocksize: $saved_mdt_blocks"
11610                 fi
11611                 mdt=$(do_facet $facet lctl get_param -n $mdt_param.mntdev)
11612                 do_facet $facet zfs set recordsize=32768 $mdt
11613         done
11614
11615         # Give new values chance to reflect change
11616         sleep 2
11617
11618         echo "After recordsize change"
11619         lfs_df_after=($($LFS df -h | grep "filesystem_summary:"))
11620         df_after=($(df -h | grep "/mnt/lustre"$))
11621
11622         # For checking.
11623         echo "lfs output : ${lfs_df_after[*]}"
11624         echo "df  output : ${df_after[*]}"
11625
11626         # Verify lfs df
11627         value_in_range ${lfs_df_after[1]%.*} ${lfs_df[1]%.*} ||
11628                 error "lfs_df bytes: ${lfs_df_after[1]%.*} != ${lfs_df[1]%.*}"
11629         value_in_range ${lfs_df_after[2]%.*} ${lfs_df[2]%.*} ||
11630                 error "lfs_df used: ${lfs_df_after[2]%.*} != ${lfs_df[2]%.*}"
11631         value_in_range ${lfs_df_after[3]%.*} ${lfs_df[3]%.*} ||
11632                 error "lfs_df avail: ${lfs_df_after[3]%.*} != ${lfs_df[3]%.*}"
11633
11634         # Verify df
11635         value_in_range ${df_after[1]%.*} ${df[1]%.*} ||
11636                 error "df bytes: ${df_after[1]%.*} != ${df[1]%.*}"
11637         value_in_range ${df_after[2]%.*} ${df[2]%.*} ||
11638                 error "df used: ${df_after[2]%.*} != ${df[2]%.*}"
11639         value_in_range ${df_after[3]%.*} ${df[3]%.*} ||
11640                 error "df avail: ${df_after[3]%.*} != ${df[3]%.*}"
11641
11642         # Restore MDT recordize back to original
11643         for facet in ${mfacets//,/ }; do
11644                 mdt=$(do_facet $facet lctl get_param -n $mdt_param.mntdev)
11645                 do_facet $facet zfs set recordsize=$saved_mdt_blocks $mdt
11646         done
11647
11648         # Restore OST recordize back to original
11649         for facet in ${ofacets//,/ }; do
11650                 ost=$(do_facet $facet lctl get_param -n $ost_param.mntdev)
11651                 do_facet $facet zfs set recordsize=$saved_ost_blocks $ost
11652         done
11653
11654         return 0
11655 }
11656 run_test 104c "Verify df vs lfs_df stays same after recordsize change"
11657
11658 test_105a() {
11659         # doesn't work on 2.4 kernels
11660         touch $DIR/$tfile
11661         if $(flock_is_enabled); then
11662                 flocks_test 1 on -f $DIR/$tfile || error "fail flock on"
11663         else
11664                 flocks_test 1 off -f $DIR/$tfile || error "fail flock off"
11665         fi
11666         rm -f $DIR/$tfile
11667 }
11668 run_test 105a "flock when mounted without -o flock test ========"
11669
11670 test_105b() {
11671         touch $DIR/$tfile
11672         if $(flock_is_enabled); then
11673                 flocks_test 1 on -c $DIR/$tfile || error "fail flock on"
11674         else
11675                 flocks_test 1 off -c $DIR/$tfile || error "fail flock off"
11676         fi
11677         rm -f $DIR/$tfile
11678 }
11679 run_test 105b "fcntl when mounted without -o flock test ========"
11680
11681 test_105c() {
11682         touch $DIR/$tfile
11683         if $(flock_is_enabled); then
11684                 flocks_test 1 on -l $DIR/$tfile || error "fail flock on"
11685         else
11686                 flocks_test 1 off -l $DIR/$tfile || error "fail flock off"
11687         fi
11688         rm -f $DIR/$tfile
11689 }
11690 run_test 105c "lockf when mounted without -o flock test"
11691
11692 test_105d() { # bug 15924
11693         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11694
11695         test_mkdir $DIR/$tdir
11696         flock_is_enabled || skip_env "mount w/o flock enabled"
11697         #define OBD_FAIL_LDLM_CP_CB_WAIT  0x315
11698         $LCTL set_param fail_loc=0x80000315
11699         flocks_test 2 $DIR/$tdir
11700 }
11701 run_test 105d "flock race (should not freeze) ========"
11702
11703 test_105e() { # bug 22660 && 22040
11704         flock_is_enabled || skip_env "mount w/o flock enabled"
11705
11706         touch $DIR/$tfile
11707         flocks_test 3 $DIR/$tfile
11708 }
11709 run_test 105e "Two conflicting flocks from same process"
11710
11711 test_106() { #bug 10921
11712         test_mkdir $DIR/$tdir
11713         $DIR/$tdir && error "exec $DIR/$tdir succeeded"
11714         chmod 777 $DIR/$tdir || error "chmod $DIR/$tdir failed"
11715 }
11716 run_test 106 "attempt exec of dir followed by chown of that dir"
11717
11718 test_107() {
11719         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11720
11721         CDIR=`pwd`
11722         local file=core
11723
11724         cd $DIR
11725         rm -f $file
11726
11727         local save_pattern=$(sysctl -n kernel.core_pattern)
11728         local save_uses_pid=$(sysctl -n kernel.core_uses_pid)
11729         sysctl -w kernel.core_pattern=$file
11730         sysctl -w kernel.core_uses_pid=0
11731
11732         ulimit -c unlimited
11733         sleep 60 &
11734         SLEEPPID=$!
11735
11736         sleep 1
11737
11738         kill -s 11 $SLEEPPID
11739         wait $SLEEPPID
11740         if [ -e $file ]; then
11741                 size=`stat -c%s $file`
11742                 [ $size -eq 0 ] && error "Fail to create core file $file"
11743         else
11744                 error "Fail to create core file $file"
11745         fi
11746         rm -f $file
11747         sysctl -w kernel.core_pattern=$save_pattern
11748         sysctl -w kernel.core_uses_pid=$save_uses_pid
11749         cd $CDIR
11750 }
11751 run_test 107 "Coredump on SIG"
11752
11753 test_110() {
11754         test_mkdir $DIR/$tdir
11755         test_mkdir $DIR/$tdir/$(str_repeat 'a' 255)
11756         $LFS mkdir -c $MDSCOUNT $DIR/$tdir/$(str_repeat 'b' 256) &&
11757                 error "mkdir with 256 char should fail, but did not"
11758         touch $DIR/$tdir/$(str_repeat 'x' 255) ||
11759                 error "create with 255 char failed"
11760         touch $DIR/$tdir/$(str_repeat 'y' 256) &&
11761                 error "create with 256 char should fail, but did not"
11762
11763         ls -l $DIR/$tdir
11764         rm -rf $DIR/$tdir
11765 }
11766 run_test 110 "filename length checking"
11767
11768 #
11769 # Purpose: To verify dynamic thread (OSS) creation.
11770 #
11771 test_115() {
11772         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11773         remote_ost_nodsh && skip "remote OST with nodsh"
11774
11775         # Lustre does not stop service threads once they are started.
11776         # Reset number of running threads to default.
11777         stopall
11778         setupall
11779
11780         local OSTIO_pre
11781         local save_params="$TMP/sanity-$TESTNAME.parameters"
11782
11783         # Get ll_ost_io count before I/O
11784         OSTIO_pre=$(do_facet ost1 \
11785                 "$LCTL get_param ost.OSS.ost_io.threads_started | cut -d= -f2")
11786         # Exit if lustre is not running (ll_ost_io not running).
11787         [ -z "$OSTIO_pre" ] && error "no OSS threads"
11788
11789         echo "Starting with $OSTIO_pre threads"
11790         local thread_max=$((OSTIO_pre * 2))
11791         local rpc_in_flight=$((thread_max * 2))
11792         # Number of I/O Process proposed to be started.
11793         local nfiles
11794         local facets=$(get_facets OST)
11795
11796         save_lustre_params client "osc.*OST*.max_rpcs_in_flight" > $save_params
11797         save_lustre_params $facets "ost.OSS.ost_io.threads_max" >> $save_params
11798
11799         # Set in_flight to $rpc_in_flight
11800         $LCTL set_param osc.*OST*.max_rpcs_in_flight=$rpc_in_flight ||
11801                 error "Failed to set max_rpcs_in_flight to $rpc_in_flight"
11802         nfiles=${rpc_in_flight}
11803         # Set ost thread_max to $thread_max
11804         do_facet ost1 "$LCTL set_param ost.OSS.ost_io.threads_max=$thread_max"
11805
11806         # 5 Minutes should be sufficient for max number of OSS
11807         # threads(thread_max) to be created.
11808         local timeout=300
11809
11810         # Start I/O.
11811         local WTL=${WTL:-"$LUSTRE/tests/write_time_limit"}
11812         test_mkdir $DIR/$tdir
11813         for i in $(seq $nfiles); do
11814                 local file=$DIR/$tdir/${tfile}-$i
11815                 $LFS setstripe -c -1 -i 0 $file
11816                 ($WTL $file $timeout)&
11817         done
11818
11819         # I/O Started - Wait for thread_started to reach thread_max or report
11820         # error if thread_started is more than thread_max.
11821         echo "Waiting for thread_started to reach thread_max"
11822         local thread_started=0
11823         local end_time=$((SECONDS + timeout))
11824
11825         while [ $SECONDS -le $end_time ] ; do
11826                 echo -n "."
11827                 # Get ost i/o thread_started count.
11828                 thread_started=$(do_facet ost1 \
11829                         "$LCTL get_param \
11830                         ost.OSS.ost_io.threads_started | cut -d= -f2")
11831                 # Break out if thread_started is equal/greater than thread_max
11832                 if [[ $thread_started -ge $thread_max ]]; then
11833                         echo ll_ost_io thread_started $thread_started, \
11834                                 equal/greater than thread_max $thread_max
11835                         break
11836                 fi
11837                 sleep 1
11838         done
11839
11840         # Cleanup - We have the numbers, Kill i/o jobs if running.
11841         jobcount=($(jobs -p))
11842         for i in $(seq 0 $((${#jobcount[@]}-1)))
11843         do
11844                 kill -9 ${jobcount[$i]}
11845                 if [ $? -ne 0 ] ; then
11846                         echo Warning: \
11847                         Failed to Kill \'WTL\(I/O\)\' with pid ${jobcount[$i]}
11848                 fi
11849         done
11850
11851         # Cleanup files left by WTL binary.
11852         for i in $(seq $nfiles); do
11853                 local file=$DIR/$tdir/${tfile}-$i
11854                 rm -rf $file
11855                 if [ $? -ne 0 ] ; then
11856                         echo "Warning: Failed to delete file $file"
11857                 fi
11858         done
11859
11860         restore_lustre_params <$save_params
11861         rm -f $save_params || echo "Warning: delete file '$save_params' failed"
11862
11863         # Error out if no new thread has started or Thread started is greater
11864         # than thread max.
11865         if [[ $thread_started -le $OSTIO_pre ||
11866                         $thread_started -gt $thread_max ]]; then
11867                 error "ll_ost_io: thread_started $thread_started" \
11868                       "OSTIO_pre $OSTIO_pre, thread_max $thread_max." \
11869                       "No new thread started or thread started greater " \
11870                       "than thread_max."
11871         fi
11872 }
11873 run_test 115 "verify dynamic thread creation===================="
11874
11875 free_min_max () {
11876         wait_delete_completed
11877         AVAIL=($(lctl get_param -n osc.*[oO][sS][cC]-[^M]*.kbytesavail))
11878         echo "OST kbytes available: ${AVAIL[@]}"
11879         MAXV=${AVAIL[0]}
11880         MAXI=0
11881         MINV=${AVAIL[0]}
11882         MINI=0
11883         for ((i = 0; i < ${#AVAIL[@]}; i++)); do
11884                 #echo OST $i: ${AVAIL[i]}kb
11885                 if [[ ${AVAIL[i]} -gt $MAXV ]]; then
11886                         MAXV=${AVAIL[i]}
11887                         MAXI=$i
11888                 fi
11889                 if [[ ${AVAIL[i]} -lt $MINV ]]; then
11890                         MINV=${AVAIL[i]}
11891                         MINI=$i
11892                 fi
11893         done
11894         echo "Min free space: OST $MINI: $MINV"
11895         echo "Max free space: OST $MAXI: $MAXV"
11896 }
11897
11898 test_116a() { # was previously test_116()
11899         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11900         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11901         remote_mds_nodsh && skip "remote MDS with nodsh"
11902
11903         echo -n "Free space priority "
11904         do_facet $SINGLEMDS lctl get_param -n lo[vd].*-mdtlov.qos_prio_free |
11905                 head -n1
11906         declare -a AVAIL
11907         free_min_max
11908
11909         [ $MINV -eq 0 ] && skip "no free space in OST$MINI, skip"
11910         [ $MINV -gt 10000000 ] && skip "too much free space in OST$MINI, skip"
11911         stack_trap simple_cleanup_common
11912
11913         # Check if we need to generate uneven OSTs
11914         test_mkdir -p $DIR/$tdir/OST${MINI}
11915         local FILL=$((MINV / 4))
11916         local DIFF=$((MAXV - MINV))
11917         local DIFF2=$((DIFF * 100 / MINV))
11918
11919         local threshold=$(do_facet $SINGLEMDS \
11920                 lctl get_param -n *.*MDT0000-mdtlov.qos_threshold_rr | head -n1)
11921         threshold=${threshold%%%}
11922         echo -n "Check for uneven OSTs: "
11923         echo -n "diff=${DIFF}KB (${DIFF2}%) must be > ${threshold}% ..."
11924
11925         if [[ $DIFF2 -gt $threshold ]]; then
11926                 echo "ok"
11927                 echo "Don't need to fill OST$MINI"
11928         else
11929                 # generate uneven OSTs. Write 2% over the QOS threshold value
11930                 echo "no"
11931                 DIFF=$((threshold - DIFF2 + 2))
11932                 DIFF2=$((MINV * DIFF / 100))
11933                 echo "Fill $DIFF% remaining space in OST$MINI with ${DIFF2}KB"
11934                 $LFS setstripe -i $MINI -c 1 $DIR/$tdir/OST${MINI} ||
11935                         error "setstripe failed"
11936                 DIFF=$((DIFF2 / 2048))
11937                 i=0
11938                 while [ $i -lt $DIFF ]; do
11939                         i=$((i + 1))
11940                         dd if=/dev/zero of=$DIR/$tdir/OST${MINI}/$tfile-$i \
11941                                 bs=2M count=1 2>/dev/null
11942                         echo -n .
11943                 done
11944                 echo .
11945                 sync
11946                 sleep_maxage
11947                 free_min_max
11948         fi
11949
11950         DIFF=$((MAXV - MINV))
11951         DIFF2=$((DIFF * 100 / MINV))
11952         echo -n "diff=$DIFF=$DIFF2% must be > $threshold% for QOS mode..."
11953         if [ $DIFF2 -gt $threshold ]; then
11954                 echo "ok"
11955         else
11956                 skip "QOS imbalance criteria not met"
11957         fi
11958
11959         MINI1=$MINI
11960         MINV1=$MINV
11961         MAXI1=$MAXI
11962         MAXV1=$MAXV
11963
11964         # now fill using QOS
11965         $LFS setstripe -c 1 $DIR/$tdir
11966         FILL=$((FILL / 200))
11967         if [ $FILL -gt 600 ]; then
11968                 FILL=600
11969         fi
11970         echo "writing $FILL files to QOS-assigned OSTs"
11971         i=0
11972         while [ $i -lt $FILL ]; do
11973                 i=$((i + 1))
11974                 dd if=/dev/zero of=$DIR/$tdir/$tfile-$i bs=200k \
11975                         count=1 2>/dev/null
11976                 echo -n .
11977         done
11978         echo "wrote $i 200k files"
11979         sync
11980         sleep_maxage
11981
11982         echo "Note: free space may not be updated, so measurements might be off"
11983         free_min_max
11984         DIFF2=$((MAXV - MINV))
11985         echo "free space delta: orig $DIFF final $DIFF2"
11986         [ $DIFF2 -gt $DIFF ] && echo "delta got worse!"
11987         DIFF=$((MINV1 - ${AVAIL[$MINI1]}))
11988         echo "Wrote ${DIFF}KB to smaller OST $MINI1"
11989         DIFF2=$((MAXV1 - ${AVAIL[$MAXI1]}))
11990         echo "Wrote ${DIFF2}KB to larger OST $MAXI1"
11991         if [[ $DIFF -gt 0 ]]; then
11992                 FILL=$((DIFF2 * 100 / DIFF - 100))
11993                 echo "Wrote ${FILL}% more data to larger OST $MAXI1"
11994         fi
11995
11996         # Figure out which files were written where
11997         UUID=$(lctl get_param -n lov.${FSNAME}-clilov-*.target_obd |
11998                awk '/'$MINI1': / {print $2; exit}')
11999         echo $UUID
12000         MINC=$($LFS getstripe --ost $UUID $DIR/$tdir | grep $DIR | wc -l)
12001         echo "$MINC files created on smaller OST $MINI1"
12002         UUID=$(lctl get_param -n lov.${FSNAME}-clilov-*.target_obd |
12003                awk '/'$MAXI1': / {print $2; exit}')
12004         echo $UUID
12005         MAXC=$($LFS getstripe --ost $UUID $DIR/$tdir | grep $DIR | wc -l)
12006         echo "$MAXC files created on larger OST $MAXI1"
12007         if [[ $MINC -gt 0 ]]; then
12008                 FILL=$((MAXC * 100 / MINC - 100))
12009                 echo "Wrote ${FILL}% more files to larger OST $MAXI1"
12010         fi
12011         [[ $MAXC -gt $MINC ]] ||
12012                 error_ignore LU-9 "stripe QOS didn't balance free space"
12013 }
12014 run_test 116a "stripe QOS: free space balance ==================="
12015
12016 test_116b() { # LU-2093
12017         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12018         remote_mds_nodsh && skip "remote MDS with nodsh"
12019
12020 #define OBD_FAIL_MDS_OSC_CREATE_FAIL     0x147
12021         local old_rr=$(do_facet $SINGLEMDS lctl get_param -n \
12022                        lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr | head -1)
12023         [ -z "$old_rr" ] && skip "no QOS"
12024         do_facet $SINGLEMDS lctl set_param \
12025                 lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr=0
12026         mkdir -p $DIR/$tdir
12027         do_facet $SINGLEMDS lctl set_param fail_loc=0x147
12028         createmany -o $DIR/$tdir/f- 20 || error "can't create"
12029         do_facet $SINGLEMDS lctl set_param fail_loc=0
12030         rm -rf $DIR/$tdir
12031         do_facet $SINGLEMDS lctl set_param \
12032                 lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr=$old_rr
12033 }
12034 run_test 116b "QoS shouldn't LBUG if not enough OSTs found on the 2nd pass"
12035
12036 test_117() # bug 10891
12037 {
12038         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12039
12040         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
12041         #define OBD_FAIL_OST_SETATTR_CREDITS 0x21e
12042         lctl set_param fail_loc=0x21e
12043         > $DIR/$tfile || error "truncate failed"
12044         lctl set_param fail_loc=0
12045         echo "Truncate succeeded."
12046         rm -f $DIR/$tfile
12047 }
12048 run_test 117 "verify osd extend =========="
12049
12050 NO_SLOW_RESENDCOUNT=4
12051 export OLD_RESENDCOUNT=""
12052 set_resend_count () {
12053         local PROC_RESENDCOUNT="osc.${FSNAME}-OST*-osc-*.resend_count"
12054         OLD_RESENDCOUNT=$(lctl get_param -n $PROC_RESENDCOUNT | head -n1)
12055         lctl set_param -n $PROC_RESENDCOUNT $1
12056         echo resend_count is set to $(lctl get_param -n $PROC_RESENDCOUNT)
12057 }
12058
12059 # for reduce test_118* time (b=14842)
12060 [ "$SLOW" = "no" ] && set_resend_count $NO_SLOW_RESENDCOUNT
12061
12062 # Reset async IO behavior after error case
12063 reset_async() {
12064         FILE=$DIR/reset_async
12065
12066         # Ensure all OSCs are cleared
12067         $LFS setstripe -c -1 $FILE
12068         dd if=/dev/zero of=$FILE bs=64k count=$OSTCOUNT
12069         sync
12070         rm $FILE
12071 }
12072
12073 test_118a() #bug 11710
12074 {
12075         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12076
12077         reset_async
12078
12079         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
12080         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12081         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
12082
12083         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12084                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12085                 return 1;
12086         fi
12087         rm -f $DIR/$tfile
12088 }
12089 run_test 118a "verify O_SYNC works =========="
12090
12091 test_118b()
12092 {
12093         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12094         remote_ost_nodsh && skip "remote OST with nodsh"
12095
12096         reset_async
12097
12098         #define OBD_FAIL_SRV_ENOENT 0x217
12099         set_nodes_failloc "$(osts_nodes)" 0x217
12100         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
12101         RC=$?
12102         set_nodes_failloc "$(osts_nodes)" 0
12103         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12104         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12105                     grep -c writeback)
12106
12107         if [[ $RC -eq 0 ]]; then
12108                 error "Must return error due to dropped pages, rc=$RC"
12109                 return 1;
12110         fi
12111
12112         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12113                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12114                 return 1;
12115         fi
12116
12117         echo "Dirty pages not leaked on ENOENT"
12118
12119         # Due to the above error the OSC will issue all RPCs syncronously
12120         # until a subsequent RPC completes successfully without error.
12121         $MULTIOP $DIR/$tfile Ow4096yc
12122         rm -f $DIR/$tfile
12123
12124         return 0
12125 }
12126 run_test 118b "Reclaim dirty pages on fatal error =========="
12127
12128 test_118c()
12129 {
12130         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12131
12132         # for 118c, restore the original resend count, LU-1940
12133         [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] &&
12134                                 set_resend_count $OLD_RESENDCOUNT
12135         remote_ost_nodsh && skip "remote OST with nodsh"
12136
12137         reset_async
12138
12139         #define OBD_FAIL_OST_EROFS               0x216
12140         set_nodes_failloc "$(osts_nodes)" 0x216
12141
12142         # multiop should block due to fsync until pages are written
12143         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
12144         MULTIPID=$!
12145         sleep 1
12146
12147         if [[ `ps h -o comm -p $MULTIPID` != "multiop" ]]; then
12148                 error "Multiop failed to block on fsync, pid=$MULTIPID"
12149         fi
12150
12151         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12152                     grep -c writeback)
12153         if [[ $WRITEBACK -eq 0 ]]; then
12154                 error "No page in writeback, writeback=$WRITEBACK"
12155         fi
12156
12157         set_nodes_failloc "$(osts_nodes)" 0
12158         wait $MULTIPID
12159         RC=$?
12160         if [[ $RC -ne 0 ]]; then
12161                 error "Multiop fsync failed, rc=$RC"
12162         fi
12163
12164         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12165         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12166                     grep -c writeback)
12167         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12168                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12169         fi
12170
12171         rm -f $DIR/$tfile
12172         echo "Dirty pages flushed via fsync on EROFS"
12173         return 0
12174 }
12175 run_test 118c "Fsync blocks on EROFS until dirty pages are flushed =========="
12176
12177 # continue to use small resend count to reduce test_118* time (b=14842)
12178 [ "$SLOW" = "no" ] && set_resend_count $NO_SLOW_RESENDCOUNT
12179
12180 test_118d()
12181 {
12182         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12183         remote_ost_nodsh && skip "remote OST with nodsh"
12184
12185         reset_async
12186
12187         #define OBD_FAIL_OST_BRW_PAUSE_BULK
12188         set_nodes_failloc "$(osts_nodes)" 0x214
12189         # multiop should block due to fsync until pages are written
12190         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
12191         MULTIPID=$!
12192         sleep 1
12193
12194         if [[ `ps h -o comm -p $MULTIPID` != "multiop" ]]; then
12195                 error "Multiop failed to block on fsync, pid=$MULTIPID"
12196         fi
12197
12198         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12199                     grep -c writeback)
12200         if [[ $WRITEBACK -eq 0 ]]; then
12201                 error "No page in writeback, writeback=$WRITEBACK"
12202         fi
12203
12204         wait $MULTIPID || error "Multiop fsync failed, rc=$?"
12205         set_nodes_failloc "$(osts_nodes)" 0
12206
12207         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12208         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12209                     grep -c writeback)
12210         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12211                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12212         fi
12213
12214         rm -f $DIR/$tfile
12215         echo "Dirty pages gaurenteed flushed via fsync"
12216         return 0
12217 }
12218 run_test 118d "Fsync validation inject a delay of the bulk =========="
12219
12220 test_118f() {
12221         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12222
12223         reset_async
12224
12225         #define OBD_FAIL_OSC_BRW_PREP_REQ2        0x40a
12226         lctl set_param fail_loc=0x8000040a
12227
12228         # Should simulate EINVAL error which is fatal
12229         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
12230         RC=$?
12231         if [[ $RC -eq 0 ]]; then
12232                 error "Must return error due to dropped pages, rc=$RC"
12233         fi
12234
12235         lctl set_param fail_loc=0x0
12236
12237         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
12238         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12239         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12240                     grep -c writeback)
12241         if [[ $LOCKED -ne 0 ]]; then
12242                 error "Locked pages remain in cache, locked=$LOCKED"
12243         fi
12244
12245         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12246                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12247         fi
12248
12249         rm -f $DIR/$tfile
12250         echo "No pages locked after fsync"
12251
12252         reset_async
12253         return 0
12254 }
12255 run_test 118f "Simulate unrecoverable OSC side error =========="
12256
12257 test_118g() {
12258         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12259
12260         reset_async
12261
12262         #define OBD_FAIL_OSC_BRW_PREP_REQ        0x406
12263         lctl set_param fail_loc=0x406
12264
12265         # simulate local -ENOMEM
12266         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
12267         RC=$?
12268
12269         lctl set_param fail_loc=0
12270         if [[ $RC -eq 0 ]]; then
12271                 error "Must return error due to dropped pages, rc=$RC"
12272         fi
12273
12274         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
12275         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12276         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12277                         grep -c writeback)
12278         if [[ $LOCKED -ne 0 ]]; then
12279                 error "Locked pages remain in cache, locked=$LOCKED"
12280         fi
12281
12282         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12283                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12284         fi
12285
12286         rm -f $DIR/$tfile
12287         echo "No pages locked after fsync"
12288
12289         reset_async
12290         return 0
12291 }
12292 run_test 118g "Don't stay in wait if we got local -ENOMEM  =========="
12293
12294 test_118h() {
12295         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12296         remote_ost_nodsh && skip "remote OST with nodsh"
12297
12298         reset_async
12299
12300         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
12301         set_nodes_failloc "$(osts_nodes)" 0x20e
12302         # Should simulate ENOMEM error which is recoverable and should be handled by timeout
12303         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
12304         RC=$?
12305
12306         set_nodes_failloc "$(osts_nodes)" 0
12307         if [[ $RC -eq 0 ]]; then
12308                 error "Must return error due to dropped pages, rc=$RC"
12309         fi
12310
12311         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
12312         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12313         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12314                     grep -c writeback)
12315         if [[ $LOCKED -ne 0 ]]; then
12316                 error "Locked pages remain in cache, locked=$LOCKED"
12317         fi
12318
12319         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12320                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12321         fi
12322
12323         rm -f $DIR/$tfile
12324         echo "No pages locked after fsync"
12325
12326         return 0
12327 }
12328 run_test 118h "Verify timeout in handling recoverables errors  =========="
12329
12330 [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] && set_resend_count $OLD_RESENDCOUNT
12331
12332 test_118i() {
12333         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12334         remote_ost_nodsh && skip "remote OST with nodsh"
12335
12336         reset_async
12337
12338         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
12339         set_nodes_failloc "$(osts_nodes)" 0x20e
12340
12341         # Should simulate ENOMEM error which is recoverable and should be handled by timeout
12342         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
12343         PID=$!
12344         sleep 5
12345         set_nodes_failloc "$(osts_nodes)" 0
12346
12347         wait $PID
12348         RC=$?
12349         if [[ $RC -ne 0 ]]; then
12350                 error "got error, but should be not, rc=$RC"
12351         fi
12352
12353         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
12354         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12355         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
12356         if [[ $LOCKED -ne 0 ]]; then
12357                 error "Locked pages remain in cache, locked=$LOCKED"
12358         fi
12359
12360         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12361                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12362         fi
12363
12364         rm -f $DIR/$tfile
12365         echo "No pages locked after fsync"
12366
12367         return 0
12368 }
12369 run_test 118i "Fix error before timeout in recoverable error  =========="
12370
12371 [ "$SLOW" = "no" ] && set_resend_count 4
12372
12373 test_118j() {
12374         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12375         remote_ost_nodsh && skip "remote OST with nodsh"
12376
12377         reset_async
12378
12379         #define OBD_FAIL_OST_BRW_WRITE_BULK2     0x220
12380         set_nodes_failloc "$(osts_nodes)" 0x220
12381
12382         # return -EIO from OST
12383         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
12384         RC=$?
12385         set_nodes_failloc "$(osts_nodes)" 0x0
12386         if [[ $RC -eq 0 ]]; then
12387                 error "Must return error due to dropped pages, rc=$RC"
12388         fi
12389
12390         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
12391         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12392         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
12393         if [[ $LOCKED -ne 0 ]]; then
12394                 error "Locked pages remain in cache, locked=$LOCKED"
12395         fi
12396
12397         # in recoverable error on OST we want resend and stay until it finished
12398         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12399                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12400         fi
12401
12402         rm -f $DIR/$tfile
12403         echo "No pages locked after fsync"
12404
12405         return 0
12406 }
12407 run_test 118j "Simulate unrecoverable OST side error =========="
12408
12409 test_118k()
12410 {
12411         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12412         remote_ost_nodsh && skip "remote OSTs with nodsh"
12413
12414         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
12415         set_nodes_failloc "$(osts_nodes)" 0x20e
12416         test_mkdir $DIR/$tdir
12417
12418         for ((i=0;i<10;i++)); do
12419                 (dd if=/dev/zero of=$DIR/$tdir/$tfile-$i bs=1M count=10 || \
12420                         error "dd to $DIR/$tdir/$tfile-$i failed" )&
12421                 SLEEPPID=$!
12422                 sleep 0.500s
12423                 kill $SLEEPPID
12424                 wait $SLEEPPID
12425         done
12426
12427         set_nodes_failloc "$(osts_nodes)" 0
12428         rm -rf $DIR/$tdir
12429 }
12430 run_test 118k "bio alloc -ENOMEM and IO TERM handling ========="
12431
12432 test_118l() # LU-646
12433 {
12434         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12435
12436         test_mkdir $DIR/$tdir
12437         $MULTIOP $DIR/$tdir Dy || error "fsync dir failed"
12438         rm -rf $DIR/$tdir
12439 }
12440 run_test 118l "fsync dir"
12441
12442 test_118m() # LU-3066
12443 {
12444         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12445
12446         test_mkdir $DIR/$tdir
12447         $MULTIOP $DIR/$tdir DY || error "fdatasync dir failed"
12448         rm -rf $DIR/$tdir
12449 }
12450 run_test 118m "fdatasync dir ========="
12451
12452 [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] && set_resend_count $OLD_RESENDCOUNT
12453
12454 test_118n()
12455 {
12456         local begin
12457         local end
12458
12459         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12460         remote_ost_nodsh && skip "remote OSTs with nodsh"
12461
12462         # Sleep to avoid a cached response.
12463         #define OBD_STATFS_CACHE_SECONDS 1
12464         sleep 2
12465
12466         # Inject a 10 second delay in the OST_STATFS handler.
12467         #define OBD_FAIL_OST_STATFS_DELAY 0x242
12468         set_nodes_failloc "$(osts_nodes)" 0x242
12469
12470         begin=$SECONDS
12471         stat --file-system $MOUNT > /dev/null
12472         end=$SECONDS
12473
12474         set_nodes_failloc "$(osts_nodes)" 0
12475
12476         if ((end - begin > 20)); then
12477             error "statfs took $((end - begin)) seconds, expected 10"
12478         fi
12479 }
12480 run_test 118n "statfs() sends OST_STATFS requests in parallel"
12481
12482 test_119a() # bug 11737
12483 {
12484         BSIZE=$((512 * 1024))
12485         directio write $DIR/$tfile 0 1 $BSIZE
12486         # We ask to read two blocks, which is more than a file size.
12487         # directio will indicate an error when requested and actual
12488         # sizes aren't equeal (a normal situation in this case) and
12489         # print actual read amount.
12490         NOB=`directio read $DIR/$tfile 0 2 $BSIZE | awk '/error/ {print $6}'`
12491         if [ "$NOB" != "$BSIZE" ]; then
12492                 error "read $NOB bytes instead of $BSIZE"
12493         fi
12494         rm -f $DIR/$tfile
12495 }
12496 run_test 119a "Short directIO read must return actual read amount"
12497
12498 test_119b() # bug 11737
12499 {
12500         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
12501
12502         $LFS setstripe -c 2 $DIR/$tfile || error "setstripe failed"
12503         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=1 || error "dd failed"
12504         sync
12505         $MULTIOP $DIR/$tfile oO_RDONLY:O_DIRECT:r$((2048 * 1024)) ||
12506                 error "direct read failed"
12507         rm -f $DIR/$tfile
12508 }
12509 run_test 119b "Sparse directIO read must return actual read amount"
12510
12511 test_119c() # bug 13099
12512 {
12513         BSIZE=1048576
12514         directio write $DIR/$tfile 3 1 $BSIZE || error "direct write failed"
12515         directio readhole $DIR/$tfile 0 2 $BSIZE || error "reading hole failed"
12516         rm -f $DIR/$tfile
12517 }
12518 run_test 119c "Testing for direct read hitting hole"
12519
12520 test_119d() # bug 15950
12521 {
12522         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12523
12524         MAX_RPCS_IN_FLIGHT=`$LCTL get_param -n osc.*OST0000-osc-[^mM]*.max_rpcs_in_flight`
12525         $LCTL set_param -n osc.*OST0000-osc-[^mM]*.max_rpcs_in_flight 1
12526         BSIZE=1048576
12527         $LFS setstripe $DIR/$tfile -i 0 -c 1 || error "setstripe failed"
12528         $DIRECTIO write $DIR/$tfile 0 1 $BSIZE || error "first directio failed"
12529         #define OBD_FAIL_OSC_DIO_PAUSE           0x40d
12530         lctl set_param fail_loc=0x40d
12531         $DIRECTIO write $DIR/$tfile 1 4 $BSIZE &
12532         pid_dio=$!
12533         sleep 1
12534         cat $DIR/$tfile > /dev/null &
12535         lctl set_param fail_loc=0
12536         pid_reads=$!
12537         wait $pid_dio
12538         log "the DIO writes have completed, now wait for the reads (should not block very long)"
12539         sleep 2
12540         [ -n "`ps h -p $pid_reads -o comm`" ] && \
12541         error "the read rpcs have not completed in 2s"
12542         rm -f $DIR/$tfile
12543         $LCTL set_param -n osc.*OST0000-osc-[^mM]*.max_rpcs_in_flight $MAX_RPCS_IN_FLIGHT
12544 }
12545 run_test 119d "The DIO path should try to send a new rpc once one is completed"
12546
12547 test_120a() {
12548         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12549         remote_mds_nodsh && skip "remote MDS with nodsh"
12550         test_mkdir -i0 -c1 $DIR/$tdir
12551         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
12552                 skip_env "no early lock cancel on server"
12553
12554         lru_resize_disable mdc
12555         lru_resize_disable osc
12556         cancel_lru_locks mdc
12557         # asynchronous object destroy at MDT could cause bl ast to client
12558         cancel_lru_locks osc
12559
12560         stat $DIR/$tdir > /dev/null
12561         can1=$(do_facet mds1 \
12562                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12563                awk '/ldlm_cancel/ {print $2}')
12564         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12565                awk '/ldlm_bl_callback/ {print $2}')
12566         test_mkdir -i0 -c1 $DIR/$tdir/d1
12567         can2=$(do_facet mds1 \
12568                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12569                awk '/ldlm_cancel/ {print $2}')
12570         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12571                awk '/ldlm_bl_callback/ {print $2}')
12572         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
12573         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
12574         lru_resize_enable mdc
12575         lru_resize_enable osc
12576 }
12577 run_test 120a "Early Lock Cancel: mkdir test"
12578
12579 test_120b() {
12580         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12581         remote_mds_nodsh && skip "remote MDS with nodsh"
12582         test_mkdir $DIR/$tdir
12583         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
12584                 skip_env "no early lock cancel on server"
12585
12586         lru_resize_disable mdc
12587         lru_resize_disable osc
12588         cancel_lru_locks mdc
12589         stat $DIR/$tdir > /dev/null
12590         can1=$(do_facet $SINGLEMDS \
12591                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12592                awk '/ldlm_cancel/ {print $2}')
12593         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12594                awk '/ldlm_bl_callback/ {print $2}')
12595         touch $DIR/$tdir/f1
12596         can2=$(do_facet $SINGLEMDS \
12597                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12598                awk '/ldlm_cancel/ {print $2}')
12599         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12600                awk '/ldlm_bl_callback/ {print $2}')
12601         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
12602         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
12603         lru_resize_enable mdc
12604         lru_resize_enable osc
12605 }
12606 run_test 120b "Early Lock Cancel: create test"
12607
12608 test_120c() {
12609         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12610         remote_mds_nodsh && skip "remote MDS with nodsh"
12611         test_mkdir -i0 -c1 $DIR/$tdir
12612         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
12613                 skip "no early lock cancel on server"
12614
12615         lru_resize_disable mdc
12616         lru_resize_disable osc
12617         test_mkdir -i0 -c1 $DIR/$tdir/d1
12618         test_mkdir -i0 -c1 $DIR/$tdir/d2
12619         touch $DIR/$tdir/d1/f1
12620         cancel_lru_locks mdc
12621         stat $DIR/$tdir/d1 $DIR/$tdir/d2 $DIR/$tdir/d1/f1 > /dev/null
12622         can1=$(do_facet mds1 \
12623                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12624                awk '/ldlm_cancel/ {print $2}')
12625         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12626                awk '/ldlm_bl_callback/ {print $2}')
12627         ln $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2
12628         can2=$(do_facet mds1 \
12629                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12630                awk '/ldlm_cancel/ {print $2}')
12631         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12632                awk '/ldlm_bl_callback/ {print $2}')
12633         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
12634         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
12635         lru_resize_enable mdc
12636         lru_resize_enable osc
12637 }
12638 run_test 120c "Early Lock Cancel: link test"
12639
12640 test_120d() {
12641         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12642         remote_mds_nodsh && skip "remote MDS with nodsh"
12643         test_mkdir -i0 -c1 $DIR/$tdir
12644         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
12645                 skip_env "no early lock cancel on server"
12646
12647         lru_resize_disable mdc
12648         lru_resize_disable osc
12649         touch $DIR/$tdir
12650         cancel_lru_locks mdc
12651         stat $DIR/$tdir > /dev/null
12652         can1=$(do_facet mds1 \
12653                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12654                awk '/ldlm_cancel/ {print $2}')
12655         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12656                awk '/ldlm_bl_callback/ {print $2}')
12657         chmod a+x $DIR/$tdir
12658         can2=$(do_facet mds1 \
12659                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12660                awk '/ldlm_cancel/ {print $2}')
12661         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12662                awk '/ldlm_bl_callback/ {print $2}')
12663         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
12664         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
12665         lru_resize_enable mdc
12666         lru_resize_enable osc
12667 }
12668 run_test 120d "Early Lock Cancel: setattr test"
12669
12670 test_120e() {
12671         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12672         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
12673                 skip_env "no early lock cancel on server"
12674         remote_mds_nodsh && skip "remote MDS with nodsh"
12675
12676         local dlmtrace_set=false
12677
12678         test_mkdir -i0 -c1 $DIR/$tdir
12679         lru_resize_disable mdc
12680         lru_resize_disable osc
12681         ! $LCTL get_param debug | grep -q dlmtrace &&
12682                 $LCTL set_param debug=+dlmtrace && dlmtrace_set=true
12683         dd if=/dev/zero of=$DIR/$tdir/f1 count=1
12684         cancel_lru_locks mdc
12685         cancel_lru_locks osc
12686         dd if=$DIR/$tdir/f1 of=/dev/null
12687         stat $DIR/$tdir $DIR/$tdir/f1 > /dev/null
12688         # XXX client can not do early lock cancel of OST lock
12689         # during unlink (LU-4206), so cancel osc lock now.
12690         sleep 2
12691         cancel_lru_locks osc
12692         can1=$(do_facet mds1 \
12693                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12694                awk '/ldlm_cancel/ {print $2}')
12695         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12696                awk '/ldlm_bl_callback/ {print $2}')
12697         unlink $DIR/$tdir/f1
12698         sleep 5
12699         can2=$(do_facet mds1 \
12700                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12701                awk '/ldlm_cancel/ {print $2}')
12702         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12703                awk '/ldlm_bl_callback/ {print $2}')
12704         [ $can1 -ne $can2 ] && error "$((can2 - can1)) cancel RPC occured" &&
12705                 $LCTL dk $TMP/cancel.debug.txt
12706         [ $blk1 -ne $blk2 ] && error "$((blk2 - blk1)) blocking RPC occured" &&
12707                 $LCTL dk $TMP/blocking.debug.txt
12708         $dlmtrace_set && $LCTL set_param debug=-dlmtrace
12709         lru_resize_enable mdc
12710         lru_resize_enable osc
12711 }
12712 run_test 120e "Early Lock Cancel: unlink test"
12713
12714 test_120f() {
12715         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12716         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
12717                 skip_env "no early lock cancel on server"
12718         remote_mds_nodsh && skip "remote MDS with nodsh"
12719
12720         test_mkdir -i0 -c1 $DIR/$tdir
12721         lru_resize_disable mdc
12722         lru_resize_disable osc
12723         test_mkdir -i0 -c1 $DIR/$tdir/d1
12724         test_mkdir -i0 -c1 $DIR/$tdir/d2
12725         dd if=/dev/zero of=$DIR/$tdir/d1/f1 count=1
12726         dd if=/dev/zero of=$DIR/$tdir/d2/f2 count=1
12727         cancel_lru_locks mdc
12728         cancel_lru_locks osc
12729         dd if=$DIR/$tdir/d1/f1 of=/dev/null
12730         dd if=$DIR/$tdir/d2/f2 of=/dev/null
12731         stat $DIR/$tdir/d1 $DIR/$tdir/d2 $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2 > /dev/null
12732         # XXX client can not do early lock cancel of OST lock
12733         # during rename (LU-4206), so cancel osc lock now.
12734         sleep 2
12735         cancel_lru_locks osc
12736         can1=$(do_facet mds1 \
12737                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12738                awk '/ldlm_cancel/ {print $2}')
12739         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12740                awk '/ldlm_bl_callback/ {print $2}')
12741         mrename $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2
12742         sleep 5
12743         can2=$(do_facet mds1 \
12744                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12745                awk '/ldlm_cancel/ {print $2}')
12746         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12747                awk '/ldlm_bl_callback/ {print $2}')
12748         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
12749         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
12750         lru_resize_enable mdc
12751         lru_resize_enable osc
12752 }
12753 run_test 120f "Early Lock Cancel: rename test"
12754
12755 test_120g() {
12756         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12757         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
12758                 skip_env "no early lock cancel on server"
12759         remote_mds_nodsh && skip "remote MDS with nodsh"
12760
12761         lru_resize_disable mdc
12762         lru_resize_disable osc
12763         count=10000
12764         echo create $count files
12765         test_mkdir $DIR/$tdir
12766         cancel_lru_locks mdc
12767         cancel_lru_locks osc
12768         t0=$(date +%s)
12769
12770         can0=$(do_facet $SINGLEMDS \
12771                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12772                awk '/ldlm_cancel/ {print $2}')
12773         blk0=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12774                awk '/ldlm_bl_callback/ {print $2}')
12775         createmany -o $DIR/$tdir/f $count
12776         sync
12777         can1=$(do_facet $SINGLEMDS \
12778                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12779                awk '/ldlm_cancel/ {print $2}')
12780         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12781                awk '/ldlm_bl_callback/ {print $2}')
12782         t1=$(date +%s)
12783         echo total: $((can1-can0)) cancels, $((blk1-blk0)) blockings
12784         echo rm $count files
12785         rm -r $DIR/$tdir
12786         sync
12787         can2=$(do_facet $SINGLEMDS \
12788                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12789                awk '/ldlm_cancel/ {print $2}')
12790         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12791                awk '/ldlm_bl_callback/ {print $2}')
12792         t2=$(date +%s)
12793         echo total: $count removes in $((t2-t1))
12794         echo total: $((can2-can1)) cancels, $((blk2-blk1)) blockings
12795         sleep 2
12796         # wait for commitment of removal
12797         lru_resize_enable mdc
12798         lru_resize_enable osc
12799 }
12800 run_test 120g "Early Lock Cancel: performance test"
12801
12802 test_121() { #bug #10589
12803         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12804
12805         rm -rf $DIR/$tfile
12806         writes=$(LANG=C dd if=/dev/zero of=$DIR/$tfile count=1 2>&1 | awk -F '+' '/out$/ {print $1}')
12807 #define OBD_FAIL_LDLM_CANCEL_RACE        0x310
12808         lctl set_param fail_loc=0x310
12809         cancel_lru_locks osc > /dev/null
12810         reads=$(LANG=C dd if=$DIR/$tfile of=/dev/null 2>&1 | awk -F '+' '/in$/ {print $1}')
12811         lctl set_param fail_loc=0
12812         [[ $reads -eq $writes ]] ||
12813                 error "read $reads blocks, must be $writes blocks"
12814 }
12815 run_test 121 "read cancel race ========="
12816
12817 test_123a_base() { # was test 123, statahead(bug 11401)
12818         local lsx="$1"
12819
12820         SLOWOK=0
12821         if ! grep -q "processor.*: 1" /proc/cpuinfo; then
12822                 log "testing UP system. Performance may be lower than expected."
12823                 SLOWOK=1
12824         fi
12825
12826         rm -rf $DIR/$tdir
12827         test_mkdir $DIR/$tdir
12828         NUMFREE=$(df -i -P $DIR | tail -n 1 | awk '{ print $4 }')
12829         [[ $NUMFREE -gt 100000 ]] && NUMFREE=100000 || NUMFREE=$((NUMFREE-1000))
12830         MULT=10
12831         for ((i=100, j=0; i<=$NUMFREE; j=$i, i=$((i * MULT)) )); do
12832                 createmany -o $DIR/$tdir/$tfile $j $((i - j))
12833
12834                 max=$(lctl get_param -n llite.*.statahead_max | head -n 1)
12835                 lctl set_param -n llite.*.statahead_max 0
12836                 lctl get_param llite.*.statahead_max
12837                 cancel_lru_locks mdc
12838                 cancel_lru_locks osc
12839                 stime=$(date +%s)
12840                 time $lsx $DIR/$tdir | wc -l
12841                 etime=$(date +%s)
12842                 delta=$((etime - stime))
12843                 log "$lsx $i files without statahead: $delta sec"
12844                 lctl set_param llite.*.statahead_max=$max
12845
12846                 swrong=$(lctl get_param -n llite.*.statahead_stats |
12847                         grep "statahead wrong:" | awk '{print $3}')
12848                 lctl get_param -n llite.*.statahead_max | grep '[0-9]'
12849                 cancel_lru_locks mdc
12850                 cancel_lru_locks osc
12851                 stime=$(date +%s)
12852                 time $lsx $DIR/$tdir | wc -l
12853                 etime=$(date +%s)
12854                 delta_sa=$((etime - stime))
12855                 log "$lsx $i files with statahead: $delta_sa sec"
12856                 lctl get_param -n llite.*.statahead_stats
12857                 ewrong=$(lctl get_param -n llite.*.statahead_stats |
12858                         grep "statahead wrong:" | awk '{print $3}')
12859
12860                 [[ $swrong -lt $ewrong ]] &&
12861                         log "statahead was stopped, maybe too many locks held!"
12862                 [[ $delta -eq 0 || $delta_sa -eq 0 ]] && continue
12863
12864                 if [ $((delta_sa * 100)) -gt $((delta * 105)) -a $delta_sa -gt $((delta + 2)) ]; then
12865                         max=$(lctl get_param -n llite.*.statahead_max |
12866                                 head -n 1)
12867                         lctl set_param -n llite.*.statahead_max 0
12868                         lctl get_param llite.*.statahead_max
12869                         cancel_lru_locks mdc
12870                         cancel_lru_locks osc
12871                         stime=$(date +%s)
12872                         time $lsx $DIR/$tdir | wc -l
12873                         etime=$(date +%s)
12874                         delta=$((etime - stime))
12875                         log "$lsx $i files again without statahead: $delta sec"
12876                         lctl set_param llite.*.statahead_max=$max
12877                         if [ $((delta_sa * 100 > delta * 105 && delta_sa > delta + 2)) ]; then
12878                                 if [  $SLOWOK -eq 0 ]; then
12879                                         error "$lsx $i files is slower with statahead!"
12880                                 else
12881                                         log "$lsx $i files is slower with statahead!"
12882                                 fi
12883                                 break
12884                         fi
12885                 fi
12886
12887                 [ $delta -gt 20 ] && break
12888                 [ $delta -gt 8 ] && MULT=$((50 / delta))
12889                 [ "$SLOW" = "no" -a $delta -gt 5 ] && break
12890         done
12891         log "$lsx done"
12892
12893         stime=$(date +%s)
12894         rm -r $DIR/$tdir
12895         sync
12896         etime=$(date +%s)
12897         delta=$((etime - stime))
12898         log "rm -r $DIR/$tdir/: $delta seconds"
12899         log "rm done"
12900         lctl get_param -n llite.*.statahead_stats
12901 }
12902
12903 test_123aa() {
12904         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12905
12906         test_123a_base "ls -l"
12907 }
12908 run_test 123aa "verify statahead work"
12909
12910 test_123ab() {
12911         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12912
12913         statx_supported || skip_env "Test must be statx() syscall supported"
12914
12915         test_123a_base "$STATX -l"
12916 }
12917 run_test 123ab "verify statahead work by using statx"
12918
12919 test_123ac() {
12920         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12921
12922         statx_supported || skip_env "Test must be statx() syscall supported"
12923
12924         local rpcs_before
12925         local rpcs_after
12926         local agl_before
12927         local agl_after
12928
12929         cancel_lru_locks $OSC
12930         rpcs_before=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
12931         agl_before=$($LCTL get_param -n llite.*.statahead_stats |
12932                 awk '/agl.total:/ {print $3}')
12933         test_123a_base "$STATX -c \"%n %i %A %h %u %g %W %X %Z\" -D"
12934         test_123a_base "$STATX --cached=always -D"
12935         agl_after=$($LCTL get_param -n llite.*.statahead_stats |
12936                 awk '/agl.total:/ {print $3}')
12937         [ $agl_before -eq $agl_after ] ||
12938                 error "Should not trigger AGL thread - $agl_before:$agl_after"
12939         rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
12940         [ $rpcs_after -eq $rpcs_before ] ||
12941                 error "$STATX should not send glimpse RPCs to $OSC"
12942 }
12943 run_test 123ac "verify statahead work by using statx without glimpse RPCs"
12944
12945 test_123b () { # statahead(bug 15027)
12946         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12947
12948         test_mkdir $DIR/$tdir
12949         createmany -o $DIR/$tdir/$tfile-%d 1000
12950
12951         cancel_lru_locks mdc
12952         cancel_lru_locks osc
12953
12954 #define OBD_FAIL_MDC_GETATTR_ENQUEUE     0x803
12955         lctl set_param fail_loc=0x80000803
12956         ls -lR $DIR/$tdir > /dev/null
12957         log "ls done"
12958         lctl set_param fail_loc=0x0
12959         lctl get_param -n llite.*.statahead_stats
12960         rm -r $DIR/$tdir
12961         sync
12962
12963 }
12964 run_test 123b "not panic with network error in statahead enqueue (bug 15027)"
12965
12966 test_123c() {
12967         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
12968
12969         test_mkdir -i 0 -c 1 $DIR/$tdir.0
12970         test_mkdir -i 1 -c 1 $DIR/$tdir.1
12971         touch $DIR/$tdir.1/{1..3}
12972         mv $DIR/$tdir.1/{1..3} $DIR/$tdir.0
12973
12974         remount_client $MOUNT
12975
12976         $MULTIOP $DIR/$tdir.0 Q
12977
12978         # let statahead to complete
12979         ls -l $DIR/$tdir.0 > /dev/null
12980
12981         testid=$(echo $TESTNAME | tr '_' ' ')
12982         dmesg | tac | sed "/$testid/,$ d" | grep "Can not initialize inode" &&
12983                 error "statahead warning" || true
12984 }
12985 run_test 123c "Can not initialize inode warning on DNE statahead"
12986
12987 test_124a() {
12988         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12989         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
12990                 skip_env "no lru resize on server"
12991
12992         local NR=2000
12993
12994         test_mkdir $DIR/$tdir
12995
12996         log "create $NR files at $DIR/$tdir"
12997         createmany -o $DIR/$tdir/f $NR ||
12998                 error "failed to create $NR files in $DIR/$tdir"
12999
13000         cancel_lru_locks mdc
13001         ls -l $DIR/$tdir > /dev/null
13002
13003         local NSDIR=""
13004         local LRU_SIZE=0
13005         for VALUE in $($LCTL get_param ldlm.namespaces.*mdc-*.lru_size); do
13006                 local PARAM=$(echo ${VALUE[0]} | cut -d "=" -f1)
13007                 LRU_SIZE=$($LCTL get_param -n $PARAM)
13008                 if [[ $LRU_SIZE -gt $(default_lru_size) ]]; then
13009                         NSDIR=$(echo $PARAM | cut -d "." -f1-3)
13010                         log "NSDIR=$NSDIR"
13011                         log "NS=$(basename $NSDIR)"
13012                         break
13013                 fi
13014         done
13015
13016         if [[ -z "$NSDIR" || $LRU_SIZE -lt $(default_lru_size) ]]; then
13017                 skip "Not enough cached locks created!"
13018         fi
13019         log "LRU=$LRU_SIZE"
13020
13021         local SLEEP=30
13022
13023         # We know that lru resize allows one client to hold $LIMIT locks
13024         # for 10h. After that locks begin to be killed by client.
13025         local MAX_HRS=10
13026         local LIMIT=$($LCTL get_param -n $NSDIR.pool.limit)
13027         log "LIMIT=$LIMIT"
13028         if [ $LIMIT -lt $LRU_SIZE ]; then
13029                 skip "Limit is too small $LIMIT"
13030         fi
13031
13032         # Make LVF so higher that sleeping for $SLEEP is enough to _start_
13033         # killing locks. Some time was spent for creating locks. This means
13034         # that up to the moment of sleep finish we must have killed some of
13035         # them (10-100 locks). This depends on how fast ther were created.
13036         # Many of them were touched in almost the same moment and thus will
13037         # be killed in groups.
13038         local LVF=$(($MAX_HRS * 60 * 60 / $SLEEP * $LIMIT / $LRU_SIZE * 100))
13039
13040         # Use $LRU_SIZE_B here to take into account real number of locks
13041         # created in the case of CMD, LRU_SIZE_B != $NR in most of cases
13042         local LRU_SIZE_B=$LRU_SIZE
13043         log "LVF=$LVF"
13044         local OLD_LVF=$($LCTL get_param -n $NSDIR.pool.lock_volume_factor)
13045         log "OLD_LVF=$OLD_LVF"
13046         $LCTL set_param -n $NSDIR.pool.lock_volume_factor $LVF
13047
13048         # Let's make sure that we really have some margin. Client checks
13049         # cached locks every 10 sec.
13050         SLEEP=$((SLEEP+20))
13051         log "Sleep ${SLEEP} sec"
13052         local SEC=0
13053         while ((SEC<$SLEEP)); do
13054                 echo -n "..."
13055                 sleep 5
13056                 SEC=$((SEC+5))
13057                 LRU_SIZE=$($LCTL get_param -n $NSDIR/lru_size)
13058                 echo -n "$LRU_SIZE"
13059         done
13060         echo ""
13061         $LCTL set_param -n $NSDIR.pool.lock_volume_factor $OLD_LVF
13062         local LRU_SIZE_A=$($LCTL get_param -n $NSDIR.lru_size)
13063
13064         [[ $LRU_SIZE_B -gt $LRU_SIZE_A ]] || {
13065                 error "No locks dropped in ${SLEEP}s. LRU size: $LRU_SIZE_A"
13066                 unlinkmany $DIR/$tdir/f $NR
13067                 return
13068         }
13069
13070         log "Dropped "$((LRU_SIZE_B-LRU_SIZE_A))" locks in ${SLEEP}s"
13071         log "unlink $NR files at $DIR/$tdir"
13072         unlinkmany $DIR/$tdir/f $NR
13073 }
13074 run_test 124a "lru resize ======================================="
13075
13076 get_max_pool_limit()
13077 {
13078         local limit=$($LCTL get_param \
13079                       -n ldlm.namespaces.*-MDT0000-mdc-*.pool.limit)
13080         local max=0
13081         for l in $limit; do
13082                 if [[ $l -gt $max ]]; then
13083                         max=$l
13084                 fi
13085         done
13086         echo $max
13087 }
13088
13089 test_124b() {
13090         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13091         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
13092                 skip_env "no lru resize on server"
13093
13094         LIMIT=$(get_max_pool_limit)
13095
13096         NR=$(($(default_lru_size)*20))
13097         if [[ $NR -gt $LIMIT ]]; then
13098                 log "Limit lock number by $LIMIT locks"
13099                 NR=$LIMIT
13100         fi
13101
13102         IFree=$(mdsrate_inodes_available)
13103         if [ $IFree -lt $NR ]; then
13104                 log "Limit lock number by $IFree inodes"
13105                 NR=$IFree
13106         fi
13107
13108         lru_resize_disable mdc
13109         test_mkdir -p $DIR/$tdir/disable_lru_resize
13110
13111         createmany -o $DIR/$tdir/disable_lru_resize/f $NR
13112         log "doing ls -la $DIR/$tdir/disable_lru_resize 3 times"
13113         cancel_lru_locks mdc
13114         stime=`date +%s`
13115         PID=""
13116         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
13117         PID="$PID $!"
13118         sleep 2
13119         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
13120         PID="$PID $!"
13121         sleep 2
13122         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
13123         PID="$PID $!"
13124         wait $PID
13125         etime=`date +%s`
13126         nolruresize_delta=$((etime-stime))
13127         log "ls -la time: $nolruresize_delta seconds"
13128         log "lru_size = $(lctl get_param -n ldlm.namespaces.*mdc*.lru_size)"
13129         unlinkmany $DIR/$tdir/disable_lru_resize/f $NR
13130
13131         lru_resize_enable mdc
13132         test_mkdir -p $DIR/$tdir/enable_lru_resize
13133
13134         createmany -o $DIR/$tdir/enable_lru_resize/f $NR
13135         log "doing ls -la $DIR/$tdir/enable_lru_resize 3 times"
13136         cancel_lru_locks mdc
13137         stime=`date +%s`
13138         PID=""
13139         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
13140         PID="$PID $!"
13141         sleep 2
13142         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
13143         PID="$PID $!"
13144         sleep 2
13145         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
13146         PID="$PID $!"
13147         wait $PID
13148         etime=`date +%s`
13149         lruresize_delta=$((etime-stime))
13150         log "ls -la time: $lruresize_delta seconds"
13151         log "lru_size = $(lctl get_param -n ldlm.namespaces.*mdc*.lru_size)"
13152
13153         if [ $lruresize_delta -gt $nolruresize_delta ]; then
13154                 log "ls -la is $(((lruresize_delta - $nolruresize_delta) * 100 / $nolruresize_delta))% slower with lru resize enabled"
13155         elif [ $nolruresize_delta -gt $lruresize_delta ]; then
13156                 log "ls -la is $(((nolruresize_delta - $lruresize_delta) * 100 / $nolruresize_delta))% faster with lru resize enabled"
13157         else
13158                 log "lru resize performs the same with no lru resize"
13159         fi
13160         unlinkmany $DIR/$tdir/enable_lru_resize/f $NR
13161 }
13162 run_test 124b "lru resize (performance test) ======================="
13163
13164 test_124c() {
13165         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13166         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
13167                 skip_env "no lru resize on server"
13168
13169         # cache ununsed locks on client
13170         local nr=100
13171         cancel_lru_locks mdc
13172         test_mkdir $DIR/$tdir
13173         createmany -o $DIR/$tdir/f $nr ||
13174                 error "failed to create $nr files in $DIR/$tdir"
13175         ls -l $DIR/$tdir > /dev/null
13176
13177         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
13178         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
13179         local max_age=$($LCTL get_param -n $nsdir.lru_max_age)
13180         local recalc_p=$($LCTL get_param -n $nsdir.pool.recalc_period)
13181         echo "unused=$unused, max_age=$max_age, recalc_p=$recalc_p"
13182
13183         # set lru_max_age to 1 sec
13184         $LCTL set_param $nsdir.lru_max_age=1000 # milliseconds
13185         echo "sleep $((recalc_p * 2)) seconds..."
13186         sleep $((recalc_p * 2))
13187
13188         local remaining=$($LCTL get_param -n $nsdir.lock_unused_count)
13189         # restore lru_max_age
13190         $LCTL set_param -n $nsdir.lru_max_age $max_age
13191         [ $remaining -eq 0 ] || error "$remaining locks are not canceled"
13192         unlinkmany $DIR/$tdir/f $nr
13193 }
13194 run_test 124c "LRUR cancel very aged locks"
13195
13196 test_124d() {
13197         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13198         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
13199                 skip_env "no lru resize on server"
13200
13201         # cache ununsed locks on client
13202         local nr=100
13203
13204         lru_resize_disable mdc
13205         stack_trap "lru_resize_enable mdc" EXIT
13206
13207         cancel_lru_locks mdc
13208
13209         # asynchronous object destroy at MDT could cause bl ast to client
13210         test_mkdir $DIR/$tdir
13211         createmany -o $DIR/$tdir/f $nr ||
13212                 error "failed to create $nr files in $DIR/$tdir"
13213         stack_trap "unlinkmany $DIR/$tdir/f $nr" EXIT
13214
13215         ls -l $DIR/$tdir > /dev/null
13216
13217         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
13218         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
13219         local max_age=$($LCTL get_param -n $nsdir.lru_max_age)
13220         local recalc_p=$($LCTL get_param -n $nsdir.pool.recalc_period)
13221
13222         echo "unused=$unused, max_age=$max_age, recalc_p=$recalc_p"
13223
13224         # set lru_max_age to 1 sec
13225         $LCTL set_param $nsdir.lru_max_age=1000 # milliseconds
13226         stack_trap "$LCTL set_param -n $nsdir.lru_max_age $max_age" EXIT
13227
13228         echo "sleep $((recalc_p * 2)) seconds..."
13229         sleep $((recalc_p * 2))
13230
13231         local remaining=$($LCTL get_param -n $nsdir.lock_unused_count)
13232
13233         [ $remaining -eq 0 ] || error "$remaining locks are not canceled"
13234 }
13235 run_test 124d "cancel very aged locks if lru-resize diasbaled"
13236
13237 test_125() { # 13358
13238         $LCTL get_param -n llite.*.client_type | grep -q local ||
13239                 skip "must run as local client"
13240         $LCTL get_param -n mdc.*-mdc-*.connect_flags | grep -q acl ||
13241                 skip_env "must have acl enabled"
13242         [ -z "$(which setfacl)" ] && skip_env "must have setfacl tool"
13243
13244         test_mkdir $DIR/$tdir
13245         $LFS setstripe -S 65536 -c -1 $DIR/$tdir || error "setstripe failed"
13246         setfacl -R -m u:bin:rwx $DIR/$tdir || error "setfacl $DIR/$tdir failed"
13247         ls -ld $DIR/$tdir || error "cannot access $DIR/$tdir"
13248 }
13249 run_test 125 "don't return EPROTO when a dir has a non-default striping and ACLs"
13250
13251 test_126() { # bug 12829/13455
13252         $GSS && skip_env "must run as gss disabled"
13253         $LCTL get_param -n llite.*.client_type | grep -q local ||
13254                 skip "must run as local client"
13255         [ "$UID" != 0 ] && skip "must run as root, not UID $UID"
13256
13257         $RUNAS -u 0 -g 1 touch $DIR/$tfile || error "touch failed"
13258         gid=`ls -n $DIR/$tfile | awk '{print $4}'`
13259         rm -f $DIR/$tfile
13260         [ $gid -eq "1" ] || error "gid is set to" $gid "instead of 1"
13261 }
13262 run_test 126 "check that the fsgid provided by the client is taken into account"
13263
13264 test_127a() { # bug 15521
13265         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13266         local name count samp unit min max sum sumsq
13267
13268         $LFS setstripe -i 0 -c 1 $DIR/$tfile || error "setstripe failed"
13269         echo "stats before reset"
13270         $LCTL get_param osc.*.stats
13271         $LCTL set_param osc.*.stats=0
13272         local fsize=$((2048 * 1024))
13273
13274         dd if=/dev/zero of=$DIR/$tfile bs=$fsize count=1
13275         cancel_lru_locks osc
13276         dd if=$DIR/$tfile of=/dev/null bs=$fsize
13277
13278         $LCTL get_param osc.*0000-osc-*.stats | grep samples > $DIR/$tfile.tmp
13279         stack_trap "rm -f $TMP/$tfile.tmp"
13280         while read name count samp unit min max sum sumsq; do
13281                 echo "got name=$name count=$count unit=$unit min=$min max=$max"
13282                 [ ! $min ] && error "Missing min value for $name proc entry"
13283                 eval $name=$count || error "Wrong proc format"
13284
13285                 case $name in
13286                 read_bytes|write_bytes)
13287                         [[ "$unit" =~ "bytes" ]] ||
13288                                 error "unit is not 'bytes': $unit"
13289                         (( $min >= 4096 )) || error "min is too small: $min"
13290                         (( $min <= $fsize )) || error "min is too big: $min"
13291                         (( $max >= 4096 )) || error "max is too small: $max"
13292                         (( $max <= $fsize )) || error "max is too big: $max"
13293                         (( $sum == $fsize )) || error "sum is wrong: $sum"
13294                         (( $sumsq >= ($fsize / 4096) * (4096 * 4096) )) ||
13295                                 error "sumsquare is too small: $sumsq"
13296                         (( $sumsq <= $fsize * $fsize )) ||
13297                                 error "sumsquare is too big: $sumsq"
13298                         ;;
13299                 ost_read|ost_write)
13300                         [[ "$unit" =~ "usec" ]] ||
13301                                 error "unit is not 'usec': $unit"
13302                         ;;
13303                 *)      ;;
13304                 esac
13305         done < $DIR/$tfile.tmp
13306
13307         #check that we actually got some stats
13308         [ "$read_bytes" ] || error "Missing read_bytes stats"
13309         [ "$write_bytes" ] || error "Missing write_bytes stats"
13310         [ "$read_bytes" != 0 ] || error "no read done"
13311         [ "$write_bytes" != 0 ] || error "no write done"
13312 }
13313 run_test 127a "verify the client stats are sane"
13314
13315 test_127b() { # bug LU-333
13316         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13317         local name count samp unit min max sum sumsq
13318
13319         echo "stats before reset"
13320         $LCTL get_param llite.*.stats
13321         $LCTL set_param llite.*.stats=0
13322
13323         # perform 2 reads and writes so MAX is different from SUM.
13324         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1
13325         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1
13326         cancel_lru_locks osc
13327         dd if=$DIR/$tfile of=/dev/null bs=$PAGE_SIZE count=1
13328         dd if=$DIR/$tfile of=/dev/null bs=$PAGE_SIZE count=1
13329
13330         $LCTL get_param llite.*.stats | grep samples > $TMP/$tfile.tmp
13331         stack_trap "rm -f $TMP/$tfile.tmp"
13332         while read name count samp unit min max sum sumsq; do
13333                 echo "got name=$name count=$count unit=$unit min=$min max=$max"
13334                 eval $name=$count || error "Wrong proc format"
13335
13336                 case $name in
13337                 read_bytes|write_bytes)
13338                         [[ "$unit" =~ "bytes" ]] ||
13339                                 error "unit is not 'bytes': $unit"
13340                         (( $count == 2 )) || error "count is not 2: $count"
13341                         (( $min == $PAGE_SIZE )) ||
13342                                 error "min is not $PAGE_SIZE: $min"
13343                         (( $max == $PAGE_SIZE )) ||
13344                                 error "max is not $PAGE_SIZE: $max"
13345                         (( $sum == $PAGE_SIZE * 2 )) ||
13346                                 error "sum is not $((PAGE_SIZE * 2)): $sum"
13347                         ;;
13348                 read|write)
13349                         [[ "$unit" =~ "usec" ]] ||
13350                                 error "unit is not 'usec': $unit"
13351                         ;;
13352                 *)      ;;
13353                 esac
13354         done < $TMP/$tfile.tmp
13355
13356         #check that we actually got some stats
13357         [ "$read_bytes" ] || error "Missing read_bytes stats"
13358         [ "$write_bytes" ] || error "Missing write_bytes stats"
13359         [ "$read_bytes" != 0 ] || error "no read done"
13360         [ "$write_bytes" != 0 ] || error "no write done"
13361 }
13362 run_test 127b "verify the llite client stats are sane"
13363
13364 test_127c() { # LU-12394
13365         [ "$OSTCOUNT" -lt "2" ] && skip_env "needs >= 2 OSTs"
13366         local size
13367         local bsize
13368         local reads
13369         local writes
13370         local count
13371
13372         $LCTL set_param llite.*.extents_stats=1
13373         stack_trap "$LCTL set_param llite.*.extents_stats=0" EXIT
13374
13375         # Use two stripes so there is enough space in default config
13376         $LFS setstripe -c 2 $DIR/$tfile
13377
13378         # Extent stats start at 0-4K and go in power of two buckets
13379         # LL_HIST_START = 12 --> 2^12 = 4K
13380         # We do 3K*2^i, so 3K, 6K, 12K, 24K... hitting each bucket.
13381         # We do not do buckets larger than 64 MiB to avoid ENOSPC issues on
13382         # small configs
13383         for size in 3K 6K 12K 24K 48K 96K 192K 384K 768K 1536K 3M 6M 12M 24M 48M;
13384                 do
13385                 # Write and read, 2x each, second time at a non-zero offset
13386                 dd if=/dev/zero of=$DIR/$tfile bs=$size count=1
13387                 dd if=/dev/zero of=$DIR/$tfile bs=$size count=1 seek=10
13388                 dd if=$DIR/$tfile of=/dev/null bs=$size count=1
13389                 dd if=$DIR/$tfile of=/dev/null bs=$size count=1 seek=10
13390                 rm -f $DIR/$tfile
13391         done
13392
13393         $LCTL get_param llite.*.extents_stats
13394
13395         count=2
13396         for bsize in 4K 8K 16K 32K 64K 128K 256K 512K 1M 2M 4M 8M 16M 32M 64M;
13397                 do
13398                 local bucket=$($LCTL get_param -n llite.*.extents_stats |
13399                                 grep -m 1 $bsize)
13400                 reads=$(echo $bucket | awk '{print $5}')
13401                 writes=$(echo $bucket | awk '{print $9}')
13402                 [ "$reads" -eq $count ] ||
13403                         error "$reads reads in < $bsize bucket, expect $count"
13404                 [ "$writes" -eq $count ] ||
13405                         error "$writes writes in < $bsize bucket, expect $count"
13406         done
13407
13408         # Test mmap write and read
13409         $LCTL set_param llite.*.extents_stats=c
13410         size=512
13411         dd if=/dev/zero of=$DIR/$tfile bs=${size}K count=1
13412         $MULTIOP $DIR/$tfile OSMRUc || error "$MULTIOP $DIR/$tfile failed"
13413         $MULTIOP $DIR/$tfile OSMWUc || error "$MULTIOP $DIR/$tfile failed"
13414
13415         $LCTL get_param llite.*.extents_stats
13416
13417         count=$(((size*1024) / PAGE_SIZE))
13418
13419         bsize=$((2 * PAGE_SIZE / 1024))K
13420
13421         bucket=$($LCTL get_param -n llite.*.extents_stats |
13422                         grep -m 1 $bsize)
13423         reads=$(echo $bucket | awk '{print $5}')
13424         writes=$(echo $bucket | awk '{print $9}')
13425         # mmap writes fault in the page first, creating an additonal read
13426         [ "$reads" -eq $((2 * count)) ] ||
13427                 error "$reads reads in < $bsize bucket, expect $count"
13428         [ "$writes" -eq $count ] ||
13429                 error "$writes writes in < $bsize bucket, expect $count"
13430 }
13431 run_test 127c "test llite extent stats with regular & mmap i/o"
13432
13433 test_128() { # bug 15212
13434         touch $DIR/$tfile
13435         $LFS 2>&1 <<-EOF | tee $TMP/$tfile.log
13436                 find $DIR/$tfile
13437                 find $DIR/$tfile
13438         EOF
13439
13440         result=$(grep error $TMP/$tfile.log)
13441         rm -f $DIR/$tfile $TMP/$tfile.log
13442         [ -z "$result" ] ||
13443                 error "consecutive find's under interactive lfs failed"
13444 }
13445 run_test 128 "interactive lfs for 2 consecutive find's"
13446
13447 set_dir_limits () {
13448         local mntdev
13449         local canondev
13450         local node
13451
13452         local ldproc=/proc/fs/ldiskfs
13453         local facets=$(get_facets MDS)
13454
13455         for facet in ${facets//,/ }; do
13456                 canondev=$(ldiskfs_canon \
13457                            *.$(convert_facet2label $facet).mntdev $facet)
13458                 do_facet $facet "test -e $ldproc/$canondev/max_dir_size" ||
13459                         ldproc=/sys/fs/ldiskfs
13460                 do_facet $facet "echo $1 >$ldproc/$canondev/max_dir_size"
13461                 do_facet $facet "echo $2 >$ldproc/$canondev/warning_dir_size"
13462         done
13463 }
13464
13465 check_mds_dmesg() {
13466         local facets=$(get_facets MDS)
13467         for facet in ${facets//,/ }; do
13468                 do_facet $facet "dmesg | tail -3 | grep $1" && return 0
13469         done
13470         return 1
13471 }
13472
13473 test_129() {
13474         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13475         [[ $MDS1_VERSION -ge $(version_code 2.5.56) ]] ||
13476                 skip "Need MDS version with at least 2.5.56"
13477         if [ "$mds1_FSTYPE" != ldiskfs ]; then
13478                 skip_env "ldiskfs only test"
13479         fi
13480         remote_mds_nodsh && skip "remote MDS with nodsh"
13481
13482         local ENOSPC=28
13483         local has_warning=false
13484
13485         rm -rf $DIR/$tdir
13486         mkdir -p $DIR/$tdir
13487
13488         # block size of mds1
13489         local maxsize=$(($($LCTL get_param -n mdc.*MDT0000*.blocksize) * 8))
13490         set_dir_limits $maxsize $((maxsize * 6 / 8))
13491         stack_trap "set_dir_limits 0 0"
13492         stack_trap "unlinkmany $DIR/$tdir/file_base_ 2000 || true"
13493         local dirsize=$(stat -c%s "$DIR/$tdir")
13494         local nfiles=0
13495         while (( $dirsize <= $maxsize )); do
13496                 $MCREATE $DIR/$tdir/file_base_$nfiles
13497                 rc=$?
13498                 # check two errors:
13499                 # ENOSPC for ext4 max_dir_size, which has been used since
13500                 # kernel v3.6-rc1-8-gdf981d03ee, lustre v2_4_50_0-79-gaed82035c0
13501                 if (( rc == ENOSPC )); then
13502                         set_dir_limits 0 0
13503                         echo "rc=$rc returned as expected after $nfiles files"
13504
13505                         createmany -o $DIR/$tdir/file_extra_$nfiles. 5 ||
13506                                 error "create failed w/o dir size limit"
13507
13508                         # messages may be rate limited if test is run repeatedly
13509                         check_mds_dmesg '"is approaching max"' ||
13510                                 echo "warning message should be output"
13511                         check_mds_dmesg '"has reached max"' ||
13512                                 echo "reached message should be output"
13513
13514                         dirsize=$(stat -c%s "$DIR/$tdir")
13515
13516                         [[ $dirsize -ge $maxsize ]] && return 0
13517                         error "dirsize $dirsize < $maxsize after $nfiles files"
13518                 elif (( rc != 0 )); then
13519                         break
13520                 fi
13521                 nfiles=$((nfiles + 1))
13522                 dirsize=$(stat -c%s "$DIR/$tdir")
13523         done
13524
13525         error "rc=$rc, size=$dirsize/$maxsize, mdt=$MDSCOUNT, nfiles=$nfiles"
13526 }
13527 run_test 129 "test directory size limit ========================"
13528
13529 OLDIFS="$IFS"
13530 cleanup_130() {
13531         trap 0
13532         IFS="$OLDIFS"
13533 }
13534
13535 test_130a() {
13536         local filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
13537         [ -n "$filefrag_op" ] && skip_env "filefrag does not support FIEMAP"
13538
13539         trap cleanup_130 EXIT RETURN
13540
13541         local fm_file=$DIR/$tfile
13542         $LFS setstripe -S 65536 -c 1 $fm_file || error "setstripe on $fm_file"
13543         dd if=/dev/zero of=$fm_file bs=65536 count=1 ||
13544                 error "dd failed for $fm_file"
13545
13546         # LU-1795: test filefrag/FIEMAP once, even if unsupported
13547         filefrag -ves $fm_file
13548         RC=$?
13549         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
13550                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
13551         [ $RC != 0 ] && error "filefrag $fm_file failed"
13552
13553         filefrag_op=$(filefrag -ve -k $fm_file |
13554                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
13555         lun=$($LFS getstripe -i $fm_file)
13556
13557         start_blk=`echo $filefrag_op | cut -d: -f2 | cut -d. -f1`
13558         IFS=$'\n'
13559         tot_len=0
13560         for line in $filefrag_op
13561         do
13562                 frag_lun=`echo $line | cut -d: -f5`
13563                 ext_len=`echo $line | cut -d: -f4`
13564                 if (( $frag_lun != $lun )); then
13565                         cleanup_130
13566                         error "FIEMAP on 1-stripe file($fm_file) failed"
13567                         return
13568                 fi
13569                 (( tot_len += ext_len ))
13570         done
13571
13572         if (( lun != frag_lun || start_blk != 0 || tot_len != 64 )); then
13573                 cleanup_130
13574                 error "FIEMAP on 1-stripe file($fm_file) failed;"
13575                 return
13576         fi
13577
13578         cleanup_130
13579
13580         echo "FIEMAP on single striped file succeeded"
13581 }
13582 run_test 130a "FIEMAP (1-stripe file)"
13583
13584 test_130b() {
13585         [ "$OSTCOUNT" -lt "2" ] && skip_env "needs >= 2 OSTs"
13586
13587         local filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
13588         [ -n "$filefrag_op" ] && skip_env "filefrag does not support FIEMAP"
13589
13590         trap cleanup_130 EXIT RETURN
13591
13592         local fm_file=$DIR/$tfile
13593         $LFS setstripe -S 65536 -c $OSTCOUNT $fm_file ||
13594                         error "setstripe on $fm_file"
13595         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
13596                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
13597
13598         dd if=/dev/zero of=$fm_file bs=1M count=$OSTCOUNT ||
13599                 error "dd failed on $fm_file"
13600
13601         filefrag -ves $fm_file || error "filefrag $fm_file failed"
13602         filefrag_op=$(filefrag -ve -k $fm_file |
13603                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
13604
13605         last_lun=$(echo $filefrag_op | cut -d: -f5 |
13606                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
13607
13608         IFS=$'\n'
13609         tot_len=0
13610         num_luns=1
13611         for line in $filefrag_op
13612         do
13613                 frag_lun=$(echo $line | cut -d: -f5 |
13614                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
13615                 ext_len=$(echo $line | cut -d: -f4)
13616                 if (( $frag_lun != $last_lun )); then
13617                         if (( tot_len != 1024 )); then
13618                                 cleanup_130
13619                                 error "FIEMAP on $fm_file failed; returned " \
13620                                 "len $tot_len for OST $last_lun instead of 1024"
13621                                 return
13622                         else
13623                                 (( num_luns += 1 ))
13624                                 tot_len=0
13625                         fi
13626                 fi
13627                 (( tot_len += ext_len ))
13628                 last_lun=$frag_lun
13629         done
13630         if (( num_luns != $OSTCOUNT || tot_len != 1024 )); then
13631                 cleanup_130
13632                 error "FIEMAP on $fm_file failed; returned wrong number of " \
13633                         "luns or wrong len for OST $last_lun"
13634                 return
13635         fi
13636
13637         cleanup_130
13638
13639         echo "FIEMAP on $OSTCOUNT-stripe file succeeded"
13640 }
13641 run_test 130b "FIEMAP ($OSTCOUNT-stripe file)"
13642
13643 test_130c() {
13644         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
13645
13646         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
13647         [ -n "$filefrag_op" ] && skip "filefrag does not support FIEMAP"
13648
13649         trap cleanup_130 EXIT RETURN
13650
13651         local fm_file=$DIR/$tfile
13652         $LFS setstripe -S 65536 -c 2 $fm_file || error "setstripe on $fm_file"
13653         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
13654                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
13655
13656         dd if=/dev/zero of=$fm_file seek=1 bs=1M count=1 ||
13657                         error "dd failed on $fm_file"
13658
13659         filefrag -ves $fm_file || error "filefrag $fm_file failed"
13660         filefrag_op=$(filefrag -ve -k $fm_file |
13661                 sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
13662
13663         last_lun=$(echo $filefrag_op | cut -d: -f5 |
13664                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
13665
13666         IFS=$'\n'
13667         tot_len=0
13668         num_luns=1
13669         for line in $filefrag_op
13670         do
13671                 frag_lun=$(echo $line | cut -d: -f5 |
13672                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
13673                 ext_len=$(echo $line | cut -d: -f4)
13674                 if (( $frag_lun != $last_lun )); then
13675                         logical=`echo $line | cut -d: -f2 | cut -d. -f1`
13676                         if (( logical != 512 )); then
13677                                 cleanup_130
13678                                 error "FIEMAP on $fm_file failed; returned " \
13679                                 "logical start for lun $logical instead of 512"
13680                                 return
13681                         fi
13682                         if (( tot_len != 512 )); then
13683                                 cleanup_130
13684                                 error "FIEMAP on $fm_file failed; returned " \
13685                                 "len $tot_len for OST $last_lun instead of 1024"
13686                                 return
13687                         else
13688                                 (( num_luns += 1 ))
13689                                 tot_len=0
13690                         fi
13691                 fi
13692                 (( tot_len += ext_len ))
13693                 last_lun=$frag_lun
13694         done
13695         if (( num_luns != 2 || tot_len != 512 )); then
13696                 cleanup_130
13697                 error "FIEMAP on $fm_file failed; returned wrong number of " \
13698                         "luns or wrong len for OST $last_lun"
13699                 return
13700         fi
13701
13702         cleanup_130
13703
13704         echo "FIEMAP on 2-stripe file with hole succeeded"
13705 }
13706 run_test 130c "FIEMAP (2-stripe file with hole)"
13707
13708 test_130d() {
13709         [[ $OSTCOUNT -lt 3 ]] && skip_env "needs >= 3 OSTs"
13710
13711         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
13712         [ -n "$filefrag_op" ] && skip "filefrag does not support FIEMAP"
13713
13714         trap cleanup_130 EXIT RETURN
13715
13716         local fm_file=$DIR/$tfile
13717         $LFS setstripe -S 65536 -c $OSTCOUNT $fm_file ||
13718                         error "setstripe on $fm_file"
13719         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
13720                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
13721
13722         local actual_stripe_count=$($LFS getstripe -c $fm_file)
13723         dd if=/dev/zero of=$fm_file bs=1M count=$actual_stripe_count ||
13724                 error "dd failed on $fm_file"
13725
13726         filefrag -ves $fm_file || error "filefrag $fm_file failed"
13727         filefrag_op=$(filefrag -ve -k $fm_file |
13728                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
13729
13730         last_lun=$(echo $filefrag_op | cut -d: -f5 |
13731                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
13732
13733         IFS=$'\n'
13734         tot_len=0
13735         num_luns=1
13736         for line in $filefrag_op
13737         do
13738                 frag_lun=$(echo $line | cut -d: -f5 |
13739                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
13740                 ext_len=$(echo $line | cut -d: -f4)
13741                 if (( $frag_lun != $last_lun )); then
13742                         if (( tot_len != 1024 )); then
13743                                 cleanup_130
13744                                 error "FIEMAP on $fm_file failed; returned " \
13745                                 "len $tot_len for OST $last_lun instead of 1024"
13746                                 return
13747                         else
13748                                 (( num_luns += 1 ))
13749                                 tot_len=0
13750                         fi
13751                 fi
13752                 (( tot_len += ext_len ))
13753                 last_lun=$frag_lun
13754         done
13755         if (( num_luns != actual_stripe_count || tot_len != 1024 )); then
13756                 cleanup_130
13757                 error "FIEMAP on $fm_file failed; returned wrong number of " \
13758                         "luns or wrong len for OST $last_lun"
13759                 return
13760         fi
13761
13762         cleanup_130
13763
13764         echo "FIEMAP on N-stripe file succeeded"
13765 }
13766 run_test 130d "FIEMAP (N-stripe file)"
13767
13768 test_130e() {
13769         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
13770
13771         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
13772         [ -n "$filefrag_op" ] && skip_env "filefrag does not support FIEMAP"
13773
13774         trap cleanup_130 EXIT RETURN
13775
13776         local fm_file=$DIR/$tfile
13777         $LFS setstripe -S 131072 -c 2 $fm_file || error "setstripe on $fm_file"
13778
13779         NUM_BLKS=512
13780         EXPECTED_LEN=$(( (NUM_BLKS / 2) * 64 ))
13781         for ((i = 0; i < $NUM_BLKS; i++)); do
13782                 dd if=/dev/zero of=$fm_file count=1 bs=64k seek=$((2*$i)) \
13783                         conv=notrunc > /dev/null 2>&1
13784         done
13785
13786         filefrag -ves $fm_file || error "filefrag $fm_file failed"
13787         filefrag_op=$(filefrag -ve -k $fm_file |
13788                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
13789
13790         last_lun=$(echo $filefrag_op | cut -d: -f5)
13791
13792         IFS=$'\n'
13793         tot_len=0
13794         num_luns=1
13795         for line in $filefrag_op; do
13796                 frag_lun=$(echo $line | cut -d: -f5)
13797                 ext_len=$(echo $line | cut -d: -f4)
13798                 if [[ "$frag_lun" != "$last_lun" ]]; then
13799                         if (( tot_len != $EXPECTED_LEN )); then
13800                                 cleanup_130
13801                                 error "OST$last_lun $tot_len != $EXPECTED_LEN"
13802                         else
13803                                 (( num_luns += 1 ))
13804                                 tot_len=0
13805                         fi
13806                 fi
13807                 (( tot_len += ext_len ))
13808                 last_lun=$frag_lun
13809         done
13810         if (( num_luns != 2 || tot_len != $EXPECTED_LEN )); then
13811                 cleanup_130
13812                 error "OST$last_lun $num_luns != 2, $tot_len != $EXPECTED_LEN"
13813         fi
13814
13815         echo "FIEMAP with continuation calls succeeded"
13816 }
13817 run_test 130e "FIEMAP (test continuation FIEMAP calls)"
13818
13819 test_130f() {
13820         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
13821         [ -n "$filefrag_op" ] && skip "filefrag does not support FIEMAP"
13822
13823         local fm_file=$DIR/$tfile
13824         $MULTIOP $fm_file oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:T33554432c ||
13825                 error "multiop create with lov_delay_create on $fm_file"
13826
13827         filefrag -ves $fm_file || error "filefrag $fm_file failed"
13828         filefrag_extents=$(filefrag -vek $fm_file |
13829                            awk '/extents? found/ { print $2 }')
13830         if [[ "$filefrag_extents" != "0" ]]; then
13831                 error "$fm_file: filefrag_extents=$filefrag_extents != 0"
13832         fi
13833
13834         rm -f $fm_file
13835 }
13836 run_test 130f "FIEMAP (unstriped file)"
13837
13838 test_130g() {
13839         local file=$DIR/$tfile
13840         local nr=$((OSTCOUNT * 100))
13841
13842         $LFS setstripe -C $nr $file ||
13843                 error "failed to setstripe -C $nr $file"
13844
13845         dd if=/dev/zero of=$file count=$nr bs=1M
13846         sync
13847         nr=$($LFS getstripe -c $file)
13848
13849         local extents=$(filefrag -v $file |
13850                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}' | wc -l)
13851
13852         echo "filefrag list $extents extents in file with stripecount $nr"
13853         if (( extents < nr )); then
13854                 $LFS getstripe $file
13855                 filefrag -v $file
13856                 error "filefrag printed $extents < $nr extents"
13857         fi
13858
13859         rm -f $file
13860 }
13861 run_test 130g "FIEMAP (overstripe file)"
13862
13863 # Test for writev/readv
13864 test_131a() {
13865         rwv -f $DIR/$tfile -w -n 3 524288 1048576 1572864 ||
13866                 error "writev test failed"
13867         rwv -f $DIR/$tfile -r -v -n 2 1572864 1048576 ||
13868                 error "readv failed"
13869         rm -f $DIR/$tfile
13870 }
13871 run_test 131a "test iov's crossing stripe boundary for writev/readv"
13872
13873 test_131b() {
13874         local fsize=$((524288 + 1048576 + 1572864))
13875         rwv -f $DIR/$tfile -w -a -n 3 524288 1048576 1572864 &&
13876                 $CHECKSTAT -t file $DIR/$tfile -s $fsize ||
13877                         error "append writev test failed"
13878
13879         ((fsize += 1572864 + 1048576))
13880         rwv -f $DIR/$tfile -w -a -n 2 1572864 1048576 &&
13881                 $CHECKSTAT -t file $DIR/$tfile -s $fsize ||
13882                         error "append writev test failed"
13883         rm -f $DIR/$tfile
13884 }
13885 run_test 131b "test append writev"
13886
13887 test_131c() {
13888         rwv -f $DIR/$tfile -w -d -n 1 1048576 || return 0
13889         error "NOT PASS"
13890 }
13891 run_test 131c "test read/write on file w/o objects"
13892
13893 test_131d() {
13894         rwv -f $DIR/$tfile -w -n 1 1572864
13895         NOB=`rwv -f $DIR/$tfile -r -n 3 524288 524288 1048576 | awk '/error/ {print $6}'`
13896         if [ "$NOB" != 1572864 ]; then
13897                 error "Short read filed: read $NOB bytes instead of 1572864"
13898         fi
13899         rm -f $DIR/$tfile
13900 }
13901 run_test 131d "test short read"
13902
13903 test_131e() {
13904         rwv -f $DIR/$tfile -w -s 1048576 -n 1 1048576
13905         rwv -f $DIR/$tfile -r -z -s 0 -n 1 524288 || \
13906         error "read hitting hole failed"
13907         rm -f $DIR/$tfile
13908 }
13909 run_test 131e "test read hitting hole"
13910
13911 check_stats() {
13912         local facet=$1
13913         local op=$2
13914         local want=${3:-0}
13915         local res
13916
13917         case $facet in
13918         mds*) res=$(do_facet $facet \
13919                    $LCTL get_param mdt.$FSNAME-MDT0000.md_stats | grep "$op")
13920                  ;;
13921         ost*) res=$(do_facet $facet \
13922                    $LCTL get_param obdfilter.$FSNAME-OST0000.stats | grep "$op")
13923                  ;;
13924         *) error "Wrong facet '$facet'" ;;
13925         esac
13926         [ "$res" ] || error "The counter for $op on $facet was not incremented"
13927         # if the argument $3 is zero, it means any stat increment is ok.
13928         if [[ $want -gt 0 ]]; then
13929                 local count=$(echo $res | awk '{ print $2 }')
13930                 [[ $count -ne $want ]] &&
13931                         error "The $op counter on $facet is $count, not $want"
13932         fi
13933 }
13934
13935 test_133a() {
13936         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13937         remote_ost_nodsh && skip "remote OST with nodsh"
13938         remote_mds_nodsh && skip "remote MDS with nodsh"
13939         do_facet $SINGLEMDS $LCTL list_param mdt.*.rename_stats ||
13940                 skip_env "MDS doesn't support rename stats"
13941
13942         local testdir=$DIR/${tdir}/stats_testdir
13943
13944         mkdir -p $DIR/${tdir}
13945
13946         # clear stats.
13947         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
13948         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
13949
13950         # verify mdt stats first.
13951         mkdir ${testdir} || error "mkdir failed"
13952         check_stats $SINGLEMDS "mkdir" 1
13953         touch ${testdir}/${tfile} || error "touch failed"
13954         check_stats $SINGLEMDS "open" 1
13955         check_stats $SINGLEMDS "close" 1
13956         [ $MDS1_VERSION -ge $(version_code 2.8.54) ] && {
13957                 mknod ${testdir}/${tfile}-pipe p || error "mknod failed"
13958                 check_stats $SINGLEMDS "mknod" 2
13959         }
13960         rm -f ${testdir}/${tfile}-pipe || error "pipe remove failed"
13961         check_stats $SINGLEMDS "unlink" 1
13962         rm -f ${testdir}/${tfile} || error "file remove failed"
13963         check_stats $SINGLEMDS "unlink" 2
13964
13965         # remove working dir and check mdt stats again.
13966         rmdir ${testdir} || error "rmdir failed"
13967         check_stats $SINGLEMDS "rmdir" 1
13968
13969         local testdir1=$DIR/${tdir}/stats_testdir1
13970         mkdir -p ${testdir}
13971         mkdir -p ${testdir1}
13972         touch ${testdir1}/test1
13973         mv ${testdir1}/test1 ${testdir} || error "file crossdir rename"
13974         check_stats $SINGLEMDS "crossdir_rename" 1
13975
13976         mv ${testdir}/test1 ${testdir}/test0 || error "file samedir rename"
13977         check_stats $SINGLEMDS "samedir_rename" 1
13978
13979         rm -rf $DIR/${tdir}
13980 }
13981 run_test 133a "Verifying MDT stats ========================================"
13982
13983 test_133b() {
13984         local res
13985
13986         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13987         remote_ost_nodsh && skip "remote OST with nodsh"
13988         remote_mds_nodsh && skip "remote MDS with nodsh"
13989
13990         local testdir=$DIR/${tdir}/stats_testdir
13991
13992         mkdir -p ${testdir} || error "mkdir failed"
13993         touch ${testdir}/${tfile} || error "touch failed"
13994         cancel_lru_locks mdc
13995
13996         # clear stats.
13997         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
13998         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
13999
14000         # extra mdt stats verification.
14001         chmod 444 ${testdir}/${tfile} || error "chmod failed"
14002         check_stats $SINGLEMDS "setattr" 1
14003         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
14004         if [ $MDS1_VERSION -ne $(version_code 2.2.0) ]
14005         then            # LU-1740
14006                 ls -l ${testdir}/${tfile} > /dev/null|| error "ls failed"
14007                 check_stats $SINGLEMDS "getattr" 1
14008         fi
14009         rm -rf $DIR/${tdir}
14010
14011         # when DNE is enabled, MDT uses STATFS RPC to ping other targets
14012         # so the check below is not reliable
14013         [ $MDSCOUNT -eq 1 ] || return 0
14014
14015         # Sleep to avoid a cached response.
14016         #define OBD_STATFS_CACHE_SECONDS 1
14017         sleep 2
14018         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
14019         do_facet ost1 $LCTL set_param obdfilter.*.exports.*.stats=clear
14020         $LFS df || error "lfs failed"
14021         check_stats $SINGLEMDS "statfs" 1
14022
14023         # check aggregated statfs (LU-10018)
14024         [ $MDS1_VERSION -lt $(version_code 2.11.54) ] &&
14025                 return 0
14026         [ $CLIENT_VERSION -lt $(version_code 2.11.54) ] &&
14027                 return 0
14028         sleep 2
14029         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
14030         do_facet ost1 $LCTL set_param obdfilter.*.exports.*.stats=clear
14031         df $DIR
14032         check_stats $SINGLEMDS "statfs" 1
14033
14034         # We want to check that the client didn't send OST_STATFS to
14035         # ost1 but the MDT also uses OST_STATFS for precreate. So some
14036         # extra care is needed here.
14037         if remote_mds; then
14038                 local nid=$($LCTL list_nids | head -1 | sed  "s/\./\\\./g")
14039                 local param="obdfilter.$FSNAME-OST0000.exports.'$nid'.stats"
14040
14041                 res=$(do_facet ost1 $LCTL get_param $param | grep statfs)
14042                 [ "$res" ] && error "OST got STATFS"
14043         fi
14044
14045         return 0
14046 }
14047 run_test 133b "Verifying extra MDT stats =================================="
14048
14049 test_133c() {
14050         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14051         remote_ost_nodsh && skip "remote OST with nodsh"
14052         remote_mds_nodsh && skip "remote MDS with nodsh"
14053
14054         local testdir=$DIR/$tdir/stats_testdir
14055
14056         test_mkdir -p $testdir
14057
14058         # verify obdfilter stats.
14059         $LFS setstripe -c 1 -i 0 $testdir/$tfile
14060         sync
14061         cancel_lru_locks osc
14062         wait_delete_completed
14063
14064         # clear stats.
14065         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
14066         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
14067
14068         dd if=/dev/zero of=$testdir/$tfile conv=notrunc bs=512k count=1 ||
14069                 error "dd failed"
14070         sync
14071         cancel_lru_locks osc
14072         check_stats ost1 "write" 1
14073
14074         dd if=$testdir/$tfile of=/dev/null bs=1k count=1 || error "dd failed"
14075         check_stats ost1 "read" 1
14076
14077         > $testdir/$tfile || error "truncate failed"
14078         check_stats ost1 "punch" 1
14079
14080         rm -f $testdir/$tfile || error "file remove failed"
14081         wait_delete_completed
14082         check_stats ost1 "destroy" 1
14083
14084         rm -rf $DIR/$tdir
14085 }
14086 run_test 133c "Verifying OST stats ========================================"
14087
14088 order_2() {
14089         local value=$1
14090         local orig=$value
14091         local order=1
14092
14093         while [ $value -ge 2 ]; do
14094                 order=$((order*2))
14095                 value=$((value/2))
14096         done
14097
14098         if [ $orig -gt $order ]; then
14099                 order=$((order*2))
14100         fi
14101         echo $order
14102 }
14103
14104 size_in_KMGT() {
14105     local value=$1
14106     local size=('K' 'M' 'G' 'T');
14107     local i=0
14108     local size_string=$value
14109
14110     while [ $value -ge 1024 ]; do
14111         if [ $i -gt 3 ]; then
14112             #T is the biggest unit we get here, if that is bigger,
14113             #just return XXXT
14114             size_string=${value}T
14115             break
14116         fi
14117         value=$((value >> 10))
14118         if [ $value -lt 1024 ]; then
14119             size_string=${value}${size[$i]}
14120             break
14121         fi
14122         i=$((i + 1))
14123     done
14124
14125     echo $size_string
14126 }
14127
14128 get_rename_size() {
14129         local size=$1
14130         local context=${2:-.}
14131         local sample=$(do_facet $SINGLEMDS $LCTL \
14132                 get_param mdt.$FSNAME-MDT0000.rename_stats |
14133                 grep -A1 $context |
14134                 awk '/ '${size}'/ {print $4}' | sed -e "s/,//g")
14135         echo $sample
14136 }
14137
14138 test_133d() {
14139         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14140         remote_ost_nodsh && skip "remote OST with nodsh"
14141         remote_mds_nodsh && skip "remote MDS with nodsh"
14142         do_facet $SINGLEMDS $LCTL list_param mdt.*.rename_stats ||
14143                 skip_env "MDS doesn't support rename stats"
14144
14145         local testdir1=$DIR/${tdir}/stats_testdir1
14146         local testdir2=$DIR/${tdir}/stats_testdir2
14147         mkdir -p $DIR/${tdir}
14148
14149         do_facet $SINGLEMDS $LCTL set_param mdt.*.rename_stats=clear
14150
14151         lfs mkdir -i 0 -c 1 ${testdir1} || error "mkdir failed"
14152         lfs mkdir -i 0 -c 1 ${testdir2} || error "mkdir failed"
14153
14154         createmany -o $testdir1/test 512 || error "createmany failed"
14155
14156         # check samedir rename size
14157         mv ${testdir1}/test0 ${testdir1}/test_0
14158
14159         local testdir1_size=$(ls -l $DIR/${tdir} |
14160                 awk '/stats_testdir1/ {print $5}')
14161         local testdir2_size=$(ls -l $DIR/${tdir} |
14162                 awk '/stats_testdir2/ {print $5}')
14163
14164         testdir1_size=$(order_2 $testdir1_size)
14165         testdir2_size=$(order_2 $testdir2_size)
14166
14167         testdir1_size=$(size_in_KMGT $testdir1_size)
14168         testdir2_size=$(size_in_KMGT $testdir2_size)
14169
14170         echo "source rename dir size: ${testdir1_size}"
14171         echo "target rename dir size: ${testdir2_size}"
14172
14173         local cmd="do_facet $SINGLEMDS $LCTL "
14174         cmd+="get_param mdt.$FSNAME-MDT0000.rename_stats"
14175
14176         eval $cmd || error "$cmd failed"
14177         local samedir=$($cmd | grep 'same_dir')
14178         local same_sample=$(get_rename_size $testdir1_size)
14179         [ -z "$samedir" ] && error "samedir_rename_size count error"
14180         [[ $same_sample -eq 1 ]] ||
14181                 error "samedir_rename_size error $same_sample"
14182         echo "Check same dir rename stats success"
14183
14184         do_facet $SINGLEMDS $LCTL set_param mdt.*.rename_stats=clear
14185
14186         # check crossdir rename size
14187         mv ${testdir1}/test_0 ${testdir2}/test_0
14188
14189         testdir1_size=$(ls -l $DIR/${tdir} |
14190                 awk '/stats_testdir1/ {print $5}')
14191         testdir2_size=$(ls -l $DIR/${tdir} |
14192                 awk '/stats_testdir2/ {print $5}')
14193
14194         testdir1_size=$(order_2 $testdir1_size)
14195         testdir2_size=$(order_2 $testdir2_size)
14196
14197         testdir1_size=$(size_in_KMGT $testdir1_size)
14198         testdir2_size=$(size_in_KMGT $testdir2_size)
14199
14200         echo "source rename dir size: ${testdir1_size}"
14201         echo "target rename dir size: ${testdir2_size}"
14202
14203         eval $cmd || error "$cmd failed"
14204         local crossdir=$($cmd | grep 'crossdir')
14205         local src_sample=$(get_rename_size $testdir1_size crossdir_src)
14206         local tgt_sample=$(get_rename_size $testdir2_size crossdir_tgt)
14207         [ -z "$crossdir" ] && error "crossdir_rename_size count error"
14208         [[ $src_sample -eq 1 ]] ||
14209                 error "crossdir_rename_size error $src_sample"
14210         [[ $tgt_sample -eq 1 ]] ||
14211                 error "crossdir_rename_size error $tgt_sample"
14212         echo "Check cross dir rename stats success"
14213         rm -rf $DIR/${tdir}
14214 }
14215 run_test 133d "Verifying rename_stats ========================================"
14216
14217 test_133e() {
14218         remote_mds_nodsh && skip "remote MDS with nodsh"
14219         remote_ost_nodsh && skip "remote OST with nodsh"
14220         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14221
14222         local testdir=$DIR/${tdir}/stats_testdir
14223         local ctr f0 f1 bs=32768 count=42 sum
14224
14225         mkdir -p ${testdir} || error "mkdir failed"
14226
14227         $LFS setstripe -c 1 -i 0 ${testdir}/${tfile}
14228
14229         for ctr in {write,read}_bytes; do
14230                 sync
14231                 cancel_lru_locks osc
14232
14233                 do_facet ost1 $LCTL set_param -n \
14234                         "obdfilter.*.exports.clear=clear"
14235
14236                 if [ $ctr = write_bytes ]; then
14237                         f0=/dev/zero
14238                         f1=${testdir}/${tfile}
14239                 else
14240                         f0=${testdir}/${tfile}
14241                         f1=/dev/null
14242                 fi
14243
14244                 dd if=$f0 of=$f1 conv=notrunc bs=$bs count=$count || \
14245                         error "dd failed"
14246                 sync
14247                 cancel_lru_locks osc
14248
14249                 sum=$(do_facet ost1 $LCTL get_param \
14250                         "obdfilter.*.exports.*.stats" |
14251                         awk -v ctr=$ctr 'BEGIN { sum = 0 }
14252                                 $1 == ctr { sum += $7 }
14253                                 END { printf("%0.0f", sum) }')
14254
14255                 if ((sum != bs * count)); then
14256                         error "Bad $ctr sum, expected $((bs * count)), got $sum"
14257                 fi
14258         done
14259
14260         rm -rf $DIR/${tdir}
14261 }
14262 run_test 133e "Verifying OST {read,write}_bytes nid stats ================="
14263
14264 test_133f() {
14265         [[ $(lustre_version_code $facet) -ge $(version_code 2.7.65) ]] ||
14266                 skip "too old lustre for get_param -R ($facet_ver)"
14267
14268         # verifying readability.
14269         $LCTL get_param -R '*' &> /dev/null
14270
14271         # Verifing writability with badarea_io.
14272         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
14273         local skipped_params='force_lbug|changelog_mask|daemon_file'
14274         $LCTL list_param -FR '*' | grep '=' | tr -d = |
14275                 egrep -v "$skipped_params" |
14276                 xargs -n 1 find $proc_dirs -name |
14277                 xargs -n 1 badarea_io ||
14278                 error "client badarea_io failed"
14279
14280         # remount the FS in case writes/reads /proc break the FS
14281         cleanup || error "failed to unmount"
14282         setup || error "failed to setup"
14283 }
14284 run_test 133f "Check reads/writes of client lustre proc files with bad area io"
14285
14286 test_133g() {
14287         remote_mds_nodsh && skip "remote MDS with nodsh"
14288         remote_ost_nodsh && skip "remote OST with nodsh"
14289
14290         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
14291         local skipped_params="'force_lbug|changelog_mask|daemon_file'"
14292         local facet
14293         for facet in mds1 ost1; do
14294                 local facet_ver=$(lustre_version_code $facet)
14295                 if [ $facet_ver -ge $(version_code 2.7.65) ]; then
14296                         do_facet $facet "$LCTL get_param -R '*'" &> /dev/null
14297                 else
14298                         log "$facet: too old lustre for get_param -R"
14299                 fi
14300                 if [ $facet_ver -ge $(version_code 2.5.54) ]; then
14301                         do_facet $facet "$LCTL list_param -FR '*' | grep '=' |
14302                                 tr -d = | egrep -v $skipped_params |
14303                                 xargs -n 1 find $proc_dirs -name |
14304                                 xargs -n 1 badarea_io" ||
14305                                         error "$facet badarea_io failed"
14306                 else
14307                         skip_noexit "$facet: too old lustre for get_param -R"
14308                 fi
14309         done
14310
14311         # remount the FS in case writes/reads /proc break the FS
14312         cleanup || error "failed to unmount"
14313         setup || error "failed to setup"
14314 }
14315 run_test 133g "Check reads/writes of server lustre proc files with bad area io"
14316
14317 test_133h() {
14318         remote_mds_nodsh && skip "remote MDS with nodsh"
14319         remote_ost_nodsh && skip "remote OST with nodsh"
14320         [[ $MDS1_VERSION -lt $(version_code 2.9.54) ]] &&
14321                 skip "Need MDS version at least 2.9.54"
14322
14323         local facet
14324         for facet in client mds1 ost1; do
14325                 # Get the list of files that are missing the terminating newline
14326                 local plist=$(do_facet $facet
14327                         $LCTL list_param -FR '*' | grep '=' | tr -d =)
14328                 local ent
14329                 for ent in $plist; do
14330                         local missing=$(do_facet $facet $LCTL get_param $ent \|\
14331                                 awk -v FS='\v' -v RS='\v\v' \
14332                                 "'END { if(NR>0 && \\\$NF !~ /.*\\\n\$/) \
14333                                         print FILENAME}'" 2>/dev/null)
14334                         [ -z $missing ] || {
14335                                 do_facet $facet $LCTL get_param $ent | od -An -tx1
14336                                 error "file does not end with newline: $facet-$ent"
14337                         }
14338                 done
14339         done
14340 }
14341 run_test 133h "Proc files should end with newlines"
14342
14343 test_134a() {
14344         remote_mds_nodsh && skip "remote MDS with nodsh"
14345         [[ $MDS1_VERSION -lt $(version_code 2.7.54) ]] &&
14346                 skip "Need MDS version at least 2.7.54"
14347
14348         mkdir_on_mdt0 $DIR/$tdir || error "failed to create $DIR/$tdir"
14349         cancel_lru_locks mdc
14350
14351         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
14352         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
14353         [ $unused -eq 0 ] || error "$unused locks are not cleared"
14354
14355         local nr=1000
14356         createmany -o $DIR/$tdir/f $nr ||
14357                 error "failed to create $nr files in $DIR/$tdir"
14358         unused=$($LCTL get_param -n $nsdir.lock_unused_count)
14359
14360         #define OBD_FAIL_LDLM_WATERMARK_LOW     0x327
14361         do_facet mds1 $LCTL set_param fail_loc=0x327
14362         do_facet mds1 $LCTL set_param fail_val=500
14363         touch $DIR/$tdir/m
14364
14365         echo "sleep 10 seconds ..."
14366         sleep 10
14367         local lck_cnt=$($LCTL get_param -n $nsdir.lock_unused_count)
14368
14369         do_facet mds1 $LCTL set_param fail_loc=0
14370         do_facet mds1 $LCTL set_param fail_val=0
14371         [ $lck_cnt -lt $unused ] ||
14372                 error "No locks reclaimed, before:$unused, after:$lck_cnt"
14373
14374         rm $DIR/$tdir/m
14375         unlinkmany $DIR/$tdir/f $nr
14376 }
14377 run_test 134a "Server reclaims locks when reaching lock_reclaim_threshold"
14378
14379 test_134b() {
14380         remote_mds_nodsh && skip "remote MDS with nodsh"
14381         [[ $MDS1_VERSION -lt $(version_code 2.7.54) ]] &&
14382                 skip "Need MDS version at least 2.7.54"
14383
14384         mkdir_on_mdt0 $DIR/$tdir || error "failed to create $DIR/$tdir"
14385         cancel_lru_locks mdc
14386
14387         local low_wm=$(do_facet mds1 $LCTL get_param -n \
14388                         ldlm.lock_reclaim_threshold_mb)
14389         # disable reclaim temporarily
14390         do_facet mds1 $LCTL set_param ldlm.lock_reclaim_threshold_mb=0
14391
14392         #define OBD_FAIL_LDLM_WATERMARK_HIGH     0x328
14393         do_facet mds1 $LCTL set_param fail_loc=0x328
14394         do_facet mds1 $LCTL set_param fail_val=500
14395
14396         $LCTL set_param debug=+trace
14397
14398         local nr=600
14399         createmany -o $DIR/$tdir/f $nr &
14400         local create_pid=$!
14401
14402         echo "Sleep $TIMEOUT seconds ..."
14403         sleep $TIMEOUT
14404         if ! ps -p $create_pid  > /dev/null 2>&1; then
14405                 do_facet mds1 $LCTL set_param fail_loc=0
14406                 do_facet mds1 $LCTL set_param fail_val=0
14407                 do_facet mds1 $LCTL set_param \
14408                         ldlm.lock_reclaim_threshold_mb=${low_wm}m
14409                 error "createmany finished incorrectly!"
14410         fi
14411         do_facet mds1 $LCTL set_param fail_loc=0
14412         do_facet mds1 $LCTL set_param fail_val=0
14413         do_facet mds1 $LCTL set_param ldlm.lock_reclaim_threshold_mb=${low_wm}m
14414         wait $create_pid || return 1
14415
14416         unlinkmany $DIR/$tdir/f $nr
14417 }
14418 run_test 134b "Server rejects lock request when reaching lock_limit_mb"
14419
14420 test_135() {
14421         remote_mds_nodsh && skip "remote MDS with nodsh"
14422         [[ $MDS1_VERSION -lt $(version_code 2.13.50) ]] &&
14423                 skip "Need MDS version at least 2.13.50"
14424         local fname
14425
14426         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
14427
14428 #define OBD_FAIL_PLAIN_RECORDS 0x1319
14429         #set only one record at plain llog
14430         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x1319 fail_val=1
14431
14432         #fill already existed plain llog each 64767
14433         #wrapping whole catalog
14434         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 1))
14435
14436         createmany -o $DIR/$tdir/$tfile_ 64700
14437         for (( i = 0; i < 64700; i = i + 2 ))
14438         do
14439                 rm $DIR/$tdir/$tfile_$i &
14440                 rm $DIR/$tdir/$tfile_$((i + 1)) &
14441                 local pid=$!
14442                 wait $pid
14443         done
14444
14445         #waiting osp synchronization
14446         wait_delete_completed
14447 }
14448 run_test 135 "Race catalog processing"
14449
14450 test_136() {
14451         remote_mds_nodsh && skip "remote MDS with nodsh"
14452         [[ $MDS1_VERSION -lt $(version_code 2.13.50) ]] &&
14453                 skip "Need MDS version at least 2.13.50"
14454         local fname
14455
14456         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
14457         $LFS setstripe -c 1 -i 0 $DIR/$tdir || error "failed to set striping"
14458         #set only one record at plain llog
14459 #define OBD_FAIL_CATALOG_FULL_CHECK                0x131a
14460         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x131a fail_val=1
14461
14462         #fill already existed 2 plain llogs each 64767
14463         #wrapping whole catalog
14464         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 1))
14465         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 3 / 2))
14466         wait_delete_completed
14467
14468         createmany -o $DIR/$tdir/$tfile_ 10
14469         sleep 25
14470
14471         do_facet $SINGLEMDS $LCTL set_param fail_val=3
14472         for (( i = 0; i < 10; i = i + 3 ))
14473         do
14474                 rm $DIR/$tdir/$tfile_$i &
14475                 rm $DIR/$tdir/$tfile_$((i + 1)) &
14476                 local pid=$!
14477                 wait $pid
14478                 sleep 7
14479                 rm $DIR/$tdir/$tfile_$((i + 2)) &
14480         done
14481
14482         #waiting osp synchronization
14483         wait_delete_completed
14484 }
14485 run_test 136 "Race catalog processing 2"
14486
14487 test_140() { #bug-17379
14488         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14489
14490         test_mkdir $DIR/$tdir
14491         cd $DIR/$tdir || error "Changing to $DIR/$tdir"
14492         cp $(which stat) . || error "Copying stat to $DIR/$tdir"
14493
14494         # VFS limits max symlink depth to 5(4KSTACK) or 7(8KSTACK) or 8
14495         # For kernel > 3.5, bellow only tests consecutive symlink (MAX 40)
14496         local i=0
14497         while i=$((i + 1)); do
14498                 test_mkdir $i
14499                 cd $i || error "Changing to $i"
14500                 ln -s ../stat stat || error "Creating stat symlink"
14501                 # Read the symlink until ELOOP present,
14502                 # not LBUGing the system is considered success,
14503                 # we didn't overrun the stack.
14504                 $OPENFILE -f O_RDONLY stat >/dev/null 2>&1; ret=$?
14505                 if [ $ret -ne 0 ]; then
14506                         if [ $ret -eq 40 ]; then
14507                                 break  # -ELOOP
14508                         else
14509                                 error "Open stat symlink"
14510                                         return
14511                         fi
14512                 fi
14513         done
14514         i=$((i - 1))
14515         echo "The symlink depth = $i"
14516         [ $i -eq 5 ] || [ $i -eq 7 ] || [ $i -eq 8 ] || [ $i -eq 40 ] ||
14517                 error "Invalid symlink depth"
14518
14519         # Test recursive symlink
14520         ln -s symlink_self symlink_self
14521         $OPENFILE -f O_RDONLY symlink_self >/dev/null 2>&1; ret=$?
14522         echo "open symlink_self returns $ret"
14523         [ $ret -eq 40 ] || error "recursive symlink doesn't return -ELOOP"
14524 }
14525 run_test 140 "Check reasonable stack depth (shouldn't LBUG) ===="
14526
14527 test_150a() {
14528         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14529
14530         local TF="$TMP/$tfile"
14531
14532         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
14533         dd if=/dev/urandom of=$TF bs=6096 count=1 || error "dd failed"
14534         cp $TF $DIR/$tfile
14535         cancel_lru_locks $OSC
14536         cmp $TF $DIR/$tfile || error "$TMP/$tfile $DIR/$tfile differ"
14537         remount_client $MOUNT
14538         df -P $MOUNT
14539         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (remount)"
14540
14541         $TRUNCATE $TF 6000
14542         $TRUNCATE $DIR/$tfile 6000
14543         cancel_lru_locks $OSC
14544         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (truncate1)"
14545
14546         echo "12345" >>$TF
14547         echo "12345" >>$DIR/$tfile
14548         cancel_lru_locks $OSC
14549         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (append1)"
14550
14551         echo "12345" >>$TF
14552         echo "12345" >>$DIR/$tfile
14553         cancel_lru_locks $OSC
14554         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (append2)"
14555 }
14556 run_test 150a "truncate/append tests"
14557
14558 test_150b() {
14559         check_set_fallocate_or_skip
14560
14561         touch $DIR/$tfile
14562         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
14563         check_fallocate $DIR/$tfile || error "fallocate failed"
14564 }
14565 run_test 150b "Verify fallocate (prealloc) functionality"
14566
14567 test_150bb() {
14568         check_set_fallocate_or_skip
14569
14570         touch $DIR/$tfile
14571         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
14572         dd if=/dev/urandom of=$DIR/$tfile bs=1M count=20 || error "dd failed"
14573         > $DIR/$tfile
14574         fallocate -l $((1048576 * 20)) $DIR/$tfile || error "fallocate failed"
14575         # precomputed md5sum for 20MB of zeroes
14576         local expect="8f4e33f3dc3e414ff94e5fb6905cba8c"
14577         local sum=($(md5sum $DIR/$tfile))
14578
14579         [[ "${sum[0]}" == "$expect" ]] || error "fallocate unwritten is not zero"
14580
14581         check_set_fallocate 1
14582
14583         > $DIR/$tfile
14584         fallocate -l $((1048576 * 20)) $DIR/$tfile || error "fallocate failed"
14585         sum=($(md5sum $DIR/$tfile))
14586
14587         [[ "${sum[0]}" == "$expect" ]] || error "fallocate zero is not zero"
14588 }
14589 run_test 150bb "Verify fallocate modes both zero space"
14590
14591 test_150c() {
14592         check_set_fallocate_or_skip
14593         local striping="-c2"
14594
14595         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
14596         $LFS setstripe -c $OSTCOUNT -S1M $DIR/$tfile || error "setstripe failed"
14597         fallocate -l ${OSTCOUNT}m $DIR/$tfile || error "fallocate failed"
14598         local bytes=$(($(stat -c '%b * %B' $DIR/$tfile)))
14599         local want=$((OSTCOUNT * 1048576))
14600
14601         # Must allocate all requested space, not more than 5% extra
14602         (( $bytes >= $want && $bytes < $want * 105 / 100 )) ||
14603                 error "bytes $bytes is not $want"
14604
14605         rm -f $DIR/$tfile
14606
14607         echo "verify fallocate on PFL file"
14608
14609         [[ "x$DOM" == "xyes" ]] && striping="-L mdt"
14610
14611         $LFS setstripe -E1M $striping -E16M -c3 -Eeof -c 4 $DIR/$tfile ||
14612                 error "Create $DIR/$tfile failed"
14613         fallocate -l $((1048576 * 512)) $DIR/$tfile ||
14614                         error "fallocate failed"
14615         bytes=$(($(stat -c '%b * %B' $DIR/$tfile)))
14616         want=$((512 * 1048576))
14617
14618         # Must allocate all requested space, not more than 5% extra
14619         (( $bytes >= $want && $bytes < $want * 105 / 100 )) ||
14620                 error "bytes $bytes is not $want"
14621 }
14622 run_test 150c "Verify fallocate Size and Blocks"
14623
14624 test_150d() {
14625         check_set_fallocate_or_skip
14626         local striping="-c2"
14627
14628         [[ "x$DOM" == "xyes" ]] && striping="-L mdt"
14629
14630         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
14631         $LFS setstripe -E1M $striping -E eof -c $OSTCOUNT -S1M $DIR/$tdir ||
14632                 error "setstripe failed"
14633         fallocate -o 1G -l ${OSTCOUNT}m $DIR/$tdir || error "fallocate failed"
14634         local bytes=$(($(stat -c '%b * %B' $DIR/$tdir)))
14635         local want=$((OSTCOUNT * 1048576))
14636
14637         # Must allocate all requested space, not more than 5% extra
14638         (( $bytes >= $want && $bytes < $want * 105 / 100 )) ||
14639                 error "bytes $bytes is not $want"
14640 }
14641 run_test 150d "Verify fallocate Size and Blocks - Non zero start"
14642
14643 test_150e() {
14644         check_set_fallocate_or_skip
14645
14646         echo "df before:"
14647         $LFS df
14648         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
14649         $LFS setstripe -c${OSTCOUNT} $DIR/$tfile ||
14650                 error "$LFS setstripe -c${OSTCOUNT} $DIR/$tfile failed"
14651
14652         # Find OST with Minimum Size
14653         min_size_ost=$($LFS df | awk "/$FSNAME-OST/ { print \$4 }" |
14654                        sort -un | head -1)
14655
14656         # Get 100MB per OST of the available space to reduce run time
14657         # else 60% of the available space if we are running SLOW tests
14658         if [ $SLOW == "no" ]; then
14659                 local space=$((1024 * 100 * OSTCOUNT))
14660         else
14661                 local space=$(((min_size_ost * 60)/100 * OSTCOUNT))
14662         fi
14663
14664         fallocate -l${space}k $DIR/$tfile ||
14665                 error "fallocate ${space}k $DIR/$tfile failed"
14666         echo "'fallocate -l ${space}k $DIR/$tfile' succeeded"
14667
14668         # get size immediately after fallocate. This should be correctly
14669         # updated
14670         local size=$(stat -c '%s' $DIR/$tfile)
14671         local used=$(( $(stat -c '%b * %B' $DIR/$tfile) / 1024))
14672
14673         # Sleep for a while for statfs to get updated. And not pull from cache.
14674         sleep 2
14675
14676         echo "df after fallocate:"
14677         $LFS df
14678
14679         (( size / 1024 == space )) || error "size $size != requested $space"
14680         [ "$ost1_FSTYPE" != ldiskfs ] || (( used >= space )) ||
14681                 error "used $used < space $space"
14682
14683         rm $DIR/$tfile || error "rm failed"
14684         sync
14685         wait_delete_completed
14686
14687         echo "df after unlink:"
14688         $LFS df
14689 }
14690 run_test 150e "Verify 60% of available OST space consumed by fallocate"
14691
14692 test_150f() {
14693         local size
14694         local blocks
14695         local want_size_before=20480 # in bytes
14696         local want_blocks_before=40 # 512 sized blocks
14697         local want_blocks_after=24  # 512 sized blocks
14698         local length=$(((want_blocks_before - want_blocks_after) * 512))
14699
14700         [[ $OST1_VERSION -ge $(version_code 2.14.0) ]] ||
14701                 skip "need at least 2.14.0 for fallocate punch"
14702
14703         if [ "$ost1_FSTYPE" = "zfs" ] || [ "$mds1_FSTYPE" = "zfs" ]; then
14704                 skip "LU-14160: punch mode is not implemented on OSD ZFS"
14705         fi
14706
14707         check_set_fallocate_or_skip
14708         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
14709
14710         [[ "x$DOM" == "xyes" ]] &&
14711                 $LFS setstripe -E1M -L mdt -E eof $DIR/$tfile
14712
14713         echo "Verify fallocate punch: Range within the file range"
14714         yes 'A' | dd of=$DIR/$tfile bs=4096 count=5 ||
14715                 error "dd failed for bs 4096 and count 5"
14716
14717         # Call fallocate with punch range which is within the file range
14718         fallocate -p --offset 4096 -l $length $DIR/$tfile ||
14719                 error "fallocate failed: offset 4096 and length $length"
14720         # client must see changes immediately after fallocate
14721         size=$(stat -c '%s' $DIR/$tfile)
14722         blocks=$(stat -c '%b' $DIR/$tfile)
14723
14724         # Verify punch worked.
14725         (( blocks == want_blocks_after )) ||
14726                 error "punch failed: blocks $blocks != $want_blocks_after"
14727
14728         (( size == want_size_before )) ||
14729                 error "punch failed: size $size != $want_size_before"
14730
14731         # Verify there is hole in file
14732         local data_off=$(lseek_test -d 4096 $DIR/$tfile)
14733         # precomputed md5sum
14734         local expect="4a9a834a2db02452929c0a348273b4aa"
14735
14736         cksum=($(md5sum $DIR/$tfile))
14737         [[ "${cksum[0]}" == "$expect" ]] ||
14738                 error "unexpected MD5SUM after punch: ${cksum[0]}"
14739
14740         # Start second sub-case for fallocate punch.
14741         echo "Verify fallocate punch: Range overlapping and less than blocksize"
14742         yes 'A' | dd of=$DIR/$tfile bs=4096 count=5 ||
14743                 error "dd failed for bs 4096 and count 5"
14744
14745         # Punch range less than block size will have no change in block count
14746         want_blocks_after=40  # 512 sized blocks
14747
14748         # Punch overlaps two blocks and less than blocksize
14749         fallocate -p --offset 4000 -l 3000 $DIR/$tfile ||
14750                 error "fallocate failed: offset 4000 length 3000"
14751         size=$(stat -c '%s' $DIR/$tfile)
14752         blocks=$(stat -c '%b' $DIR/$tfile)
14753
14754         # Verify punch worked.
14755         (( blocks == want_blocks_after )) ||
14756                 error "punch failed: blocks $blocks != $want_blocks_after"
14757
14758         (( size == want_size_before )) ||
14759                 error "punch failed: size $size != $want_size_before"
14760
14761         # Verify if range is really zero'ed out. We expect Zeros.
14762         # precomputed md5sum
14763         expect="c57ec5d769c3dbe3426edc3f7d7e11d3"
14764         cksum=($(md5sum $DIR/$tfile))
14765         [[ "${cksum[0]}" == "$expect" ]] ||
14766                 error "unexpected MD5SUM after punch: ${cksum[0]}"
14767 }
14768 run_test 150f "Verify fallocate punch functionality"
14769
14770 test_150g() {
14771         local space
14772         local size
14773         local blocks
14774         local blocks_after
14775         local size_after
14776         local BS=4096 # Block size in bytes
14777
14778         [[ $OST1_VERSION -ge $(version_code 2.14.0) ]] ||
14779                 skip "need at least 2.14.0 for fallocate punch"
14780
14781         if [ "$ost1_FSTYPE" = "zfs" ] || [ "$mds1_FSTYPE" = "zfs" ]; then
14782                 skip "LU-14160: punch mode is not implemented on OSD ZFS"
14783         fi
14784
14785         check_set_fallocate_or_skip
14786         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
14787
14788         if [[ "x$DOM" == "xyes" ]]; then
14789                 $LFS setstripe -E2M -L mdt -E eof -c${OSTCOUNT} $DIR/$tfile ||
14790                         error "$LFS setstripe DoM + ${OSTCOUNT} OST failed"
14791         else
14792                 $LFS setstripe -c${OSTCOUNT} $DIR/$tfile ||
14793                         error "$LFS setstripe -c${OSTCOUNT} $DIR/$tfile failed"
14794         fi
14795
14796         # Get 100MB per OST of the available space to reduce run time
14797         # else 60% of the available space if we are running SLOW tests
14798         if [ $SLOW == "no" ]; then
14799                 space=$((1024 * 100 * OSTCOUNT))
14800         else
14801                 # Find OST with Minimum Size
14802                 space=$($LFS df | awk "/$FSNAME-OST/ { print \$4 }" |
14803                         sort -un | head -1)
14804                 echo "min size OST: $space"
14805                 space=$(((space * 60)/100 * OSTCOUNT))
14806         fi
14807         # space in 1k units, round to 4k blocks
14808         local blkcount=$((space * 1024 / $BS))
14809
14810         echo "Verify fallocate punch: Very large Range"
14811         fallocate -l${space}k $DIR/$tfile ||
14812                 error "fallocate ${space}k $DIR/$tfile failed"
14813         # write 1M at the end, start and in the middle
14814         yes 'A' | dd of=$DIR/$tfile bs=$BS count=256 ||
14815                 error "dd failed: bs $BS count 256"
14816         yes 'A' | dd of=$DIR/$tfile bs=$BS seek=$((blkcount - 256)) count=256 ||
14817                 error "dd failed: bs $BS count 256 seek $((blkcount - 256))"
14818         yes 'A' | dd of=$DIR/$tfile bs=$BS seek=$((blkcount / 2)) count=1024 ||
14819                 error "dd failed: bs $BS count 256 seek $((blkcount / 2))"
14820
14821         # Gather stats.
14822         size=$(stat -c '%s' $DIR/$tfile)
14823
14824         # gather punch length.
14825         local punch_size=$((size - (BS * 2)))
14826
14827         echo "punch_size = $punch_size"
14828         echo "size - punch_size: $((size - punch_size))"
14829         echo "size - punch_size in blocks: $(((size - punch_size)/BS))"
14830
14831         # Call fallocate to punch all except 2 blocks. We leave the
14832         # first and the last block
14833         echo "fallocate -p --offset $BS -l $punch_size $DIR/$tfile"
14834         fallocate -p --offset $BS -l $punch_size $DIR/$tfile ||
14835                 error "fallocate failed: offset $BS length $punch_size"
14836
14837         size_after=$(stat -c '%s' $DIR/$tfile)
14838         blocks_after=$(stat -c '%b' $DIR/$tfile)
14839
14840         # Verify punch worked.
14841         # Size should be kept
14842         (( size == size_after )) ||
14843                 error "punch failed: size $size != $size_after"
14844
14845         # two 4k data blocks to remain plus possible 1 extra extent block
14846         (( blocks_after <= ((BS / 512) * 3) )) ||
14847                 error "too many blocks remains: $blocks_after"
14848
14849         # Verify that file has hole between the first and the last blocks
14850         local hole_start=$(lseek_test -l 0 $DIR/$tfile)
14851         local hole_end=$(lseek_test -d $BS $DIR/$tfile)
14852
14853         echo "Hole at [$hole_start, $hole_end)"
14854         (( hole_start == BS )) ||
14855                 error "no hole at offset $BS after punch"
14856
14857         (( hole_end == BS + punch_size )) ||
14858                 error "data at offset $hole_end < $((BS + punch_size))"
14859 }
14860 run_test 150g "Verify fallocate punch on large range"
14861
14862 #LU-2902 roc_hit was not able to read all values from lproc
14863 function roc_hit_init() {
14864         local list=$(comma_list $(osts_nodes))
14865         local dir=$DIR/$tdir-check
14866         local file=$dir/$tfile
14867         local BEFORE
14868         local AFTER
14869         local idx
14870
14871         test_mkdir $dir
14872         #use setstripe to do a write to every ost
14873         for i in $(seq 0 $((OSTCOUNT-1))); do
14874                 $LFS setstripe -c 1 -i $i $dir || error "$LFS setstripe $file failed"
14875                 dd if=/dev/urandom of=$file bs=4k count=4 2>&1 > /dev/null
14876                 idx=$(printf %04x $i)
14877                 BEFORE=$(get_osd_param $list *OST*$idx stats |
14878                         awk '$1 == "cache_access" {sum += $7}
14879                                 END { printf("%0.0f", sum) }')
14880
14881                 cancel_lru_locks osc
14882                 cat $file >/dev/null
14883
14884                 AFTER=$(get_osd_param $list *OST*$idx stats |
14885                         awk '$1 == "cache_access" {sum += $7}
14886                                 END { printf("%0.0f", sum) }')
14887
14888                 echo BEFORE:$BEFORE AFTER:$AFTER
14889                 if ! let "AFTER - BEFORE == 4"; then
14890                         rm -rf $dir
14891                         error "roc_hit is not safe to use"
14892                 fi
14893                 rm $file
14894         done
14895
14896         rm -rf $dir
14897 }
14898
14899 function roc_hit() {
14900         local list=$(comma_list $(osts_nodes))
14901         echo $(get_osd_param $list '' stats |
14902                 awk '$1 == "cache_hit" {sum += $7}
14903                         END { printf("%0.0f", sum) }')
14904 }
14905
14906 function set_cache() {
14907         local on=1
14908
14909         if [ "$2" == "off" ]; then
14910                 on=0;
14911         fi
14912         local list=$(comma_list $(osts_nodes))
14913         set_osd_param $list '' $1_cache_enable $on
14914
14915         cancel_lru_locks osc
14916 }
14917
14918 test_151() {
14919         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14920         remote_ost_nodsh && skip "remote OST with nodsh"
14921
14922         local CPAGES=3
14923         local list=$(comma_list $(osts_nodes))
14924
14925         # check whether obdfilter is cache capable at all
14926         if ! get_osd_param $list '' read_cache_enable >/dev/null; then
14927                 skip "not cache-capable obdfilter"
14928         fi
14929
14930         # check cache is enabled on all obdfilters
14931         if get_osd_param $list '' read_cache_enable | grep 0; then
14932                 skip "oss cache is disabled"
14933         fi
14934
14935         set_osd_param $list '' writethrough_cache_enable 1
14936
14937         # check write cache is enabled on all obdfilters
14938         if get_osd_param $list '' writethrough_cache_enable | grep 0; then
14939                 skip "oss write cache is NOT enabled"
14940         fi
14941
14942         roc_hit_init
14943
14944         #define OBD_FAIL_OBD_NO_LRU  0x609
14945         do_nodes $list $LCTL set_param fail_loc=0x609
14946
14947         # pages should be in the case right after write
14948         dd if=/dev/urandom of=$DIR/$tfile bs=4k count=$CPAGES ||
14949                 error "dd failed"
14950
14951         local BEFORE=$(roc_hit)
14952         cancel_lru_locks osc
14953         cat $DIR/$tfile >/dev/null
14954         local AFTER=$(roc_hit)
14955
14956         do_nodes $list $LCTL set_param fail_loc=0
14957
14958         if ! let "AFTER - BEFORE == CPAGES"; then
14959                 error "NOT IN CACHE: before: $BEFORE, after: $AFTER"
14960         fi
14961
14962         cancel_lru_locks osc
14963         # invalidates OST cache
14964         do_nodes $list "echo 1 > /proc/sys/vm/drop_caches"
14965         set_osd_param $list '' read_cache_enable 0
14966         cat $DIR/$tfile >/dev/null
14967
14968         # now data shouldn't be found in the cache
14969         BEFORE=$(roc_hit)
14970         cancel_lru_locks osc
14971         cat $DIR/$tfile >/dev/null
14972         AFTER=$(roc_hit)
14973         if let "AFTER - BEFORE != 0"; then
14974                 error "IN CACHE: before: $BEFORE, after: $AFTER"
14975         fi
14976
14977         set_osd_param $list '' read_cache_enable 1
14978         rm -f $DIR/$tfile
14979 }
14980 run_test 151 "test cache on oss and controls ==============================="
14981
14982 test_152() {
14983         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14984
14985         local TF="$TMP/$tfile"
14986
14987         # simulate ENOMEM during write
14988 #define OBD_FAIL_OST_NOMEM      0x226
14989         lctl set_param fail_loc=0x80000226
14990         dd if=/dev/urandom of=$TF bs=6096 count=1 || error "dd failed"
14991         cp $TF $DIR/$tfile
14992         sync || error "sync failed"
14993         lctl set_param fail_loc=0
14994
14995         # discard client's cache
14996         cancel_lru_locks osc
14997
14998         # simulate ENOMEM during read
14999         lctl set_param fail_loc=0x80000226
15000         cmp $TF $DIR/$tfile || error "cmp failed"
15001         lctl set_param fail_loc=0
15002
15003         rm -f $TF
15004 }
15005 run_test 152 "test read/write with enomem ============================"
15006
15007 test_153() {
15008         $MULTIOP $DIR/$tfile Ow4096Ycu || error "multiop failed"
15009 }
15010 run_test 153 "test if fdatasync does not crash ======================="
15011
15012 dot_lustre_fid_permission_check() {
15013         local fid=$1
15014         local ffid=$MOUNT/.lustre/fid/$fid
15015         local test_dir=$2
15016
15017         echo "stat fid $fid"
15018         stat $ffid > /dev/null || error "stat $ffid failed."
15019         echo "touch fid $fid"
15020         touch $ffid || error "touch $ffid failed."
15021         echo "write to fid $fid"
15022         cat /etc/hosts > $ffid || error "write $ffid failed."
15023         echo "read fid $fid"
15024         diff /etc/hosts $ffid || error "read $ffid failed."
15025         echo "append write to fid $fid"
15026         cat /etc/hosts >> $ffid || error "append write $ffid failed."
15027         echo "rename fid $fid"
15028         mv $ffid $test_dir/$tfile.1 &&
15029                 error "rename $ffid to $tfile.1 should fail."
15030         touch $test_dir/$tfile.1
15031         mv $test_dir/$tfile.1 $ffid &&
15032                 error "rename $tfile.1 to $ffid should fail."
15033         rm -f $test_dir/$tfile.1
15034         echo "truncate fid $fid"
15035         $TRUNCATE $ffid 777 || error "truncate $ffid failed."
15036         echo "link fid $fid"
15037         ln -f $ffid $test_dir/tfile.lnk || error "link $ffid failed."
15038         if [[ $($LCTL get_param -n mdc.*-mdc-*.connect_flags) =~ acl ]]; then
15039                 echo "setfacl fid $fid"
15040                 setfacl -R -m u:bin:rwx $ffid || error "setfacl $ffid failed."
15041                 echo "getfacl fid $fid"
15042                 getfacl $ffid >/dev/null || error "getfacl $ffid failed."
15043         fi
15044         echo "unlink fid $fid"
15045         unlink $MOUNT/.lustre/fid/$fid && error "unlink $ffid should fail."
15046         echo "mknod fid $fid"
15047         mknod $ffid c 1 3 && error "mknod $ffid should fail."
15048
15049         fid=[0xf00000400:0x1:0x0]
15050         ffid=$MOUNT/.lustre/fid/$fid
15051
15052         echo "stat non-exist fid $fid"
15053         stat $ffid > /dev/null && error "stat non-exist $ffid should fail."
15054         echo "write to non-exist fid $fid"
15055         cat /etc/hosts > $ffid && error "write non-exist $ffid should fail."
15056         echo "link new fid $fid"
15057         ln $test_dir/$tfile $ffid && error "link $ffid should fail."
15058
15059         mkdir -p $test_dir/$tdir
15060         touch $test_dir/$tdir/$tfile
15061         fid=$($LFS path2fid $test_dir/$tdir)
15062         rc=$?
15063         [ $rc -ne 0 ] &&
15064                 error "error: could not get fid for $test_dir/$dir/$tfile."
15065
15066         ffid=$MOUNT/.lustre/fid/$fid
15067
15068         echo "ls $fid"
15069         ls $ffid > /dev/null || error "ls $ffid failed."
15070         echo "touch $fid/$tfile.1"
15071         touch $ffid/$tfile.1 || error "touch $ffid/$tfile.1 failed."
15072
15073         echo "touch $MOUNT/.lustre/fid/$tfile"
15074         touch $MOUNT/.lustre/fid/$tfile && \
15075                 error "touch $MOUNT/.lustre/fid/$tfile should fail."
15076
15077         echo "setxattr to $MOUNT/.lustre/fid"
15078         setfattr -n trusted.name1 -v value1 $MOUNT/.lustre/fid
15079
15080         echo "listxattr for $MOUNT/.lustre/fid"
15081         getfattr -d -m "^trusted" $MOUNT/.lustre/fid
15082
15083         echo "delxattr from $MOUNT/.lustre/fid"
15084         setfattr -x trusted.name1 $MOUNT/.lustre/fid
15085
15086         echo "touch invalid fid: $MOUNT/.lustre/fid/[0x200000400:0x2:0x3]"
15087         touch $MOUNT/.lustre/fid/[0x200000400:0x2:0x3] &&
15088                 error "touch invalid fid should fail."
15089
15090         echo "touch non-normal fid: $MOUNT/.lustre/fid/[0x1:0x2:0x0]"
15091         touch $MOUNT/.lustre/fid/[0x1:0x2:0x0] &&
15092                 error "touch non-normal fid should fail."
15093
15094         echo "rename $tdir to $MOUNT/.lustre/fid"
15095         mrename $test_dir/$tdir $MOUNT/.lustre/fid &&
15096                 error "rename to $MOUNT/.lustre/fid should fail."
15097
15098         if [ $MDS1_VERSION -ge $(version_code 2.3.51) ]
15099         then            # LU-3547
15100                 local old_obf_mode=$(stat --format="%a" $DIR/.lustre/fid)
15101                 local new_obf_mode=777
15102
15103                 echo "change mode of $DIR/.lustre/fid to $new_obf_mode"
15104                 chmod $new_obf_mode $DIR/.lustre/fid ||
15105                         error "chmod $new_obf_mode $DIR/.lustre/fid failed"
15106
15107                 local obf_mode=$(stat --format=%a $DIR/.lustre/fid)
15108                 [ $obf_mode -eq $new_obf_mode ] ||
15109                         error "stat $DIR/.lustre/fid returned wrong mode $obf_mode"
15110
15111                 echo "restore mode of $DIR/.lustre/fid to $old_obf_mode"
15112                 chmod $old_obf_mode $DIR/.lustre/fid ||
15113                         error "chmod $old_obf_mode $DIR/.lustre/fid failed"
15114         fi
15115
15116         $OPENFILE -f O_LOV_DELAY_CREATE:O_CREAT $test_dir/$tfile-2
15117         fid=$($LFS path2fid $test_dir/$tfile-2)
15118
15119         if [ $MDS1_VERSION -ge $(version_code 2.6.50) ]
15120         then # LU-5424
15121                 echo "cp /etc/passwd $MOUNT/.lustre/fid/$fid"
15122                 cp /etc/passwd $MOUNT/.lustre/fid/$fid ||
15123                         error "create lov data thru .lustre failed"
15124         fi
15125         echo "cp /etc/passwd $test_dir/$tfile-2"
15126         cp /etc/passwd $test_dir/$tfile-2 ||
15127                 error "copy to $test_dir/$tfile-2 failed."
15128         echo "diff /etc/passwd $MOUNT/.lustre/fid/$fid"
15129         diff /etc/passwd $MOUNT/.lustre/fid/$fid ||
15130                 error "diff /etc/passwd $MOUNT/.lustre/fid/$fid failed."
15131
15132         rm -rf $test_dir/tfile.lnk
15133         rm -rf $test_dir/$tfile-2
15134 }
15135
15136 test_154A() {
15137         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
15138                 skip "Need MDS version at least 2.4.1"
15139
15140         local tf=$DIR/$tfile
15141         touch $tf
15142
15143         local fid=$($LFS path2fid $tf)
15144         [ -z "$fid" ] && error "path2fid unable to get $tf FID"
15145
15146         # check that we get the same pathname back
15147         local rootpath
15148         local found
15149         for rootpath in "$MOUNT" "$MOUNT///" "$MOUNT/$tfile"; do
15150                 echo "$rootpath $fid"
15151                 found=$($LFS fid2path $rootpath "$fid")
15152                 [ -z "$found" ] && error "fid2path unable to get '$fid' path"
15153                 [ "$found" == "$tf" ] || error "fid2path $found != $tf"
15154         done
15155
15156         # check wrong root path format
15157         rootpath=$MOUNT"_wrong"
15158         found=$($LFS fid2path $rootpath "$fid")
15159         [ -z "$found" ] || error "should fail ($rootpath != $MOUNT)"
15160 }
15161 run_test 154A "lfs path2fid and fid2path basic checks"
15162
15163 test_154B() {
15164         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
15165                 skip "Need MDS version at least 2.4.1"
15166
15167         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
15168         touch $DIR/$tdir/$tfile || error "touch $DIR/$tdir/$tfile failed"
15169         local linkea=$($LL_DECODE_LINKEA $DIR/$tdir/$tfile | grep 'pfid')
15170         [ -z "$linkea" ] && error "decode linkea $DIR/$tdir/$tfile failed"
15171
15172         local name=$(echo $linkea | awk '/pfid/ {print $5}' | sed -e "s/'//g")
15173         local PFID=$(echo $linkea | awk '/pfid/ {print $3}' | sed -e "s/,//g")
15174
15175         # check that we get the same pathname
15176         echo "PFID: $PFID, name: $name"
15177         local FOUND=$($LFS fid2path $MOUNT "$PFID")
15178         [ -z "$FOUND" ] && error "fid2path unable to get $PFID path"
15179         [ "$FOUND/$name" != "$DIR/$tdir/$tfile" ] &&
15180                 error "ll_decode_linkea has $FOUND/$name != $DIR/$tdir/$tfile"
15181
15182         rm -rf $DIR/$tdir || error "Can not delete directory $DIR/$tdir"
15183 }
15184 run_test 154B "verify the ll_decode_linkea tool"
15185
15186 test_154a() {
15187         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15188         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
15189         [[ $MDS1_VERSION -ge $(version_code 2.2.51) ]] ||
15190                 skip "Need MDS version at least 2.2.51"
15191         [ -z "$(which setfacl)" ] && skip_env "must have setfacl tool"
15192
15193         cp /etc/hosts $DIR/$tfile
15194
15195         fid=$($LFS path2fid $DIR/$tfile)
15196         rc=$?
15197         [ $rc -ne 0 ] && error "error: could not get fid for $DIR/$tfile."
15198
15199         dot_lustre_fid_permission_check "$fid" $DIR ||
15200                 error "dot lustre permission check $fid failed"
15201
15202         ls -a $MOUNT | grep "\.lustre" && error ".lustre should not be listed"
15203
15204         rm -rf $MOUNT/.lustre && error ".lustre is not allowed to be unlinked"
15205
15206         touch $MOUNT/.lustre/file &&
15207                 error "creation is not allowed under .lustre"
15208
15209         mkdir $MOUNT/.lustre/dir &&
15210                 error "mkdir is not allowed under .lustre"
15211
15212         rm -rf $DIR/$tfile
15213 }
15214 run_test 154a "Open-by-FID"
15215
15216 test_154b() {
15217         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15218         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
15219         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
15220         [[ $MDS1_VERSION -ge $(version_code 2.2.51) ]] ||
15221                 skip "Need MDS version at least 2.2.51"
15222
15223         local remote_dir=$DIR/$tdir/remote_dir
15224         local MDTIDX=1
15225         local rc=0
15226
15227         mkdir -p $DIR/$tdir
15228         $LFS mkdir -i $MDTIDX $remote_dir ||
15229                 error "create remote directory failed"
15230
15231         cp /etc/hosts $remote_dir/$tfile
15232
15233         fid=$($LFS path2fid $remote_dir/$tfile)
15234         rc=$?
15235         [ $rc -ne 0 ] && error "error: could not get fid for $remote_dir/$tfile"
15236
15237         dot_lustre_fid_permission_check "$fid" $remote_dir ||
15238                 error "dot lustre permission check $fid failed"
15239         rm -rf $DIR/$tdir
15240 }
15241 run_test 154b "Open-by-FID for remote directory"
15242
15243 test_154c() {
15244         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
15245                 skip "Need MDS version at least 2.4.1"
15246
15247         touch $DIR/$tfile.1 $DIR/$tfile.2 $DIR/$tfile.3
15248         local FID1=$($LFS path2fid $DIR/$tfile.1)
15249         local FID2=$($LFS path2fid $DIR/$tfile.2)
15250         local FID3=$($LFS path2fid $DIR/$tfile.3)
15251
15252         local N=1
15253         $LFS path2fid $DIR/$tfile.[123] | while read PATHNAME FID; do
15254                 [ "$PATHNAME" = "$DIR/$tfile.$N:" ] ||
15255                         error "path2fid pathname $PATHNAME != $DIR/$tfile.$N:"
15256                 local want=FID$N
15257                 [ "$FID" = "${!want}" ] ||
15258                         error "path2fid $PATHNAME FID $FID != FID$N ${!want}"
15259                 N=$((N + 1))
15260         done
15261
15262         $LFS fid2path $MOUNT "$FID1" "$FID2" "$FID3" | while read PATHNAME;
15263         do
15264                 [ "$PATHNAME" = "$DIR/$tfile.$N" ] ||
15265                         error "fid2path pathname $PATHNAME != $DIR/$tfile.$N:"
15266                 N=$((N + 1))
15267         done
15268 }
15269 run_test 154c "lfs path2fid and fid2path multiple arguments"
15270
15271 test_154d() {
15272         remote_mds_nodsh && skip "remote MDS with nodsh"
15273         [[ $MDS1_VERSION -lt $(version_code 2.5.53) ]] &&
15274                 skip "Need MDS version at least 2.5.53"
15275
15276         if remote_mds; then
15277                 nid=$($LCTL list_nids | sed  "s/\./\\\./g")
15278         else
15279                 nid="0@lo"
15280         fi
15281         local proc_ofile="mdt.*.exports.'$nid'.open_files"
15282         local fd
15283         local cmd
15284
15285         rm -f $DIR/$tfile
15286         touch $DIR/$tfile
15287
15288         local fid=$($LFS path2fid $DIR/$tfile)
15289         # Open the file
15290         fd=$(free_fd)
15291         cmd="exec $fd<$DIR/$tfile"
15292         eval $cmd
15293         local fid_list=$(do_facet $SINGLEMDS $LCTL get_param $proc_ofile)
15294         echo "$fid_list" | grep "$fid"
15295         rc=$?
15296
15297         cmd="exec $fd>/dev/null"
15298         eval $cmd
15299         if [ $rc -ne 0 ]; then
15300                 error "FID $fid not found in open files list $fid_list"
15301         fi
15302 }
15303 run_test 154d "Verify open file fid"
15304
15305 test_154e()
15306 {
15307         [[ $MDS1_VERSION -lt $(version_code 2.6.50) ]] &&
15308                 skip "Need MDS version at least 2.6.50"
15309
15310         if ls -a $MOUNT | grep -q '^\.lustre$'; then
15311                 error ".lustre returned by readdir"
15312         fi
15313 }
15314 run_test 154e ".lustre is not returned by readdir"
15315
15316 test_154f() {
15317         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
15318
15319         # create parent directory on a single MDT to avoid cross-MDT hardlinks
15320         mkdir_on_mdt0 $DIR/$tdir
15321         # test dirs inherit from its stripe
15322         mkdir -p $DIR/$tdir/foo1 || error "mkdir error"
15323         mkdir -p $DIR/$tdir/foo2 || error "mkdir error"
15324         cp /etc/hosts $DIR/$tdir/foo1/$tfile
15325         ln $DIR/$tdir/foo1/$tfile $DIR/$tdir/foo2/link
15326         touch $DIR/f
15327
15328         # get fid of parents
15329         local FID0=$($LFS path2fid $DIR/$tdir)
15330         local FID1=$($LFS path2fid $DIR/$tdir/foo1)
15331         local FID2=$($LFS path2fid $DIR/$tdir/foo2)
15332         local FID3=$($LFS path2fid $DIR)
15333
15334         # check that path2fid --parents returns expected <parent_fid>/name
15335         # 1) test for a directory (single parent)
15336         local parent=$($LFS path2fid --parents $DIR/$tdir/foo1)
15337         [ "$parent" == "$FID0/foo1" ] ||
15338                 error "expected parent: $FID0/foo1, got: $parent"
15339
15340         # 2) test for a file with nlink > 1 (multiple parents)
15341         parent=$($LFS path2fid --parents $DIR/$tdir/foo1/$tfile)
15342         echo "$parent" | grep -F "$FID1/$tfile" ||
15343                 error "$FID1/$tfile not returned in parent list"
15344         echo "$parent" | grep -F "$FID2/link" ||
15345                 error "$FID2/link not returned in parent list"
15346
15347         # 3) get parent by fid
15348         local file_fid=$($LFS path2fid $DIR/$tdir/foo1/$tfile)
15349         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
15350         echo "$parent" | grep -F "$FID1/$tfile" ||
15351                 error "$FID1/$tfile not returned in parent list (by fid)"
15352         echo "$parent" | grep -F "$FID2/link" ||
15353                 error "$FID2/link not returned in parent list (by fid)"
15354
15355         # 4) test for entry in root directory
15356         parent=$($LFS path2fid --parents $DIR/f)
15357         echo "$parent" | grep -F "$FID3/f" ||
15358                 error "$FID3/f not returned in parent list"
15359
15360         # 5) test it on root directory
15361         [ -z "$($LFS path2fid --parents $MOUNT 2>/dev/null)" ] ||
15362                 error "$MOUNT should not have parents"
15363
15364         # enable xattr caching and check that linkea is correctly updated
15365         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
15366         save_lustre_params client "llite.*.xattr_cache" > $save
15367         lctl set_param llite.*.xattr_cache 1
15368
15369         # 6.1) linkea update on rename
15370         mv $DIR/$tdir/foo1/$tfile $DIR/$tdir/foo2/$tfile.moved
15371
15372         # get parents by fid
15373         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
15374         # foo1 should no longer be returned in parent list
15375         echo "$parent" | grep -F "$FID1" &&
15376                 error "$FID1 should no longer be in parent list"
15377         # the new path should appear
15378         echo "$parent" | grep -F "$FID2/$tfile.moved" ||
15379                 error "$FID2/$tfile.moved is not in parent list"
15380
15381         # 6.2) linkea update on unlink
15382         rm -f $DIR/$tdir/foo2/link
15383         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
15384         # foo2/link should no longer be returned in parent list
15385         echo "$parent" | grep -F "$FID2/link" &&
15386                 error "$FID2/link should no longer be in parent list"
15387         true
15388
15389         rm -f $DIR/f
15390         restore_lustre_params < $save
15391         rm -f $save
15392 }
15393 run_test 154f "get parent fids by reading link ea"
15394
15395 test_154g()
15396 {
15397         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
15398         [[ $MDS1_VERSION -ge $(version_code 2.6.92) &&
15399            $CLIENT_VERSION -gt $(version_code 2.6.99) ]] ||
15400                 skip "Need MDS version at least 2.6.92"
15401
15402         mkdir_on_mdt0 $DIR/$tdir
15403         llapi_fid_test -d $DIR/$tdir
15404 }
15405 run_test 154g "various llapi FID tests"
15406
15407 test_155_small_load() {
15408     local temp=$TMP/$tfile
15409     local file=$DIR/$tfile
15410
15411     dd if=/dev/urandom of=$temp bs=6096 count=1 || \
15412         error "dd of=$temp bs=6096 count=1 failed"
15413     cp $temp $file
15414     cancel_lru_locks $OSC
15415     cmp $temp $file || error "$temp $file differ"
15416
15417     $TRUNCATE $temp 6000
15418     $TRUNCATE $file 6000
15419     cmp $temp $file || error "$temp $file differ (truncate1)"
15420
15421     echo "12345" >>$temp
15422     echo "12345" >>$file
15423     cmp $temp $file || error "$temp $file differ (append1)"
15424
15425     echo "12345" >>$temp
15426     echo "12345" >>$file
15427     cmp $temp $file || error "$temp $file differ (append2)"
15428
15429     rm -f $temp $file
15430     true
15431 }
15432
15433 test_155_big_load() {
15434         remote_ost_nodsh && skip "remote OST with nodsh"
15435
15436         local temp=$TMP/$tfile
15437         local file=$DIR/$tfile
15438
15439         free_min_max
15440         local cache_size=$(do_facet ost$((MAXI+1)) \
15441                 "awk '/cache/ {sum+=\\\$4} END {print sum}' /proc/cpuinfo")
15442         local large_file_size=$((cache_size * 2))
15443
15444         echo "OSS cache size: $cache_size KB"
15445         echo "Large file size: $large_file_size KB"
15446
15447         [ $MAXV -le $large_file_size ] &&
15448                 skip_env "max available OST size needs > $large_file_size KB"
15449
15450         $LFS setstripe $file -c 1 -i $MAXI || error "$LFS setstripe $file failed"
15451
15452         dd if=/dev/urandom of=$temp bs=$large_file_size count=1k ||
15453                 error "dd of=$temp bs=$large_file_size count=1k failed"
15454         cp $temp $file
15455         ls -lh $temp $file
15456         cancel_lru_locks osc
15457         cmp $temp $file || error "$temp $file differ"
15458
15459         rm -f $temp $file
15460         true
15461 }
15462
15463 save_writethrough() {
15464         local facets=$(get_facets OST)
15465
15466         save_lustre_params $facets "osd-*.*.writethrough_cache_enable" > $1
15467 }
15468
15469 test_155a() {
15470         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15471
15472         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15473
15474         save_writethrough $p
15475
15476         set_cache read on
15477         set_cache writethrough on
15478         test_155_small_load
15479         restore_lustre_params < $p
15480         rm -f $p
15481 }
15482 run_test 155a "Verify small file correctness: read cache:on write_cache:on"
15483
15484 test_155b() {
15485         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15486
15487         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15488
15489         save_writethrough $p
15490
15491         set_cache read on
15492         set_cache writethrough off
15493         test_155_small_load
15494         restore_lustre_params < $p
15495         rm -f $p
15496 }
15497 run_test 155b "Verify small file correctness: read cache:on write_cache:off"
15498
15499 test_155c() {
15500         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15501
15502         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15503
15504         save_writethrough $p
15505
15506         set_cache read off
15507         set_cache writethrough on
15508         test_155_small_load
15509         restore_lustre_params < $p
15510         rm -f $p
15511 }
15512 run_test 155c "Verify small file correctness: read cache:off write_cache:on"
15513
15514 test_155d() {
15515         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15516
15517         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15518
15519         save_writethrough $p
15520
15521         set_cache read off
15522         set_cache writethrough off
15523         test_155_small_load
15524         restore_lustre_params < $p
15525         rm -f $p
15526 }
15527 run_test 155d "Verify small file correctness: read cache:off write_cache:off"
15528
15529 test_155e() {
15530         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15531
15532         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15533
15534         save_writethrough $p
15535
15536         set_cache read on
15537         set_cache writethrough on
15538         test_155_big_load
15539         restore_lustre_params < $p
15540         rm -f $p
15541 }
15542 run_test 155e "Verify big file correctness: read cache:on write_cache:on"
15543
15544 test_155f() {
15545         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15546
15547         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15548
15549         save_writethrough $p
15550
15551         set_cache read on
15552         set_cache writethrough off
15553         test_155_big_load
15554         restore_lustre_params < $p
15555         rm -f $p
15556 }
15557 run_test 155f "Verify big file correctness: read cache:on write_cache:off"
15558
15559 test_155g() {
15560         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15561
15562         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15563
15564         save_writethrough $p
15565
15566         set_cache read off
15567         set_cache writethrough on
15568         test_155_big_load
15569         restore_lustre_params < $p
15570         rm -f $p
15571 }
15572 run_test 155g "Verify big file correctness: read cache:off write_cache:on"
15573
15574 test_155h() {
15575         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15576
15577         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15578
15579         save_writethrough $p
15580
15581         set_cache read off
15582         set_cache writethrough off
15583         test_155_big_load
15584         restore_lustre_params < $p
15585         rm -f $p
15586 }
15587 run_test 155h "Verify big file correctness: read cache:off write_cache:off"
15588
15589 test_156() {
15590         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15591         remote_ost_nodsh && skip "remote OST with nodsh"
15592         [ $OST1_VERSION -lt $(version_code 2.6.93) ] &&
15593                 skip "stats not implemented on old servers"
15594         [ "$ost1_FSTYPE" = "zfs" ] &&
15595                 skip "LU-1956/LU-2261: stats not implemented on OSD ZFS"
15596
15597         local CPAGES=3
15598         local BEFORE
15599         local AFTER
15600         local file="$DIR/$tfile"
15601         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15602
15603         save_writethrough $p
15604         roc_hit_init
15605
15606         log "Turn on read and write cache"
15607         set_cache read on
15608         set_cache writethrough on
15609
15610         log "Write data and read it back."
15611         log "Read should be satisfied from the cache."
15612         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
15613         BEFORE=$(roc_hit)
15614         cancel_lru_locks osc
15615         cat $file >/dev/null
15616         AFTER=$(roc_hit)
15617         if ! let "AFTER - BEFORE == CPAGES"; then
15618                 error "NOT IN CACHE (2): before: $BEFORE, after: $AFTER"
15619         else
15620                 log "cache hits: before: $BEFORE, after: $AFTER"
15621         fi
15622
15623         log "Read again; it should be satisfied from the cache."
15624         BEFORE=$AFTER
15625         cancel_lru_locks osc
15626         cat $file >/dev/null
15627         AFTER=$(roc_hit)
15628         if ! let "AFTER - BEFORE == CPAGES"; then
15629                 error "NOT IN CACHE (3): before: $BEFORE, after: $AFTER"
15630         else
15631                 log "cache hits:: before: $BEFORE, after: $AFTER"
15632         fi
15633
15634         log "Turn off the read cache and turn on the write cache"
15635         set_cache read off
15636         set_cache writethrough on
15637
15638         log "Read again; it should be satisfied from the cache."
15639         BEFORE=$(roc_hit)
15640         cancel_lru_locks osc
15641         cat $file >/dev/null
15642         AFTER=$(roc_hit)
15643         if ! let "AFTER - BEFORE == CPAGES"; then
15644                 error "NOT IN CACHE (4): before: $BEFORE, after: $AFTER"
15645         else
15646                 log "cache hits:: before: $BEFORE, after: $AFTER"
15647         fi
15648
15649         if [ $OST1_VERSION -lt $(version_code 2.12.55) ]; then
15650                 # > 2.12.56 uses pagecache if cached
15651                 log "Read again; it should not be satisfied from the cache."
15652                 BEFORE=$AFTER
15653                 cancel_lru_locks osc
15654                 cat $file >/dev/null
15655                 AFTER=$(roc_hit)
15656                 if ! let "AFTER - BEFORE == 0"; then
15657                         error "IN CACHE (5): before: $BEFORE, after: $AFTER"
15658                 else
15659                         log "cache hits:: before: $BEFORE, after: $AFTER"
15660                 fi
15661         fi
15662
15663         log "Write data and read it back."
15664         log "Read should be satisfied from the cache."
15665         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
15666         BEFORE=$(roc_hit)
15667         cancel_lru_locks osc
15668         cat $file >/dev/null
15669         AFTER=$(roc_hit)
15670         if ! let "AFTER - BEFORE == CPAGES"; then
15671                 error "NOT IN CACHE (6): before: $BEFORE, after: $AFTER"
15672         else
15673                 log "cache hits:: before: $BEFORE, after: $AFTER"
15674         fi
15675
15676         if [ $OST1_VERSION -lt $(version_code 2.12.55) ]; then
15677                 # > 2.12.56 uses pagecache if cached
15678                 log "Read again; it should not be satisfied from the cache."
15679                 BEFORE=$AFTER
15680                 cancel_lru_locks osc
15681                 cat $file >/dev/null
15682                 AFTER=$(roc_hit)
15683                 if ! let "AFTER - BEFORE == 0"; then
15684                         error "IN CACHE (7): before: $BEFORE, after: $AFTER"
15685                 else
15686                         log "cache hits:: before: $BEFORE, after: $AFTER"
15687                 fi
15688         fi
15689
15690         log "Turn off read and write cache"
15691         set_cache read off
15692         set_cache writethrough off
15693
15694         log "Write data and read it back"
15695         log "It should not be satisfied from the cache."
15696         rm -f $file
15697         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
15698         cancel_lru_locks osc
15699         BEFORE=$(roc_hit)
15700         cat $file >/dev/null
15701         AFTER=$(roc_hit)
15702         if ! let "AFTER - BEFORE == 0"; then
15703                 error_ignore bz20762 "IN CACHE (8):before:$BEFORE,after:$AFTER"
15704         else
15705                 log "cache hits:: before: $BEFORE, after: $AFTER"
15706         fi
15707
15708         log "Turn on the read cache and turn off the write cache"
15709         set_cache read on
15710         set_cache writethrough off
15711
15712         log "Write data and read it back"
15713         log "It should not be satisfied from the cache."
15714         rm -f $file
15715         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
15716         BEFORE=$(roc_hit)
15717         cancel_lru_locks osc
15718         cat $file >/dev/null
15719         AFTER=$(roc_hit)
15720         if ! let "AFTER - BEFORE == 0"; then
15721                 error_ignore bz20762 "IN CACHE (9):before:$BEFORE,after:$AFTER"
15722         else
15723                 log "cache hits:: before: $BEFORE, after: $AFTER"
15724         fi
15725
15726         log "Read again; it should be satisfied from the cache."
15727         BEFORE=$(roc_hit)
15728         cancel_lru_locks osc
15729         cat $file >/dev/null
15730         AFTER=$(roc_hit)
15731         if ! let "AFTER - BEFORE == CPAGES"; then
15732                 error "NOT IN CACHE (1): before: $BEFORE, after: $AFTER"
15733         else
15734                 log "cache hits:: before: $BEFORE, after: $AFTER"
15735         fi
15736
15737         restore_lustre_params < $p
15738         rm -f $p $file
15739 }
15740 run_test 156 "Verification of tunables"
15741
15742 test_160a() {
15743         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15744         remote_mds_nodsh && skip "remote MDS with nodsh"
15745         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] ||
15746                 skip "Need MDS version at least 2.2.0"
15747
15748         changelog_register || error "changelog_register failed"
15749         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
15750         changelog_users $SINGLEMDS | grep -q $cl_user ||
15751                 error "User $cl_user not found in changelog_users"
15752
15753         mkdir_on_mdt0 $DIR/$tdir
15754
15755         # change something
15756         test_mkdir -p $DIR/$tdir/pics/2008/zachy
15757         changelog_clear 0 || error "changelog_clear failed"
15758         touch $DIR/$tdir/pics/2008/zachy/$tfile                 # open 1
15759         cp /etc/hosts $DIR/$tdir/pics/2008/zachy/pic1.jpg       # open 2
15760         mv $DIR/$tdir/pics/2008/zachy $DIR/$tdir/pics/zach
15761         ln $DIR/$tdir/pics/zach/pic1.jpg $DIR/$tdir/pics/2008/portland.jpg
15762         ln -s $DIR/$tdir/pics/2008/portland.jpg $DIR/$tdir/pics/desktop.jpg
15763         rm $DIR/$tdir/pics/desktop.jpg
15764
15765         echo "verifying changelog mask"
15766         changelog_chmask "-MKDIR"
15767         changelog_chmask "-CLOSE"
15768
15769         test_mkdir -p $DIR/$tdir/pics/zach/sofia                # not logged
15770         echo "zzzzzz" > $DIR/$tdir/pics/zach/file               # not logged
15771
15772         changelog_chmask "+MKDIR"
15773         changelog_chmask "+CLOSE"
15774
15775         test_mkdir -p $DIR/$tdir/pics/2008/sofia                # mkdir 1
15776         echo "zzzzzz" > $DIR/$tdir/pics/zach/file               # open 3
15777
15778         MKDIRS=$(changelog_dump | grep -c "MKDIR")
15779         CLOSES=$(changelog_dump | grep -c "CLOSE")
15780         [ $MKDIRS -eq 1 ] || error "MKDIR changelog mask count $MKDIRS != 1"
15781         [ $CLOSES -eq 3 ] || error "CLOSE changelog mask count $CLOSES != 3"
15782
15783         # verify contents
15784         echo "verifying target fid"
15785         local fidc=$(changelog_extract_field "CREAT" "$tfile" "t=")
15786         local fidf=$($LFS path2fid $DIR/$tdir/pics/zach/$tfile)
15787         [ "$fidc" == "$fidf" ] ||
15788                 error "changelog '$tfile' fid $fidc != file fid $fidf"
15789         echo "verifying parent fid"
15790         # The FID returned from the Changelog may be the directory shard on
15791         # a different MDT, and not the FID returned by path2fid on the parent.
15792         # Instead of comparing FIDs, verify that fid2path(fidp) is correct,
15793         # since this is what will matter when recreating this file in the tree.
15794         local fidp=$(changelog_extract_field "CREAT" "$tfile" "p=")
15795         local pathp=$($LFS fid2path $MOUNT "$fidp")
15796         [ "${pathp%/}" == "$DIR/$tdir/pics/zach" ] ||
15797                 error "changelog fid2path($fidc) $pathp != $DIR/$tdir/pics/zach"
15798
15799         echo "getting records for $cl_user"
15800         changelog_users $SINGLEMDS
15801         local user_rec1=$(changelog_user_rec $SINGLEMDS $cl_user)
15802         local nclr=3
15803         __changelog_clear $SINGLEMDS $cl_user +$nclr ||
15804                 error "changelog_clear failed"
15805         local user_rec2=$(changelog_user_rec $SINGLEMDS $cl_user)
15806         echo "verifying user clear: $user_rec1 + $nclr == $user_rec2"
15807         [ $user_rec2 == $((user_rec1 + nclr)) ] ||
15808                 error "user index expect $user_rec1 + $nclr != $user_rec2"
15809
15810         local min0_rec=$(changelog_users $SINGLEMDS |
15811                 awk 'min == "" || $2 < min { min = $2 }; END { print min }')
15812         local first_rec=$($LFS changelog $(facet_svc $SINGLEMDS) |
15813                           awk '{ print $1; exit; }')
15814
15815         changelog_dump | tail -n 5
15816         echo "verifying user min purge: $min0_rec + 1 == $first_rec"
15817         [ $first_rec == $((min0_rec + 1)) ] ||
15818                 error "first index should be $min0_rec + 1 not $first_rec"
15819
15820         # LU-3446 changelog index reset on MDT restart
15821         local cur_rec1=$(changelog_users $SINGLEMDS |
15822                          awk '/^current.index:/ { print $NF }')
15823         changelog_clear 0 ||
15824                 error "clear all changelog records for $cl_user failed"
15825         stop $SINGLEMDS || error "Fail to stop $SINGLEMDS"
15826         start $SINGLEMDS $(mdsdevname ${SINGLEMDS//mds/}) $MDS_MOUNT_OPTS ||
15827                 error "Fail to start $SINGLEMDS"
15828         local cur_rec2=$(changelog_users $SINGLEMDS |
15829                          awk '/^current.index:/ { print $NF }')
15830         echo "verifying index survives MDT restart: $cur_rec1 == $cur_rec2"
15831         [ $cur_rec1 == $cur_rec2 ] ||
15832                 error "current index should be $cur_rec1 not $cur_rec2"
15833
15834         echo "verifying users from this test are deregistered"
15835         changelog_deregister || error "changelog_deregister failed"
15836         changelog_users $SINGLEMDS | grep -q $cl_user &&
15837                 error "User '$cl_user' still in changelog_users"
15838
15839         # lctl get_param -n mdd.*.changelog_users
15840         # current_index: 144
15841         # ID    index (idle seconds)
15842         # cl3   144   (2) mask=<list>
15843         if [ -z "$(changelog_users $SINGLEMDS | grep -v current.index)" ]; then
15844                 # this is the normal case where all users were deregistered
15845                 # make sure no new records are added when no users are present
15846                 local last_rec1=$(changelog_users $SINGLEMDS |
15847                                   awk '/^current.index:/ { print $NF }')
15848                 touch $DIR/$tdir/chloe
15849                 local last_rec2=$(changelog_users $SINGLEMDS |
15850                                   awk '/^current.index:/ { print $NF }')
15851                 echo "verify changelogs are off: $last_rec1 == $last_rec2"
15852                 [ $last_rec1 == $last_rec2 ] || error "changelogs not off"
15853         else
15854                 # any changelog users must be leftovers from a previous test
15855                 changelog_users $SINGLEMDS
15856                 echo "other changelog users; can't verify off"
15857         fi
15858 }
15859 run_test 160a "changelog sanity"
15860
15861 test_160b() { # LU-3587
15862         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15863         remote_mds_nodsh && skip "remote MDS with nodsh"
15864         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] ||
15865                 skip "Need MDS version at least 2.2.0"
15866
15867         changelog_register || error "changelog_register failed"
15868         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
15869         changelog_users $SINGLEMDS | grep -q $cl_user ||
15870                 error "User '$cl_user' not found in changelog_users"
15871
15872         local longname1=$(str_repeat a 255)
15873         local longname2=$(str_repeat b 255)
15874
15875         cd $DIR
15876         echo "creating very long named file"
15877         touch $longname1 || error "create of '$longname1' failed"
15878         echo "renaming very long named file"
15879         mv $longname1 $longname2
15880
15881         changelog_dump | grep RENME | tail -n 5
15882         rm -f $longname2
15883 }
15884 run_test 160b "Verify that very long rename doesn't crash in changelog"
15885
15886 test_160c() {
15887         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15888         remote_mds_nodsh && skip "remote MDS with nodsh"
15889
15890         [[ $MDS1_VERSION -gt $(version_code 2.5.57) ]] ||
15891                 [[ $MDS1_VERSION -gt $(version_code 2.5.1) &&
15892                    $MDS1_VERSION -lt $(version_code 2.5.50) ]] ||
15893                 skip "Need MDS version at least 2.5.58 or 2.5.2+"
15894
15895         local rc=0
15896
15897         # Registration step
15898         changelog_register || error "changelog_register failed"
15899
15900         rm -rf $DIR/$tdir
15901         mkdir -p $DIR/$tdir
15902         $MCREATE $DIR/$tdir/foo_160c
15903         changelog_chmask "-TRUNC"
15904         $TRUNCATE $DIR/$tdir/foo_160c 200
15905         changelog_chmask "+TRUNC"
15906         $TRUNCATE $DIR/$tdir/foo_160c 199
15907         changelog_dump | tail -n 5
15908         local truncs=$(changelog_dump | tail -n 5 | grep -c TRUNC)
15909         [ $truncs -eq 1 ] || error "TRUNC changelog mask count $truncs != 1"
15910 }
15911 run_test 160c "verify that changelog log catch the truncate event"
15912
15913 test_160d() {
15914         remote_mds_nodsh && skip "remote MDS with nodsh"
15915         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
15916         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15917         [[ $MDS1_VERSION -ge $(version_code 2.7.60) ]] ||
15918                 skip "Need MDS version at least 2.7.60"
15919
15920         # Registration step
15921         changelog_register || error "changelog_register failed"
15922
15923         mkdir -p $DIR/$tdir/migrate_dir
15924         changelog_clear 0 || error "changelog_clear failed"
15925
15926         $LFS migrate -m 1 $DIR/$tdir/migrate_dir || error "migrate fails"
15927         changelog_dump | tail -n 5
15928         local migrates=$(changelog_dump | grep -c "MIGRT")
15929         [ $migrates -eq 1 ] || error "MIGRATE changelog count $migrates != 1"
15930 }
15931 run_test 160d "verify that changelog log catch the migrate event"
15932
15933 test_160e() {
15934         remote_mds_nodsh && skip "remote MDS with nodsh"
15935
15936         # Create a user
15937         changelog_register || error "changelog_register failed"
15938
15939         local MDT0=$(facet_svc $SINGLEMDS)
15940         local rc
15941
15942         # No user (expect fail)
15943         do_facet $SINGLEMDS $LCTL --device $MDT0 changelog_deregister
15944         rc=$?
15945         if [ $rc -eq 0 ]; then
15946                 error "Should fail without user"
15947         elif [ $rc -ne 4 ]; then
15948                 error "changelog_deregister failed with $rc, expect 4(CMD_HELP)"
15949         fi
15950
15951         # Delete a future user (expect fail)
15952         do_facet $SINGLEMDS $LCTL --device $MDT0 changelog_deregister "cl77"
15953         rc=$?
15954         if [ $rc -eq 0 ]; then
15955                 error "Deleted non-existant user cl77"
15956         elif [ $rc -ne 2 ]; then
15957                 error "changelog_deregister failed with $rc, expect 2 (ENOENT)"
15958         fi
15959
15960         # Clear to a bad index (1 billion should be safe)
15961         $LFS changelog_clear $MDT0 "${CL_USERS[$SINGLEMDS]%% *}" 1000000000
15962         rc=$?
15963
15964         if [ $rc -eq 0 ]; then
15965                 error "Successfully cleared to invalid CL index"
15966         elif [ $rc -ne 22 ]; then
15967                 error "changelog_clear failed with $rc, expected 22 (EINVAL)"
15968         fi
15969 }
15970 run_test 160e "changelog negative testing (should return errors)"
15971
15972 test_160f() {
15973         remote_mds_nodsh && skip "remote MDS with nodsh" && return
15974         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
15975                 skip "Need MDS version at least 2.10.56"
15976
15977         local mdts=$(comma_list $(mdts_nodes))
15978
15979         # Create a user
15980         changelog_register || error "first changelog_register failed"
15981         changelog_register || error "second changelog_register failed"
15982         local cl_users
15983         declare -A cl_user1
15984         declare -A cl_user2
15985         local user_rec1
15986         local user_rec2
15987         local i
15988
15989         # generate some changelog records to accumulate on each MDT
15990         # use all_char because created files should be evenly distributed
15991         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
15992                 error "test_mkdir $tdir failed"
15993         log "$(date +%s): creating first files"
15994         for ((i = 0; i < MDSCOUNT * 2; i++)); do
15995                 $LFS mkdir -i $((i%MDSCOUNT)) $DIR/$tdir/d$i.$((i/MDSCOUNT)) ||
15996                         error "create $DIR/$tdir/d$i.$((i/MDSCOUNT)) failed"
15997         done
15998
15999         # check changelogs have been generated
16000         local start=$SECONDS
16001         local idle_time=$((MDSCOUNT * 5 + 5))
16002         local nbcl=$(changelog_dump | wc -l)
16003         [[ $nbcl -eq 0 ]] && error "no changelogs found"
16004
16005         for param in "changelog_max_idle_time=$idle_time" \
16006                      "changelog_gc=1" \
16007                      "changelog_min_gc_interval=2" \
16008                      "changelog_min_free_cat_entries=3"; do
16009                 local MDT0=$(facet_svc $SINGLEMDS)
16010                 local var="${param%=*}"
16011                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
16012
16013                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
16014                 do_nodes $mdts $LCTL set_param mdd.*.$param
16015         done
16016
16017         # force cl_user2 to be idle (1st part), but also cancel the
16018         # cl_user1 records so that it is not evicted later in the test.
16019         local sleep1=$((idle_time / 2))
16020         echo "$(date +%s): sleep1 $sleep1/${idle_time}s"
16021         sleep $sleep1
16022
16023         # simulate changelog catalog almost full
16024         #define OBD_FAIL_CAT_FREE_RECORDS       0x1313
16025         do_nodes $mdts "$LCTL set_param fail_loc=0x1313 fail_val=3"
16026
16027         for i in $(seq $MDSCOUNT); do
16028                 cl_users=(${CL_USERS[mds$i]})
16029                 cl_user1[mds$i]="${cl_users[0]}"
16030                 cl_user2[mds$i]="${cl_users[1]}"
16031
16032                 [ -n "${cl_user1[mds$i]}" ] ||
16033                         error "mds$i: no user registered"
16034                 [ -n "${cl_user2[mds$i]}" ] ||
16035                         error "mds$i: only ${cl_user2[mds$i]} is registered"
16036
16037                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16038                 [ -n "$user_rec1" ] ||
16039                         error "mds$i: User ${cl_user1[mds$i]} not registered"
16040                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
16041                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16042                 [ -n "$user_rec2" ] ||
16043                         error "mds$i: User ${cl_user1[mds$i]} not registered"
16044                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
16045                      "$user_rec1 + 2 == $user_rec2"
16046                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
16047                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
16048                               "$user_rec1 + 2, but is $user_rec2"
16049                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
16050                 [ -n "$user_rec2" ] ||
16051                         error "mds$i: User ${cl_user2[mds$i]} not registered"
16052                 [ $user_rec1 == $user_rec2 ] ||
16053                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
16054                               "$user_rec1, but is $user_rec2"
16055         done
16056
16057         # force cl_user2 idle (2nd part) to just exceed changelog_max_idle_time
16058         local sleep2=$((idle_time - (SECONDS - start) + 1))
16059         echo "$(date +%s): sleep2 $sleep2/${idle_time}s"
16060         sleep $sleep2
16061
16062         # Generate one more changelog to trigger GC at fail_loc for cl_user2.
16063         # cl_user1 should be OK because it recently processed records.
16064         echo "$(date +%s): creating $((MDSCOUNT * 2)) files"
16065         for ((i = 0; i < MDSCOUNT * 2; i++)); do
16066                 $LFS mkdir -i $((i%MDSCOUNT)) $DIR/$tdir/d$i.$((i/MDSCOUNT+2))||
16067                         error "create $DIR/$tdir/d$i.$((i/MDSCOUNT+2)) failed"
16068         done
16069
16070         # ensure gc thread is done
16071         for i in $(mdts_nodes); do
16072                 wait_update $i "ps -e -o comm= | grep chlg_gc_thread" "" 20 ||
16073                         error "$i: GC-thread not done"
16074         done
16075
16076         local first_rec
16077         for (( i = 1; i <= MDSCOUNT; i++ )); do
16078                 # check cl_user1 still registered
16079                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
16080                         error "mds$i: User ${cl_user1[mds$i]} not registered"
16081                 # check cl_user2 unregistered
16082                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
16083                         error "mds$i: User ${cl_user2[mds$i]} still registered"
16084
16085                 # check changelogs are present and starting at $user_rec1 + 1
16086                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16087                 [ -n "$user_rec1" ] ||
16088                         error "mds$i: User ${cl_user1[mds$i]} not registered"
16089                 first_rec=$($LFS changelog $(facet_svc mds$i) |
16090                             awk '{ print $1; exit; }')
16091
16092                 echo "mds$i: $(date +%s) verify rec $user_rec1+1 == $first_rec"
16093                 [ $((user_rec1 + 1)) == $first_rec ] ||
16094                         error "mds$i: rec $first_rec != $user_rec1 + 1"
16095         done
16096 }
16097 run_test 160f "changelog garbage collect (timestamped users)"
16098
16099 test_160g() {
16100         remote_mds_nodsh && skip "remote MDS with nodsh"
16101         [[ $MDS1_VERSION -ge $(version_code 2.14.55) ]] ||
16102                 skip "Need MDS version at least 2.14.55"
16103
16104         local mdts=$(comma_list $(mdts_nodes))
16105
16106         # Create a user
16107         changelog_register || error "first changelog_register failed"
16108         changelog_register || error "second changelog_register failed"
16109         local cl_users
16110         declare -A cl_user1
16111         declare -A cl_user2
16112         local user_rec1
16113         local user_rec2
16114         local i
16115
16116         # generate some changelog records to accumulate on each MDT
16117         # use all_char because created files should be evenly distributed
16118         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
16119                 error "test_mkdir $tdir failed"
16120         for ((i = 0; i < MDSCOUNT; i++)); do
16121                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
16122                         error "create $DIR/$tdir/d$i.1 failed"
16123         done
16124
16125         # check changelogs have been generated
16126         local nbcl=$(changelog_dump | wc -l)
16127         (( $nbcl > 0 )) || error "no changelogs found"
16128
16129         # reduce the max_idle_indexes value to make sure we exceed it
16130         for param in "changelog_max_idle_indexes=2" \
16131                      "changelog_gc=1" \
16132                      "changelog_min_gc_interval=2"; do
16133                 local MDT0=$(facet_svc $SINGLEMDS)
16134                 local var="${param%=*}"
16135                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
16136
16137                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
16138                 do_nodes $mdts $LCTL set_param mdd.*.$param ||
16139                         error "unable to set mdd.*.$param"
16140         done
16141
16142         local start=$SECONDS
16143         for i in $(seq $MDSCOUNT); do
16144                 cl_users=(${CL_USERS[mds$i]})
16145                 cl_user1[mds$i]="${cl_users[0]}"
16146                 cl_user2[mds$i]="${cl_users[1]}"
16147
16148                 [ -n "${cl_user1[mds$i]}" ] ||
16149                         error "mds$i: user1 is not registered"
16150                 [ -n "${cl_user2[mds$i]}" ] ||
16151                         error "mds$i: only ${cl_user1[mds$i]} is registered"
16152
16153                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16154                 [ -n "$user_rec1" ] ||
16155                         error "mds$i: user1 ${cl_user1[mds$i]} not found"
16156                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
16157                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16158                 [ -n "$user_rec2" ] ||
16159                         error "mds$i: user1 ${cl_user1[mds$i]} not found (2)"
16160                 echo "mds$i: verifying user1 ${cl_user1[mds$i]} clear: " \
16161                      "$user_rec1 + 2 == $user_rec2"
16162                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
16163                         error "mds$i: user1 ${cl_user1[mds$i]} index " \
16164                               "expected $user_rec1 + 2, but is $user_rec2"
16165                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
16166                 [ -n "$user_rec2" ] ||
16167                         error "mds$i: user2 ${cl_user2[mds$i]} not found"
16168                 [ $user_rec1 == $user_rec2 ] ||
16169                         error "mds$i: user2 ${cl_user2[mds$i]} index " \
16170                               "expected $user_rec1, but is $user_rec2"
16171         done
16172
16173         # ensure we are past the previous changelog_min_gc_interval set above
16174         local sleep2=$((start + 2 - SECONDS))
16175         (( sleep2 > 0 )) && echo "sleep $sleep2 for interval" && sleep $sleep2
16176         # Generate one more changelog to trigger GC at fail_loc for cl_user2.
16177         # cl_user1 should be OK because it recently processed records.
16178         for ((i = 0; i < MDSCOUNT; i++)); do
16179                 $LFS mkdir -i $i $DIR/$tdir/d$i.3 ||
16180                         error "create $DIR/$tdir/d$i.3 failed"
16181         done
16182
16183         # ensure gc thread is done
16184         for i in $(mdts_nodes); do
16185                 wait_update $i "ps -e -o comm= | grep chlg_gc_thread" "" 20 ||
16186                         error "$i: GC-thread not done"
16187         done
16188
16189         local first_rec
16190         for (( i = 1; i <= MDSCOUNT; i++ )); do
16191                 # check cl_user1 still registered
16192                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
16193                         error "mds$i: user1 ${cl_user1[mds$i]} not found (3)"
16194                 # check cl_user2 unregistered
16195                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
16196                         error "mds$i: user2 ${cl_user2[mds$i]} is registered"
16197
16198                 # check changelogs are present and starting at $user_rec1 + 1
16199                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16200                 [ -n "$user_rec1" ] ||
16201                         error "mds$i: user1 ${cl_user1[mds$i]} not found (4)"
16202                 first_rec=$($LFS changelog $(facet_svc mds$i) |
16203                             awk '{ print $1; exit; }')
16204
16205                 echo "mds$i: $(date +%s) verify rec $user_rec1+1 == $first_rec"
16206                 [ $((user_rec1 + 1)) == $first_rec ] ||
16207                         error "mds$i: rec $first_rec != $user_rec1 + 1"
16208         done
16209 }
16210 run_test 160g "changelog garbage collect on idle records"
16211
16212 test_160h() {
16213         remote_mds_nodsh && skip "remote MDS with nodsh" && return
16214         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
16215                 skip "Need MDS version at least 2.10.56"
16216
16217         local mdts=$(comma_list $(mdts_nodes))
16218
16219         # Create a user
16220         changelog_register || error "first changelog_register failed"
16221         changelog_register || error "second changelog_register failed"
16222         local cl_users
16223         declare -A cl_user1
16224         declare -A cl_user2
16225         local user_rec1
16226         local user_rec2
16227         local i
16228
16229         # generate some changelog records to accumulate on each MDT
16230         # use all_char because created files should be evenly distributed
16231         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
16232                 error "test_mkdir $tdir failed"
16233         for ((i = 0; i < MDSCOUNT; i++)); do
16234                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
16235                         error "create $DIR/$tdir/d$i.1 failed"
16236         done
16237
16238         # check changelogs have been generated
16239         local nbcl=$(changelog_dump | wc -l)
16240         [[ $nbcl -eq 0 ]] && error "no changelogs found"
16241
16242         for param in "changelog_max_idle_time=10" \
16243                      "changelog_gc=1" \
16244                      "changelog_min_gc_interval=2"; do
16245                 local MDT0=$(facet_svc $SINGLEMDS)
16246                 local var="${param%=*}"
16247                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
16248
16249                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
16250                 do_nodes $mdts $LCTL set_param mdd.*.$param
16251         done
16252
16253         # force cl_user2 to be idle (1st part)
16254         sleep 9
16255
16256         for i in $(seq $MDSCOUNT); do
16257                 cl_users=(${CL_USERS[mds$i]})
16258                 cl_user1[mds$i]="${cl_users[0]}"
16259                 cl_user2[mds$i]="${cl_users[1]}"
16260
16261                 [ -n "${cl_user1[mds$i]}" ] ||
16262                         error "mds$i: no user registered"
16263                 [ -n "${cl_user2[mds$i]}" ] ||
16264                         error "mds$i: only ${cl_user2[mds$i]} is registered"
16265
16266                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16267                 [ -n "$user_rec1" ] ||
16268                         error "mds$i: User ${cl_user1[mds$i]} not registered"
16269                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
16270                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16271                 [ -n "$user_rec2" ] ||
16272                         error "mds$i: User ${cl_user1[mds$i]} not registered"
16273                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
16274                      "$user_rec1 + 2 == $user_rec2"
16275                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
16276                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
16277                               "$user_rec1 + 2, but is $user_rec2"
16278                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
16279                 [ -n "$user_rec2" ] ||
16280                         error "mds$i: User ${cl_user2[mds$i]} not registered"
16281                 [ $user_rec1 == $user_rec2 ] ||
16282                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
16283                               "$user_rec1, but is $user_rec2"
16284         done
16285
16286         # force cl_user2 to be idle (2nd part) and to reach
16287         # changelog_max_idle_time
16288         sleep 2
16289
16290         # force each GC-thread start and block then
16291         # one per MDT/MDD, set fail_val accordingly
16292         #define OBD_FAIL_FORCE_GC_THREAD 0x1316
16293         do_nodes $mdts $LCTL set_param fail_loc=0x1316
16294
16295         # generate more changelogs to trigger fail_loc
16296         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
16297                 error "create $DIR/$tdir/${tfile}bis failed"
16298
16299         # stop MDT to stop GC-thread, should be done in back-ground as it will
16300         # block waiting for the thread to be released and exit
16301         declare -A stop_pids
16302         for i in $(seq $MDSCOUNT); do
16303                 stop mds$i &
16304                 stop_pids[mds$i]=$!
16305         done
16306
16307         for i in $(mdts_nodes); do
16308                 local facet
16309                 local nb=0
16310                 local facets=$(facets_up_on_host $i)
16311
16312                 for facet in ${facets//,/ }; do
16313                         if [[ $facet == mds* ]]; then
16314                                 nb=$((nb + 1))
16315                         fi
16316                 done
16317                 # ensure each MDS's gc threads are still present and all in "R"
16318                 # state (OBD_FAIL_FORCE_GC_THREAD effect!)
16319                 [[ $(do_node $i pgrep chlg_gc_thread | wc -l) -eq $nb ]] ||
16320                         error "$i: expected $nb GC-thread"
16321                 wait_update $i \
16322                         "ps -C chlg_gc_thread -o state --no-headers | uniq" \
16323                         "R" 20 ||
16324                         error "$i: GC-thread not found in R-state"
16325                 # check umounts of each MDT on MDS have reached kthread_stop()
16326                 [[ $(do_node $i pgrep umount | wc -l) -eq $nb ]] ||
16327                         error "$i: expected $nb umount"
16328                 wait_update $i \
16329                         "ps -C umount -o state --no-headers | uniq" "D" 20 ||
16330                         error "$i: umount not found in D-state"
16331         done
16332
16333         # release all GC-threads
16334         do_nodes $mdts $LCTL set_param fail_loc=0
16335
16336         # wait for MDT stop to complete
16337         for i in $(seq $MDSCOUNT); do
16338                 wait ${stop_pids[mds$i]} || error "mds$i: stop failed"
16339         done
16340
16341         # XXX
16342         # may try to check if any orphan changelog records are present
16343         # via ldiskfs/zfs and llog_reader...
16344
16345         # re-start/mount MDTs
16346         for i in $(seq $MDSCOUNT); do
16347                 start mds$i $(mdsdevname $i) $MDS_MOUNT_OPTS ||
16348                         error "Fail to start mds$i"
16349         done
16350
16351         local first_rec
16352         for i in $(seq $MDSCOUNT); do
16353                 # check cl_user1 still registered
16354                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
16355                         error "mds$i: User ${cl_user1[mds$i]} not registered"
16356                 # check cl_user2 unregistered
16357                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
16358                         error "mds$i: User ${cl_user2[mds$i]} still registered"
16359
16360                 # check changelogs are present and starting at $user_rec1 + 1
16361                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16362                 [ -n "$user_rec1" ] ||
16363                         error "mds$i: User ${cl_user1[mds$i]} not registered"
16364                 first_rec=$($LFS changelog $(facet_svc mds$i) |
16365                             awk '{ print $1; exit; }')
16366
16367                 echo "mds$i: verifying first index $user_rec1 + 1 == $first_rec"
16368                 [ $((user_rec1 + 1)) == $first_rec ] ||
16369                         error "mds$i: first index should be $user_rec1 + 1, " \
16370                               "but is $first_rec"
16371         done
16372 }
16373 run_test 160h "changelog gc thread stop upon umount, orphan records delete " \
16374               "during mount"
16375
16376 test_160i() {
16377
16378         local mdts=$(comma_list $(mdts_nodes))
16379
16380         changelog_register || error "first changelog_register failed"
16381
16382         # generate some changelog records to accumulate on each MDT
16383         # use all_char because created files should be evenly distributed
16384         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
16385                 error "test_mkdir $tdir failed"
16386         for ((i = 0; i < MDSCOUNT; i++)); do
16387                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
16388                         error "create $DIR/$tdir/d$i.1 failed"
16389         done
16390
16391         # check changelogs have been generated
16392         local nbcl=$(changelog_dump | wc -l)
16393         [[ $nbcl -eq 0 ]] && error "no changelogs found"
16394
16395         # simulate race between register and unregister
16396         # XXX as fail_loc is set per-MDS, with DNE configs the race
16397         # simulation will only occur for one MDT per MDS and for the
16398         # others the normal race scenario will take place
16399         #define CFS_FAIL_CHLOG_USER_REG_UNREG_RACE          0x1315
16400         do_nodes $mdts $LCTL set_param fail_loc=0x10001315
16401         do_nodes $mdts $LCTL set_param fail_val=1
16402
16403         # unregister 1st user
16404         changelog_deregister &
16405         local pid1=$!
16406         # wait some time for deregister work to reach race rdv
16407         sleep 2
16408         # register 2nd user
16409         changelog_register || error "2nd user register failed"
16410
16411         wait $pid1 || error "1st user deregister failed"
16412
16413         local i
16414         local last_rec
16415         declare -A LAST_REC
16416         for i in $(seq $MDSCOUNT); do
16417                 if changelog_users mds$i | grep "^cl"; then
16418                         # make sure new records are added with one user present
16419                         LAST_REC[mds$i]=$(changelog_users $SINGLEMDS |
16420                                           awk '/^current.index:/ { print $NF }')
16421                 else
16422                         error "mds$i has no user registered"
16423                 fi
16424         done
16425
16426         # generate more changelog records to accumulate on each MDT
16427         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
16428                 error "create $DIR/$tdir/${tfile}bis failed"
16429
16430         for i in $(seq $MDSCOUNT); do
16431                 last_rec=$(changelog_users $SINGLEMDS |
16432                            awk '/^current.index:/ { print $NF }')
16433                 echo "verify changelogs are on: $last_rec != ${LAST_REC[mds$i]}"
16434                 [ $last_rec != ${LAST_REC[mds$i]} ] ||
16435                         error "changelogs are off on mds$i"
16436         done
16437 }
16438 run_test 160i "changelog user register/unregister race"
16439
16440 test_160j() {
16441         remote_mds_nodsh && skip "remote MDS with nodsh"
16442         [[ $MDS1_VERSION -lt $(version_code 2.12.56) ]] &&
16443                 skip "Need MDS version at least 2.12.56"
16444
16445         mount_client $MOUNT2 || error "mount_client on $MOUNT2 failed"
16446         stack_trap "umount $MOUNT2" EXIT
16447
16448         changelog_register || error "first changelog_register failed"
16449         stack_trap "changelog_deregister" EXIT
16450
16451         # generate some changelog
16452         # use all_char because created files should be evenly distributed
16453         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
16454                 error "mkdir $tdir failed"
16455         for ((i = 0; i < MDSCOUNT; i++)); do
16456                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
16457                         error "create $DIR/$tdir/d$i.1 failed"
16458         done
16459
16460         # open the changelog device
16461         exec 3>/dev/changelog-$FSNAME-MDT0000
16462         stack_trap "exec 3>&-" EXIT
16463         exec 4</dev/changelog-$FSNAME-MDT0000
16464         stack_trap "exec 4<&-" EXIT
16465
16466         # umount the first lustre mount
16467         umount $MOUNT
16468         stack_trap "mount_client $MOUNT" EXIT
16469
16470         # read changelog, which may or may not fail, but should not crash
16471         cat <&4 >/dev/null
16472
16473         # clear changelog
16474         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
16475         changelog_users $SINGLEMDS | grep -q $cl_user ||
16476                 error "User $cl_user not found in changelog_users"
16477
16478         printf 'clear:'$cl_user':0' >&3
16479 }
16480 run_test 160j "client can be umounted while its chanangelog is being used"
16481
16482 test_160k() {
16483         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16484         remote_mds_nodsh && skip "remote MDS with nodsh"
16485
16486         mkdir -p $DIR/$tdir/1/1
16487
16488         changelog_register || error "changelog_register failed"
16489         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
16490
16491         changelog_users $SINGLEMDS | grep -q $cl_user ||
16492                 error "User '$cl_user' not found in changelog_users"
16493 #define OBD_FAIL_MDS_CHANGELOG_REORDER 0x15d
16494         do_facet mds1 $LCTL set_param fail_loc=0x8000015d fail_val=3
16495         rmdir $DIR/$tdir/1/1 & sleep 1
16496         mkdir $DIR/$tdir/2
16497         touch $DIR/$tdir/2/2
16498         rm -rf $DIR/$tdir/2
16499
16500         wait
16501         sleep 4
16502
16503         changelog_dump | grep rmdir || error "rmdir not recorded"
16504 }
16505 run_test 160k "Verify that changelog records are not lost"
16506
16507 # Verifies that a file passed as a parameter has recently had an operation
16508 # performed on it that has generated an MTIME changelog which contains the
16509 # correct parent FID. As files might reside on a different MDT from the
16510 # parent directory in DNE configurations, the FIDs are translated to paths
16511 # before being compared, which should be identical
16512 compare_mtime_changelog() {
16513         local file="${1}"
16514         local mdtidx
16515         local mtime
16516         local cl_fid
16517         local pdir
16518         local dir
16519
16520         mdtidx=$($LFS getstripe --mdt-index $file)
16521         mdtidx=$(printf "%04x" $mdtidx)
16522
16523         # Obtain the parent FID from the MTIME changelog
16524         mtime=$($LFS changelog $FSNAME-MDT$mdtidx | tail -n 1 | grep MTIME)
16525         [ -z "$mtime" ] && error "MTIME changelog not recorded"
16526
16527         cl_fid=$(sed -e 's/.* p=//' -e 's/ .*//' <<<$mtime)
16528         [ -z "$cl_fid" ] && error "parent FID not present"
16529
16530         # Verify that the path for the parent FID is the same as the path for
16531         # the test directory
16532         pdir=$($LFS fid2path $MOUNT "$cl_fid")
16533
16534         dir=$(dirname $1)
16535
16536         [[ "${pdir%/}" == "$dir" ]] ||
16537                 error "MTIME changelog parent FID is wrong, expected $dir, got $pdir"
16538 }
16539
16540 test_160l() {
16541         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16542
16543         remote_mds_nodsh && skip "remote MDS with nodsh"
16544         [[ $MDS1_VERSION -ge $(version_code 2.13.55) ]] ||
16545                 skip "Need MDS version at least 2.13.55"
16546
16547         local cl_user
16548
16549         changelog_register || error "changelog_register failed"
16550         cl_user="${CL_USERS[$SINGLEMDS]%% *}"
16551
16552         changelog_users $SINGLEMDS | grep -q $cl_user ||
16553                 error "User '$cl_user' not found in changelog_users"
16554
16555         # Clear some types so that MTIME changelogs are generated
16556         changelog_chmask "-CREAT"
16557         changelog_chmask "-CLOSE"
16558
16559         test_mkdir $DIR/$tdir || error "failed to mkdir $DIR/$tdir"
16560
16561         # Test CL_MTIME during setattr
16562         touch $DIR/$tdir/$tfile
16563         compare_mtime_changelog $DIR/$tdir/$tfile
16564
16565         # Test CL_MTIME during close
16566         $MULTIOP $DIR/$tdir/${tfile}_2 O_2w4096c || error "multiop failed"
16567         compare_mtime_changelog $DIR/$tdir/${tfile}_2
16568 }
16569 run_test 160l "Verify that MTIME changelog records contain the parent FID"
16570
16571 test_160m() {
16572         remote_mds_nodsh && skip "remote MDS with nodsh" && return
16573         [[ $MDS1_VERSION -ge $(version_code 2.14.51) ]] ||
16574                 skip "Need MDS version at least 2.14.51"
16575         local cl_users
16576         local cl_user1
16577         local cl_user2
16578         local pid1
16579
16580         # Create a user
16581         changelog_register || error "first changelog_register failed"
16582         changelog_register || error "second changelog_register failed"
16583
16584         cl_users=(${CL_USERS[mds1]})
16585         cl_user1="${cl_users[0]}"
16586         cl_user2="${cl_users[1]}"
16587         # generate some changelog records to accumulate on MDT0
16588         test_mkdir -p -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
16589         createmany -m $DIR/$tdir/$tfile 50 ||
16590                 error "create $DIR/$tdir/$tfile failed"
16591         unlinkmany $DIR/$tdir/$tfile 50 || error "unlinkmany failed"
16592         rm -f $DIR/$tdir
16593
16594         # check changelogs have been generated
16595         local nbcl=$(changelog_dump | wc -l)
16596         [[ $nbcl -eq 0 ]] && error "no changelogs found"
16597
16598 #define OBD_FAIL_MDS_CHANGELOG_RACE      0x15f
16599         do_facet mds1 $LCTL set_param fail_loc=0x8000015f fail_val=0
16600
16601         __changelog_clear mds1 $cl_user1 +10
16602         __changelog_clear mds1 $cl_user2 0 &
16603         pid1=$!
16604         sleep 2
16605         __changelog_clear mds1 $cl_user1 0 ||
16606                 error "fail to cancel record for $cl_user1"
16607         wait $pid1
16608         [[ $? -eq 0 ]] || error "fail to cancel record for $cl_user2"
16609 }
16610 run_test 160m "Changelog clear race"
16611
16612 test_160n() {
16613         remote_mds_nodsh && skip "remote MDS with nodsh" && return
16614         [[ $MDS1_VERSION -ge $(version_code 2.14.51) ]] ||
16615                 skip "Need MDS version at least 2.14.51"
16616         local cl_users
16617         local cl_user1
16618         local cl_user2
16619         local pid1
16620         local first_rec
16621         local last_rec=0
16622
16623         # Create a user
16624         changelog_register || error "first changelog_register failed"
16625
16626         cl_users=(${CL_USERS[mds1]})
16627         cl_user1="${cl_users[0]}"
16628
16629         # generate some changelog records to accumulate on MDT0
16630         test_mkdir -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
16631         first_rec=$(changelog_users $SINGLEMDS |
16632                         awk '/^current.index:/ { print $NF }')
16633         while (( last_rec < (( first_rec + 65000)) )); do
16634                 createmany -m $DIR/$tdir/$tfile 10000 ||
16635                         error "create $DIR/$tdir/$tfile failed"
16636
16637                 for i in $(seq 0 10000); do
16638                         mrename $DIR/$tdir/$tfile$i $DIR/$tdir/$tfile-new$i \
16639                                 > /dev/null
16640                 done
16641
16642                 unlinkmany $DIR/$tdir/$tfile-new 10000 ||
16643                         error "unlinkmany failed unlink"
16644                 last_rec=$(changelog_users $SINGLEMDS |
16645                         awk '/^current.index:/ { print $NF }')
16646                 echo last record $last_rec
16647                 (( last_rec == 0 )) && error "no changelog found"
16648         done
16649
16650 #define OBD_FAIL_MDS_CHANGELOG_DEL       0x16c
16651         do_facet mds1 $LCTL set_param fail_loc=0x8000016c fail_val=0
16652
16653         __changelog_clear mds1 $cl_user1 0 &
16654         pid1=$!
16655         sleep 2
16656         __changelog_clear mds1 $cl_user1 0 ||
16657                 error "fail to cancel record for $cl_user1"
16658         wait $pid1
16659         [[ $? -eq 0 ]] || error "fail to cancel record for $cl_user2"
16660 }
16661 run_test 160n "Changelog destroy race"
16662
16663 test_160o() {
16664         local mdt="$(facet_svc $SINGLEMDS)"
16665
16666         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
16667         remote_mds_nodsh && skip "remote MDS with nodsh"
16668         [ $MDS1_VERSION -ge $(version_code 2.14.52) ] ||
16669                 skip "Need MDS version at least 2.14.52"
16670
16671         changelog_register --user test_160o -m unlnk+close+open ||
16672                 error "changelog_register failed"
16673
16674         do_facet $SINGLEMDS $LCTL --device $mdt \
16675                                 changelog_register -u "Tt3_-#" &&
16676                 error "bad symbols in name should fail"
16677
16678         do_facet $SINGLEMDS $LCTL --device $mdt \
16679                                 changelog_register -u test_160o &&
16680                 error "the same name registration should fail"
16681
16682         do_facet $SINGLEMDS $LCTL --device $mdt \
16683                         changelog_register -u test_160toolongname &&
16684                 error "too long name registration should fail"
16685
16686         changelog_chmask "MARK+HSM"
16687         lctl get_param mdd.*.changelog*mask
16688         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
16689         changelog_users $SINGLEMDS | grep -q $cl_user ||
16690                 error "User $cl_user not found in changelog_users"
16691         #verify username
16692         echo $cl_user | grep -q test_160o ||
16693                 error "User $cl_user has no specific name 'test160o'"
16694
16695         # change something
16696         changelog_clear 0 || error "changelog_clear failed"
16697         # generate some changelog records to accumulate on MDT0
16698         test_mkdir -p -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
16699         touch $DIR/$tdir/$tfile                 # open 1
16700
16701         OPENS=$(changelog_dump | grep -c "OPEN")
16702         [[ $OPENS -eq 1 ]] || error "OPEN changelog mask count $OPENS != 1"
16703
16704         # must be no MKDIR it wasn't set as user mask
16705         MKDIR=$(changelog_dump | grep -c "MKDIR")
16706         [[ $MKDIR -eq 0 ]] || error "MKDIR changelog mask found $MKDIR > 0"
16707
16708         oldmask=$(do_facet $SINGLEMDS $LCTL get_param \
16709                                 mdd.$mdt.changelog_current_mask -n)
16710         # register maskless user
16711         changelog_register || error "changelog_register failed"
16712         # effective mask should be not changed because it is not minimal
16713         mask=$(do_facet $SINGLEMDS $LCTL get_param \
16714                                 mdd.$mdt.changelog_current_mask -n)
16715         [[ $mask == $oldmask ]] || error "mask was changed: $mask vs $oldmask"
16716         # set server mask to minimal value
16717         changelog_chmask "MARK"
16718         # check effective mask again, should be treated as DEFMASK now
16719         mask=$(do_facet $SINGLEMDS $LCTL get_param \
16720                                 mdd.$mdt.changelog_current_mask -n)
16721         [[ $mask == *"HLINK"* ]] || error "mask is not DEFMASK as expected"
16722
16723         do_facet $SINGLEMDS $LCTL --device $mdt \
16724                                 changelog_deregister -u test_160o ||
16725                 error "cannot deregister by name"
16726 }
16727 run_test 160o "changelog user name and mask"
16728
16729 test_160p() {
16730         remote_mds_nodsh && skip "remote MDS with nodsh" && return
16731         [[ $MDS1_VERSION -ge $(version_code 2.14.51) ]] ||
16732                 skip "Need MDS version at least 2.14.51"
16733         [[ "$mds1_FSTYPE" == "ldiskfs" ]] || skip "ldiskfs only test"
16734         local cl_users
16735         local cl_user1
16736         local entry_count
16737
16738         # Create a user
16739         changelog_register || error "first changelog_register failed"
16740
16741         cl_users=(${CL_USERS[mds1]})
16742         cl_user1="${cl_users[0]}"
16743
16744         test_mkdir -p -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
16745         createmany -m $DIR/$tdir/$tfile 50 ||
16746                 error "create $DIR/$tdir/$tfile failed"
16747         unlinkmany $DIR/$tdir/$tfile 50 || error "unlinkmany failed"
16748         rm -rf $DIR/$tdir
16749
16750         # check changelogs have been generated
16751         entry_count=$(changelog_dump | wc -l)
16752         ((entry_count != 0)) || error "no changelog entries found"
16753
16754         # remove changelog_users and check that orphan entries are removed
16755         stop mds1
16756         do_facet mds1 "$DEBUGFS -w -R 'rm changelog_users' $(mdsdevname 1)"
16757         start mds1 || error "cannot start mdt"
16758         entry_count=$(changelog_dump | wc -l)
16759         ((entry_count == 0)) ||
16760                 error "found $entry_count changelog entries, expected none"
16761 }
16762 run_test 160p "Changelog orphan cleanup with no users"
16763
16764 test_160q() {
16765         local mdt="$(facet_svc $SINGLEMDS)"
16766         local clu
16767
16768         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
16769         remote_mds_nodsh && skip "remote MDS with nodsh"
16770         [ $MDS1_VERSION -ge $(version_code 2.14.54) ] ||
16771                 skip "Need MDS version at least 2.14.54"
16772
16773         # set server mask to minimal value like server init does
16774         changelog_chmask "MARK"
16775         clu=$(do_facet $SINGLEMDS $LCTL --device $mdt changelog_register -n) ||
16776                 error "changelog_register failed"
16777         # check effective mask again, should be treated as DEFMASK now
16778         mask=$(do_facet $SINGLEMDS $LCTL get_param \
16779                                 mdd.$mdt.changelog_current_mask -n)
16780         do_facet $SINGLEMDS $LCTL --device $mdt changelog_deregister $clu ||
16781                 error "changelog_deregister failed"
16782         [[ $mask == *"HLINK"* ]] || error "mask is not DEFMASK as expected"
16783 }
16784 run_test 160q "changelog effective mask is DEFMASK if not set"
16785
16786 test_160s() {
16787         remote_mds_nodsh && skip "remote MDS with nodsh"
16788         (( $MDS1_VERSION >= $(version_code 2.14.55) )) ||
16789                 skip "Need MDS version at least 2.14.55"
16790
16791         local mdts=$(comma_list $(mdts_nodes))
16792
16793         #define OBD_FAIL_TIME_IN_CHLOG_USER     0x1314
16794         do_nodes $mdts $LCTL set_param fail_loc=0x1314 \
16795                                        fail_val=$((24 * 3600 * 10))
16796
16797         # Create a user which is 10 days old
16798         changelog_register || error "first changelog_register failed"
16799         local cl_users
16800         declare -A cl_user1
16801         local i
16802
16803         # generate some changelog records to accumulate on each MDT
16804         # use all_char because created files should be evenly distributed
16805         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
16806                 error "test_mkdir $tdir failed"
16807         for ((i = 0; i < MDSCOUNT; i++)); do
16808                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
16809                         error "create $DIR/$tdir/d$i.1 failed"
16810         done
16811
16812         # check changelogs have been generated
16813         local nbcl=$(changelog_dump | wc -l)
16814         (( nbcl > 0 )) || error "no changelogs found"
16815
16816         # reduce the max_idle_indexes value to make sure we exceed it
16817         for param in "changelog_max_idle_indexes=2097446912" \
16818                      "changelog_max_idle_time=2592000" \
16819                      "changelog_gc=1" \
16820                      "changelog_min_gc_interval=2"; do
16821                 local MDT0=$(facet_svc $SINGLEMDS)
16822                 local var="${param%=*}"
16823                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
16824
16825                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
16826                 do_nodes $mdts $LCTL set_param mdd.*.$param ||
16827                         error "unable to set mdd.*.$param"
16828         done
16829
16830         local start=$SECONDS
16831         for i in $(seq $MDSCOUNT); do
16832                 cl_users=(${CL_USERS[mds$i]})
16833                 cl_user1[mds$i]="${cl_users[0]}"
16834
16835                 [[ -n "${cl_user1[mds$i]}" ]] ||
16836                         error "mds$i: no user registered"
16837         done
16838
16839         #define OBD_FAIL_MDS_CHANGELOG_IDX_PUMP   0x16d
16840         do_nodes $mdts $LCTL set_param fail_loc=0x16d fail_val=500000000
16841
16842         # ensure we are past the previous changelog_min_gc_interval set above
16843         local sleep2=$((start + 2 - SECONDS))
16844         (( sleep2 > 0 )) && echo "sleep $sleep2 for interval" && sleep $sleep2
16845
16846         # Generate one more changelog to trigger GC
16847         for ((i = 0; i < MDSCOUNT; i++)); do
16848                 $LFS mkdir -i $i $DIR/$tdir/d$i.3 $DIR/$tdir/d$i.4 ||
16849                         error "create $DIR/$tdir/d$i.3 failed"
16850         done
16851
16852         # ensure gc thread is done
16853         for node in $(mdts_nodes); do
16854                 wait_update $node "pgrep chlg_gc_thread" "" 20 ||
16855                         error "$node: GC-thread not done"
16856         done
16857
16858         do_nodes $mdts $LCTL set_param fail_loc=0
16859
16860         for (( i = 1; i <= MDSCOUNT; i++ )); do
16861                 # check cl_user1 is purged
16862                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" &&
16863                         error "mds$i: User ${cl_user1[mds$i]} is registered"
16864         done
16865         return 0
16866 }
16867 run_test 160s "changelog garbage collect on idle records * time"
16868
16869 test_161a() {
16870         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16871
16872         test_mkdir -c1 $DIR/$tdir
16873         cp /etc/hosts $DIR/$tdir/$tfile
16874         test_mkdir -c1 $DIR/$tdir/foo1
16875         test_mkdir -c1 $DIR/$tdir/foo2
16876         ln $DIR/$tdir/$tfile $DIR/$tdir/foo1/sofia
16877         ln $DIR/$tdir/$tfile $DIR/$tdir/foo2/zachary
16878         ln $DIR/$tdir/$tfile $DIR/$tdir/foo1/luna
16879         ln $DIR/$tdir/$tfile $DIR/$tdir/foo2/thor
16880         local FID=$($LFS path2fid $DIR/$tdir/$tfile | tr -d '[]')
16881         if [ "$($LFS fid2path $DIR $FID | wc -l)" != "5" ]; then
16882                 $LFS fid2path $DIR $FID
16883                 error "bad link ea"
16884         fi
16885         # middle
16886         rm $DIR/$tdir/foo2/zachary
16887         # last
16888         rm $DIR/$tdir/foo2/thor
16889         # first
16890         rm $DIR/$tdir/$tfile
16891         # rename
16892         mv $DIR/$tdir/foo1/sofia $DIR/$tdir/foo2/maggie
16893         [ "$($LFS fid2path $FSNAME --link 1 $FID)" != "$tdir/foo2/maggie" ] &&
16894                 { $LFS fid2path $DIR $FID; error "bad link rename"; }
16895         rm $DIR/$tdir/foo2/maggie
16896
16897         # overflow the EA
16898         local longname=$tfile.avg_len_is_thirty_two_
16899         stack_trap "unlinkmany $DIR/$tdir/foo2/$longname 1000 || \
16900                 error_noexit 'failed to unlink many hardlinks'" EXIT
16901         createmany -l$DIR/$tdir/foo1/luna $DIR/$tdir/foo2/$longname 1000 ||
16902                 error "failed to hardlink many files"
16903         links=$($LFS fid2path $DIR $FID | wc -l)
16904         echo -n "${links}/1000 links in link EA"
16905         [[ $links -gt 60 ]] || error "expected at least 60 links in link EA"
16906 }
16907 run_test 161a "link ea sanity"
16908
16909 test_161b() {
16910         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16911         [ $MDSCOUNT -lt 2 ] && skip_env "skipping remote directory test"
16912
16913         local MDTIDX=1
16914         local remote_dir=$DIR/$tdir/remote_dir
16915
16916         mkdir -p $DIR/$tdir
16917         $LFS mkdir -i $MDTIDX $remote_dir ||
16918                 error "create remote directory failed"
16919
16920         cp /etc/hosts $remote_dir/$tfile
16921         mkdir -p $remote_dir/foo1
16922         mkdir -p $remote_dir/foo2
16923         ln $remote_dir/$tfile $remote_dir/foo1/sofia
16924         ln $remote_dir/$tfile $remote_dir/foo2/zachary
16925         ln $remote_dir/$tfile $remote_dir/foo1/luna
16926         ln $remote_dir/$tfile $remote_dir/foo2/thor
16927
16928         local FID=$($LFS path2fid $remote_dir/$tfile | tr -d '[' |
16929                      tr -d ']')
16930         if [ "$($LFS fid2path $DIR $FID | wc -l)" != "5" ]; then
16931                 $LFS fid2path $DIR $FID
16932                 error "bad link ea"
16933         fi
16934         # middle
16935         rm $remote_dir/foo2/zachary
16936         # last
16937         rm $remote_dir/foo2/thor
16938         # first
16939         rm $remote_dir/$tfile
16940         # rename
16941         mv $remote_dir/foo1/sofia $remote_dir/foo2/maggie
16942         local link_path=$($LFS fid2path $FSNAME --link 1 $FID)
16943         if [ "$DIR/$link_path" != "$remote_dir/foo2/maggie" ]; then
16944                 $LFS fid2path $DIR $FID
16945                 error "bad link rename"
16946         fi
16947         rm $remote_dir/foo2/maggie
16948
16949         # overflow the EA
16950         local longname=filename_avg_len_is_thirty_two_
16951         createmany -l$remote_dir/foo1/luna $remote_dir/foo2/$longname 1000 ||
16952                 error "failed to hardlink many files"
16953         links=$($LFS fid2path $DIR $FID | wc -l)
16954         echo -n "${links}/1000 links in link EA"
16955         [[ ${links} -gt 60 ]] ||
16956                 error "expected at least 60 links in link EA"
16957         unlinkmany $remote_dir/foo2/$longname 1000 ||
16958         error "failed to unlink many hardlinks"
16959 }
16960 run_test 161b "link ea sanity under remote directory"
16961
16962 test_161c() {
16963         remote_mds_nodsh && skip "remote MDS with nodsh"
16964         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16965         [[ $MDS1_VERSION -lt $(version_code 2.1.5) ]] &&
16966                 skip "Need MDS version at least 2.1.5"
16967
16968         # define CLF_RENAME_LAST 0x0001
16969         # rename overwrite a target having nlink = 1 (changelog flag 0x1)
16970         changelog_register || error "changelog_register failed"
16971
16972         rm -rf $DIR/$tdir
16973         test_mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir
16974         touch $DIR/$tdir/foo_161c
16975         touch $DIR/$tdir/bar_161c
16976         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/bar_161c
16977         changelog_dump | grep RENME | tail -n 5
16978         local flags=$(changelog_dump | grep "RENME.*bar_161c" | cut -f5 -d' ')
16979         changelog_clear 0 || error "changelog_clear failed"
16980         if [ x$flags != "x0x1" ]; then
16981                 error "flag $flags is not 0x1"
16982         fi
16983
16984         echo "rename overwrite target with nlink = 1, changelog flags=$flags"
16985         # rename overwrite a target having nlink > 1 (changelog flag 0x0)
16986         touch $DIR/$tdir/foo_161c
16987         touch $DIR/$tdir/bar_161c
16988         ln $DIR/$tdir/bar_161c $DIR/$tdir/foobar_161c
16989         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/bar_161c
16990         changelog_dump | grep RENME | tail -n 5
16991         flags=$(changelog_dump | grep "RENME.*bar_161c" | cut -f5 -d' ')
16992         changelog_clear 0 || error "changelog_clear failed"
16993         if [ x$flags != "x0x0" ]; then
16994                 error "flag $flags is not 0x0"
16995         fi
16996         echo "rename overwrite a target having nlink > 1," \
16997                 "changelog record has flags of $flags"
16998
16999         # rename doesn't overwrite a target (changelog flag 0x0)
17000         touch $DIR/$tdir/foo_161c
17001         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/foo2_161c
17002         changelog_dump | grep RENME | tail -n 5
17003         flags=$(changelog_dump | grep RENME | tail -1 | cut -f5 -d' ')
17004         changelog_clear 0 || error "changelog_clear failed"
17005         if [ x$flags != "x0x0" ]; then
17006                 error "flag $flags is not 0x0"
17007         fi
17008         echo "rename doesn't overwrite a target," \
17009                 "changelog record has flags of $flags"
17010
17011         # define CLF_UNLINK_LAST 0x0001
17012         # unlink a file having nlink = 1 (changelog flag 0x1)
17013         rm -f $DIR/$tdir/foo2_161c
17014         changelog_dump | grep UNLNK | tail -n 5
17015         flags=$(changelog_dump | grep UNLNK | tail -1 | cut -f5 -d' ')
17016         changelog_clear 0 || error "changelog_clear failed"
17017         if [ x$flags != "x0x1" ]; then
17018                 error "flag $flags is not 0x1"
17019         fi
17020         echo "unlink a file having nlink = 1," \
17021                 "changelog record has flags of $flags"
17022
17023         # unlink a file having nlink > 1 (changelog flag 0x0)
17024         ln -f $DIR/$tdir/bar_161c $DIR/$tdir/foobar_161c
17025         rm -f $DIR/$tdir/foobar_161c
17026         changelog_dump | grep UNLNK | tail -n 5
17027         flags=$(changelog_dump | grep UNLNK | tail -1 | cut -f5 -d' ')
17028         changelog_clear 0 || error "changelog_clear failed"
17029         if [ x$flags != "x0x0" ]; then
17030                 error "flag $flags is not 0x0"
17031         fi
17032         echo "unlink a file having nlink > 1, changelog record flags '$flags'"
17033 }
17034 run_test 161c "check CL_RENME[UNLINK] changelog record flags"
17035
17036 test_161d() {
17037         remote_mds_nodsh && skip "remote MDS with nodsh"
17038         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
17039
17040         local pid
17041         local fid
17042
17043         changelog_register || error "changelog_register failed"
17044
17045         # work in a standalone dir to avoid locking on $DIR/$MOUNT to
17046         # interfer with $MOUNT/.lustre/fid/ access
17047         mkdir $DIR/$tdir
17048         [[ $? -eq 0 ]] || error "mkdir failed"
17049
17050         #define OBD_FAIL_LLITE_CREATE_NODE_PAUSE 0x140c | OBD_FAIL_ONCE
17051         $LCTL set_param fail_loc=0x8000140c
17052         # 5s pause
17053         $LCTL set_param fail_val=5
17054
17055         # create file
17056         echo foofoo > $DIR/$tdir/$tfile &
17057         pid=$!
17058
17059         # wait for create to be delayed
17060         sleep 2
17061
17062         ps -p $pid
17063         [[ $? -eq 0 ]] || error "create should be blocked"
17064
17065         local tempfile="$(mktemp --tmpdir $tfile.XXXXXX)"
17066         stack_trap "rm -f $tempfile"
17067         fid=$(changelog_extract_field "CREAT" "$tfile" "t=")
17068         cat $MOUNT/.lustre/fid/$fid 2>/dev/null >$tempfile || error "cat failed"
17069         # some delay may occur during ChangeLog publishing and file read just
17070         # above, that could allow file write to happen finally
17071         [[ -s $tempfile ]] && echo "file should be empty"
17072
17073         $LCTL set_param fail_loc=0
17074
17075         wait $pid
17076         [[ $? -eq 0 ]] || error "create failed"
17077 }
17078 run_test 161d "create with concurrent .lustre/fid access"
17079
17080 check_path() {
17081         local expected="$1"
17082         shift
17083         local fid="$2"
17084
17085         local path
17086         path=$($LFS fid2path "$@")
17087         local rc=$?
17088
17089         if [ $rc -ne 0 ]; then
17090                 error "path looked up of '$expected' failed: rc=$rc"
17091         elif [ "$path" != "$expected" ]; then
17092                 error "path looked up '$path' instead of '$expected'"
17093         else
17094                 echo "FID '$fid' resolves to path '$path' as expected"
17095         fi
17096 }
17097
17098 test_162a() { # was test_162
17099         test_mkdir -p -c1 $DIR/$tdir/d2
17100         touch $DIR/$tdir/d2/$tfile
17101         touch $DIR/$tdir/d2/x1
17102         touch $DIR/$tdir/d2/x2
17103         test_mkdir -p -c1 $DIR/$tdir/d2/a/b/c
17104         test_mkdir -p -c1 $DIR/$tdir/d2/p/q/r
17105         # regular file
17106         local fid=$($LFS path2fid $DIR/$tdir/d2/$tfile | tr -d '[]')
17107         check_path "$tdir/d2/$tfile" $FSNAME "$fid" --link 0
17108
17109         # softlink
17110         ln -s $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/p/q/r/slink
17111         fid=$($LFS path2fid $DIR/$tdir/d2/p/q/r/slink | tr -d '[]')
17112         check_path "$tdir/d2/p/q/r/slink" $FSNAME "$fid" --link 0
17113
17114         # softlink to wrong file
17115         ln -s /this/is/garbage $DIR/$tdir/d2/p/q/r/slink.wrong
17116         fid=$($LFS path2fid $DIR/$tdir/d2/p/q/r/slink.wrong | tr -d '[]')
17117         check_path "$tdir/d2/p/q/r/slink.wrong" $FSNAME "$fid" --link 0
17118
17119         # hardlink
17120         ln $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/p/q/r/hlink
17121         mv $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/a/b/c/new_file
17122         fid=$($LFS path2fid $DIR/$tdir/d2/a/b/c/new_file | tr -d '[]')
17123         # fid2path dir/fsname should both work
17124         check_path "$tdir/d2/a/b/c/new_file" $FSNAME "$fid" --link 1
17125         check_path "$DIR/$tdir/d2/p/q/r/hlink" $DIR "$fid" --link 0
17126
17127         # hardlink count: check that there are 2 links
17128         local nlinks=$($LFS fid2path $DIR "$fid" | wc -l)
17129         [ $nlinks -eq 2 ] || error "expect 2 links, found $nlinks"
17130
17131         # hardlink indexing: remove the first link
17132         rm $DIR/$tdir/d2/p/q/r/hlink
17133         check_path "$tdir/d2/a/b/c/new_file" $FSNAME $fid --link 0
17134 }
17135 run_test 162a "path lookup sanity"
17136
17137 test_162b() {
17138         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17139         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
17140
17141         mkdir $DIR/$tdir
17142         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
17143                                 error "create striped dir failed"
17144
17145         local FID=$($LFS getdirstripe $DIR/$tdir/striped_dir |
17146                                         tail -n 1 | awk '{print $2}')
17147         stat $MOUNT/.lustre/fid/$FID && error "sub_stripe can be accessed"
17148
17149         touch $DIR/$tdir/striped_dir/f{0..4} || error "touch f0..4 failed"
17150         mkdir $DIR/$tdir/striped_dir/d{0..4} || error "mkdir d0..4 failed"
17151
17152         # regular file
17153         for ((i=0;i<5;i++)); do
17154                 FID=$($LFS path2fid $DIR/$tdir/striped_dir/f$i | tr -d '[]') ||
17155                         error "get fid for f$i failed"
17156                 check_path "$tdir/striped_dir/f$i" $FSNAME $FID --link 0
17157
17158                 FID=$($LFS path2fid $DIR/$tdir/striped_dir/d$i | tr -d '[]') ||
17159                         error "get fid for d$i failed"
17160                 check_path "$tdir/striped_dir/d$i" $FSNAME $FID --link 0
17161         done
17162
17163         return 0
17164 }
17165 run_test 162b "striped directory path lookup sanity"
17166
17167 # LU-4239: Verify fid2path works with paths 100 or more directories deep
17168 test_162c() {
17169         [[ $MDS1_VERSION -lt $(version_code 2.7.51) ]] &&
17170                 skip "Need MDS version at least 2.7.51"
17171
17172         local lpath=$tdir.local
17173         local rpath=$tdir.remote
17174
17175         test_mkdir $DIR/$lpath
17176         test_mkdir $DIR/$rpath
17177
17178         for ((i = 0; i <= 101; i++)); do
17179                 lpath="$lpath/$i"
17180                 mkdir $DIR/$lpath
17181                 FID=$($LFS path2fid $DIR/$lpath | tr -d '[]') ||
17182                         error "get fid for local directory $DIR/$lpath failed"
17183                 check_path "$DIR/$lpath" $MOUNT $FID --link 0
17184
17185                 rpath="$rpath/$i"
17186                 test_mkdir $DIR/$rpath
17187                 FID=$($LFS path2fid $DIR/$rpath | tr -d '[]') ||
17188                         error "get fid for remote directory $DIR/$rpath failed"
17189                 check_path "$DIR/$rpath" $MOUNT $FID --link 0
17190         done
17191
17192         return 0
17193 }
17194 run_test 162c "fid2path works with paths 100 or more directories deep"
17195
17196 oalr_event_count() {
17197         local event="${1}"
17198         local trace="${2}"
17199
17200         awk -v name="${FSNAME}-OST0000" \
17201             -v event="${event}" \
17202             '$1 == "TRACE" && $2 == event && $3 == name' \
17203             "${trace}" |
17204         wc -l
17205 }
17206
17207 oalr_expect_event_count() {
17208         local event="${1}"
17209         local trace="${2}"
17210         local expect="${3}"
17211         local count
17212
17213         count=$(oalr_event_count "${event}" "${trace}")
17214         if ((count == expect)); then
17215                 return 0
17216         fi
17217
17218         error_noexit "${event} event count was '${count}', expected ${expect}"
17219         cat "${trace}" >&2
17220         exit 1
17221 }
17222
17223 cleanup_165() {
17224         do_facet ost1 killall --quiet -KILL ofd_access_log_reader || true
17225         stop ost1
17226         start ost1 "$(ostdevname 1)" $OST_MOUNT_OPTS
17227 }
17228
17229 setup_165() {
17230         sync # Flush previous IOs so we can count log entries.
17231         do_facet ost1 $LCTL set_param "obdfilter.${FSNAME}-OST0000.access_log_size=4096"
17232         stack_trap cleanup_165 EXIT
17233 }
17234
17235 test_165a() {
17236         local trace="/tmp/${tfile}.trace"
17237         local rc
17238         local count
17239
17240         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
17241                 skip "OFD access log unsupported"
17242
17243         setup_165
17244         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
17245         sleep 5
17246
17247         do_facet ost1 ofd_access_log_reader --list
17248         stop ost1
17249
17250         do_facet ost1 killall -TERM ofd_access_log_reader
17251         wait
17252         rc=$?
17253
17254         if ((rc != 0)); then
17255                 error "ofd_access_log_reader exited with rc = '${rc}'"
17256         fi
17257
17258         # Parse trace file for discovery events:
17259         oalr_expect_event_count alr_log_add "${trace}" 1
17260         oalr_expect_event_count alr_log_eof "${trace}" 1
17261         oalr_expect_event_count alr_log_free "${trace}" 1
17262 }
17263 run_test 165a "ofd access log discovery"
17264
17265 test_165b() {
17266         local trace="/tmp/${tfile}.trace"
17267         local file="${DIR}/${tfile}"
17268         local pfid1
17269         local pfid2
17270         local -a entry
17271         local rc
17272         local count
17273         local size
17274         local flags
17275
17276         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
17277                 skip "OFD access log unsupported"
17278
17279         setup_165
17280         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
17281         sleep 5
17282
17283         do_facet ost1 ofd_access_log_reader --list
17284
17285         lfs setstripe -c 1 -i 0 "${file}"
17286         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
17287                 error "cannot create '${file}'"
17288
17289         sleep 5
17290         do_facet ost1 killall -TERM ofd_access_log_reader
17291         wait
17292         rc=$?
17293
17294         if ((rc != 0)); then
17295                 error "ofd_access_log_reader exited with rc = '${rc}'"
17296         fi
17297
17298         oalr_expect_event_count alr_log_entry "${trace}" 1
17299
17300         pfid1=$($LFS path2fid "${file}")
17301
17302         # 1     2             3   4    5     6   7    8    9     10
17303         # TRACE alr_log_entry OST PFID BEGIN END TIME SIZE COUNT FLAGS
17304         entry=( - $(awk -v pfid="${pfid}" '$1 == "TRACE" && $2 == "alr_log_entry"' "${trace}" ) )
17305
17306         echo "entry = '${entry[*]}'" >&2
17307
17308         pfid2=${entry[4]}
17309         if [[ "${pfid1}" != "${pfid2}" ]]; then
17310                 error "entry '${entry[*]}' has invalid PFID '${pfid2}', expected ${pfid1}"
17311         fi
17312
17313         size=${entry[8]}
17314         if ((size != 1048576)); then
17315                 error "entry '${entry[*]}' has invalid io size '${size}', expected 1048576"
17316         fi
17317
17318         flags=${entry[10]}
17319         if [[ "${flags}" != "w" ]]; then
17320                 error "entry '${entry[*]}' has invalid io flags '${flags}', expected 'w'"
17321         fi
17322
17323         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
17324         sleep 5
17325
17326         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r524288c ||
17327                 error "cannot read '${file}'"
17328         sleep 5
17329
17330         do_facet ost1 killall -TERM ofd_access_log_reader
17331         wait
17332         rc=$?
17333
17334         if ((rc != 0)); then
17335                 error "ofd_access_log_reader exited with rc = '${rc}'"
17336         fi
17337
17338         oalr_expect_event_count alr_log_entry "${trace}" 1
17339
17340         entry=( - $(awk -v pfid="${pfid}" '$1 == "TRACE" && $2 == "alr_log_entry"' "${trace}" ) )
17341         echo "entry = '${entry[*]}'" >&2
17342
17343         pfid2=${entry[4]}
17344         if [[ "${pfid1}" != "${pfid2}" ]]; then
17345                 error "entry '${entry[*]}' has invalid PFID '${pfid2}', expected ${pfid1}"
17346         fi
17347
17348         size=${entry[8]}
17349         if ((size != 524288)); then
17350                 error "entry '${entry[*]}' has invalid io size '${size}', 524288"
17351         fi
17352
17353         flags=${entry[10]}
17354         if [[ "${flags}" != "r" ]]; then
17355                 error "entry '${entry[*]}' has invalid io flags '${flags}', expected 'r'"
17356         fi
17357 }
17358 run_test 165b "ofd access log entries are produced and consumed"
17359
17360 test_165c() {
17361         local trace="/tmp/${tfile}.trace"
17362         local file="${DIR}/${tdir}/${tfile}"
17363
17364         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
17365                 skip "OFD access log unsupported"
17366
17367         test_mkdir "${DIR}/${tdir}"
17368
17369         setup_165
17370         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
17371         sleep 5
17372
17373         lfs setstripe -c 1 -i 0 "${DIR}/${tdir}"
17374
17375         # 4096 / 64 = 64. Create twice as many entries.
17376         for ((i = 0; i < 128; i++)); do
17377                 $MULTIOP "${file}-${i}" oO_CREAT:O_WRONLY:w512c ||
17378                         error "cannot create file"
17379         done
17380
17381         sync
17382
17383         do_facet ost1 killall -TERM ofd_access_log_reader
17384         wait
17385         rc=$?
17386         if ((rc != 0)); then
17387                 error "ofd_access_log_reader exited with rc = '${rc}'"
17388         fi
17389
17390         unlinkmany  "${file}-%d" 128
17391 }
17392 run_test 165c "full ofd access logs do not block IOs"
17393
17394 oal_get_read_count() {
17395         local stats="$1"
17396
17397         # STATS lustre-OST0001 alr_read_count 1
17398
17399         do_facet ost1 cat "${stats}" |
17400         awk '$1 == "STATS" && $3 == "alr_read_count" { count = $4; }
17401              END { print count; }'
17402 }
17403
17404 oal_expect_read_count() {
17405         local stats="$1"
17406         local count
17407         local expect="$2"
17408
17409         # Ask ofd_access_log_reader to write stats.
17410         do_facet ost1 killall -USR1 ofd_access_log_reader
17411
17412         # Allow some time for things to happen.
17413         sleep 1
17414
17415         count=$(oal_get_read_count "${stats}")
17416         if ((count == expect)); then
17417                 return 0
17418         fi
17419
17420         error_noexit "bad read count, got ${count}, expected ${expect}"
17421         do_facet ost1 cat "${stats}" >&2
17422         exit 1
17423 }
17424
17425 test_165d() {
17426         local stats="/tmp/${tfile}.stats"
17427         local file="${DIR}/${tdir}/${tfile}"
17428         local param="obdfilter.${FSNAME}-OST0000.access_log_mask"
17429
17430         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
17431                 skip "OFD access log unsupported"
17432
17433         test_mkdir "${DIR}/${tdir}"
17434
17435         setup_165
17436         do_facet ost1 ofd_access_log_reader --stats="${stats}" &
17437         sleep 5
17438
17439         lfs setstripe -c 1 -i 0 "${file}"
17440
17441         do_facet ost1 lctl set_param "${param}=rw"
17442         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
17443                 error "cannot create '${file}'"
17444         oal_expect_read_count "${stats}" 1
17445
17446         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
17447                 error "cannot read '${file}'"
17448         oal_expect_read_count "${stats}" 2
17449
17450         do_facet ost1 lctl set_param "${param}=r"
17451         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
17452                 error "cannot create '${file}'"
17453         oal_expect_read_count "${stats}" 2
17454
17455         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
17456                 error "cannot read '${file}'"
17457         oal_expect_read_count "${stats}" 3
17458
17459         do_facet ost1 lctl set_param "${param}=w"
17460         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
17461                 error "cannot create '${file}'"
17462         oal_expect_read_count "${stats}" 4
17463
17464         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
17465                 error "cannot read '${file}'"
17466         oal_expect_read_count "${stats}" 4
17467
17468         do_facet ost1 lctl set_param "${param}=0"
17469         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
17470                 error "cannot create '${file}'"
17471         oal_expect_read_count "${stats}" 4
17472
17473         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
17474                 error "cannot read '${file}'"
17475         oal_expect_read_count "${stats}" 4
17476
17477         do_facet ost1 killall -TERM ofd_access_log_reader
17478         wait
17479         rc=$?
17480         if ((rc != 0)); then
17481                 error "ofd_access_log_reader exited with rc = '${rc}'"
17482         fi
17483 }
17484 run_test 165d "ofd_access_log mask works"
17485
17486 test_165e() {
17487         local stats="/tmp/${tfile}.stats"
17488         local file0="${DIR}/${tdir}-0/${tfile}"
17489         local file1="${DIR}/${tdir}-1/${tfile}"
17490
17491         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
17492                 skip "OFD access log unsupported"
17493
17494         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
17495
17496         test_mkdir -c 1 -i 0 "${DIR}/${tdir}-0"
17497         test_mkdir -c 1 -i 1 "${DIR}/${tdir}-1"
17498
17499         lfs setstripe -c 1 -i 0 "${file0}"
17500         lfs setstripe -c 1 -i 0 "${file1}"
17501
17502         setup_165
17503         do_facet ost1 ofd_access_log_reader -I 1 --stats="${stats}" &
17504         sleep 5
17505
17506         $MULTIOP "${file0}" oO_CREAT:O_WRONLY:w512c ||
17507                 error "cannot create '${file0}'"
17508         sync
17509         oal_expect_read_count "${stats}" 0
17510
17511         $MULTIOP "${file1}" oO_CREAT:O_WRONLY:w512c ||
17512                 error "cannot create '${file1}'"
17513         sync
17514         oal_expect_read_count "${stats}" 1
17515
17516         do_facet ost1 killall -TERM ofd_access_log_reader
17517         wait
17518         rc=$?
17519         if ((rc != 0)); then
17520                 error "ofd_access_log_reader exited with rc = '${rc}'"
17521         fi
17522 }
17523 run_test 165e "ofd_access_log MDT index filter works"
17524
17525 test_165f() {
17526         local trace="/tmp/${tfile}.trace"
17527         local rc
17528         local count
17529
17530         setup_165
17531         do_facet ost1 timeout 60 ofd_access_log_reader \
17532                 --exit-on-close --debug=- --trace=- > "${trace}" &
17533         sleep 5
17534         stop ost1
17535
17536         wait
17537         rc=$?
17538
17539         if ((rc != 0)); then
17540                 error_noexit "ofd_access_log_reader exited with rc = '${rc}'"
17541                 cat "${trace}"
17542                 exit 1
17543         fi
17544 }
17545 run_test 165f "ofd_access_log_reader --exit-on-close works"
17546
17547 test_169() {
17548         # do directio so as not to populate the page cache
17549         log "creating a 10 Mb file"
17550         $MULTIOP $DIR/$tfile oO_CREAT:O_DIRECT:O_RDWR:w$((10*1048576))c ||
17551                 error "multiop failed while creating a file"
17552         log "starting reads"
17553         dd if=$DIR/$tfile of=/dev/null bs=4096 &
17554         log "truncating the file"
17555         $MULTIOP $DIR/$tfile oO_TRUNC:c ||
17556                 error "multiop failed while truncating the file"
17557         log "killing dd"
17558         kill %+ || true # reads might have finished
17559         echo "wait until dd is finished"
17560         wait
17561         log "removing the temporary file"
17562         rm -rf $DIR/$tfile || error "tmp file removal failed"
17563 }
17564 run_test 169 "parallel read and truncate should not deadlock"
17565
17566 test_170() {
17567         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17568
17569         $LCTL clear     # bug 18514
17570         $LCTL debug_daemon start $TMP/${tfile}_log_good
17571         touch $DIR/$tfile
17572         $LCTL debug_daemon stop
17573         sed -e "s/^...../a/g" $TMP/${tfile}_log_good > $TMP/${tfile}_log_bad ||
17574                 error "sed failed to read log_good"
17575
17576         $LCTL debug_daemon start $TMP/${tfile}_log_good
17577         rm -rf $DIR/$tfile
17578         $LCTL debug_daemon stop
17579
17580         $LCTL df $TMP/${tfile}_log_bad > $TMP/${tfile}_log_bad.out 2>&1 ||
17581                error "lctl df log_bad failed"
17582
17583         local bad_line=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $9}')
17584         local good_line1=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $5}')
17585
17586         $LCTL df $TMP/${tfile}_log_good > $TMP/${tfile}_log_good.out 2>&1
17587         local good_line2=$(tail -n 1 $TMP/${tfile}_log_good.out | awk '{print $5}')
17588
17589         [ "$bad_line" ] && [ "$good_line1" ] && [ "$good_line2" ] ||
17590                 error "bad_line good_line1 good_line2 are empty"
17591
17592         cat $TMP/${tfile}_log_good >> $TMP/${tfile}_logs_corrupt
17593         cat $TMP/${tfile}_log_bad >> $TMP/${tfile}_logs_corrupt
17594         cat $TMP/${tfile}_log_good >> $TMP/${tfile}_logs_corrupt
17595
17596         $LCTL df $TMP/${tfile}_logs_corrupt > $TMP/${tfile}_log_bad.out 2>&1
17597         local bad_line_new=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $9}')
17598         local good_line_new=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $5}')
17599
17600         [ "$bad_line_new" ] && [ "$good_line_new" ] ||
17601                 error "bad_line_new good_line_new are empty"
17602
17603         local expected_good=$((good_line1 + good_line2*2))
17604
17605         rm -f $TMP/${tfile}*
17606         # LU-231, short malformed line may not be counted into bad lines
17607         if [ $bad_line -ne $bad_line_new ] &&
17608                    [ $bad_line -ne $((bad_line_new - 1)) ]; then
17609                 error "expected $bad_line bad lines, but got $bad_line_new"
17610                 return 1
17611         fi
17612
17613         if [ $expected_good -ne $good_line_new ]; then
17614                 error "expected $expected_good good lines, but got $good_line_new"
17615                 return 2
17616         fi
17617         true
17618 }
17619 run_test 170 "test lctl df to handle corrupted log ====================="
17620
17621 test_171() { # bug20592
17622         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17623
17624         #define OBD_FAIL_PTLRPC_DUMP_LOG         0x50e
17625         $LCTL set_param fail_loc=0x50e
17626         $LCTL set_param fail_val=3000
17627         multiop_bg_pause $DIR/$tfile O_s || true
17628         local MULTIPID=$!
17629         kill -USR1 $MULTIPID
17630         # cause log dump
17631         sleep 3
17632         wait $MULTIPID
17633         if dmesg | grep "recursive fault"; then
17634                 error "caught a recursive fault"
17635         fi
17636         $LCTL set_param fail_loc=0
17637         true
17638 }
17639 run_test 171 "test libcfs_debug_dumplog_thread stuck in do_exit() ======"
17640
17641 # it would be good to share it with obdfilter-survey/iokit-libecho code
17642 setup_obdecho_osc () {
17643         local rc=0
17644         local ost_nid=$1
17645         local obdfilter_name=$2
17646         echo "Creating new osc for $obdfilter_name on $ost_nid"
17647         # make sure we can find loopback nid
17648         $LCTL add_uuid $ost_nid $ost_nid >/dev/null 2>&1
17649
17650         [ $rc -eq 0 ] && { $LCTL attach osc ${obdfilter_name}_osc     \
17651                            ${obdfilter_name}_osc_UUID || rc=2; }
17652         [ $rc -eq 0 ] && { $LCTL --device ${obdfilter_name}_osc setup \
17653                            ${obdfilter_name}_UUID  $ost_nid || rc=3; }
17654         return $rc
17655 }
17656
17657 cleanup_obdecho_osc () {
17658         local obdfilter_name=$1
17659         $LCTL --device ${obdfilter_name}_osc cleanup >/dev/null
17660         $LCTL --device ${obdfilter_name}_osc detach  >/dev/null
17661         return 0
17662 }
17663
17664 obdecho_test() {
17665         local OBD=$1
17666         local node=$2
17667         local pages=${3:-64}
17668         local rc=0
17669         local id
17670
17671         local count=10
17672         local obd_size=$(get_obd_size $node $OBD)
17673         local page_size=$(get_page_size $node)
17674         if [[ -n "$obd_size" ]]; then
17675                 local new_count=$((obd_size / (pages * page_size / 1024)))
17676                 [[ $new_count -ge $count ]] || count=$new_count
17677         fi
17678
17679         do_facet $node "$LCTL attach echo_client ec ec_uuid" || rc=1
17680         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec setup $OBD" ||
17681                            rc=2; }
17682         if [ $rc -eq 0 ]; then
17683             id=$(do_facet $node "$LCTL --device ec create 1"  | awk '/object id/ {print $6}')
17684             [ ${PIPESTATUS[0]} -eq 0 -a -n "$id" ] || rc=3
17685         fi
17686         echo "New object id is $id"
17687         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec getattr $id" ||
17688                            rc=4; }
17689         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec "                 \
17690                            "test_brw $count w v $pages $id" || rc=4; }
17691         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec destroy $id 1" ||
17692                            rc=4; }
17693         [ $rc -eq 0 ] || [ $rc -gt 2 ] &&
17694                 { do_facet $node "$LCTL --device ec cleanup" || rc=5; }
17695         [ $rc -eq 0 ] || [ $rc -gt 1 ] &&
17696                 { do_facet $node "$LCTL --device ec detach" || rc=6; }
17697         [ $rc -ne 0 ] && echo "obecho_create_test failed: $rc"
17698         return $rc
17699 }
17700
17701 test_180a() {
17702         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17703
17704         if ! [ -d /sys/fs/lustre/echo_client ] &&
17705            ! module_loaded obdecho; then
17706                 load_module obdecho/obdecho &&
17707                         stack_trap "rmmod obdecho" EXIT ||
17708                         error "unable to load obdecho on client"
17709         fi
17710
17711         local osc=$($LCTL dl | grep -v mdt | awk '$3 == "osc" {print $4; exit}')
17712         local host=$($LCTL get_param -n osc.$osc.import |
17713                      awk '/current_connection:/ { print $2 }' )
17714         local target=$($LCTL get_param -n osc.$osc.import |
17715                        awk '/target:/ { print $2 }' )
17716         target=${target%_UUID}
17717
17718         if [ -n "$target" ]; then
17719                 setup_obdecho_osc $host $target &&
17720                         stack_trap "cleanup_obdecho_osc $target" EXIT ||
17721                         { error "obdecho setup failed with $?"; return; }
17722
17723                 obdecho_test ${target}_osc client ||
17724                         error "obdecho_test failed on ${target}_osc"
17725         else
17726                 $LCTL get_param osc.$osc.import
17727                 error "there is no osc.$osc.import target"
17728         fi
17729 }
17730 run_test 180a "test obdecho on osc"
17731
17732 test_180b() {
17733         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17734         remote_ost_nodsh && skip "remote OST with nodsh"
17735
17736         do_rpc_nodes $(facet_active_host ost1) load_module obdecho/obdecho &&
17737                 stack_trap "do_facet ost1 rmmod obdecho" EXIT ||
17738                 error "failed to load module obdecho"
17739
17740         local target=$(do_facet ost1 $LCTL dl |
17741                        awk '/obdfilter/ { print $4; exit; }')
17742
17743         if [ -n "$target" ]; then
17744                 obdecho_test $target ost1 || error "obdecho_test failed with $?"
17745         else
17746                 do_facet ost1 $LCTL dl
17747                 error "there is no obdfilter target on ost1"
17748         fi
17749 }
17750 run_test 180b "test obdecho directly on obdfilter"
17751
17752 test_180c() { # LU-2598
17753         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17754         remote_ost_nodsh && skip "remote OST with nodsh"
17755         [[ $MDS1_VERSION -lt $(version_code 2.4.0) ]] &&
17756                 skip "Need MDS version at least 2.4.0"
17757
17758         do_rpc_nodes $(facet_active_host ost1) load_module obdecho/obdecho &&
17759                 stack_trap "do_facet ost1 rmmod obdecho" EXIT ||
17760                 error "failed to load module obdecho"
17761
17762         local target=$(do_facet ost1 $LCTL dl |
17763                        awk '/obdfilter/ { print $4; exit; }')
17764
17765         if [ -n "$target" ]; then
17766                 local pages=16384 # 64MB bulk I/O RPC size
17767
17768                 obdecho_test "$target" ost1 "$pages" ||
17769                         error "obdecho_test with pages=$pages failed with $?"
17770         else
17771                 do_facet ost1 $LCTL dl
17772                 error "there is no obdfilter target on ost1"
17773         fi
17774 }
17775 run_test 180c "test huge bulk I/O size on obdfilter, don't LASSERT"
17776
17777 test_181() { # bug 22177
17778         test_mkdir $DIR/$tdir
17779         # create enough files to index the directory
17780         createmany -o $DIR/$tdir/foobar 4000
17781         # print attributes for debug purpose
17782         lsattr -d .
17783         # open dir
17784         multiop_bg_pause $DIR/$tdir D_Sc || return 1
17785         MULTIPID=$!
17786         # remove the files & current working dir
17787         unlinkmany $DIR/$tdir/foobar 4000
17788         rmdir $DIR/$tdir
17789         kill -USR1 $MULTIPID
17790         wait $MULTIPID
17791         stat $DIR/$tdir && error "open-unlinked dir was not removed!"
17792         return 0
17793 }
17794 run_test 181 "Test open-unlinked dir ========================"
17795
17796 test_182() {
17797         local fcount=1000
17798         local tcount=10
17799
17800         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
17801
17802         $LCTL set_param mdc.*.rpc_stats=clear
17803
17804         for (( i = 0; i < $tcount; i++ )) ; do
17805                 mkdir $DIR/$tdir/$i
17806         done
17807
17808         for (( i = 0; i < $tcount; i++ )) ; do
17809                 createmany -o $DIR/$tdir/$i/f- $fcount &
17810         done
17811         wait
17812
17813         for (( i = 0; i < $tcount; i++ )) ; do
17814                 unlinkmany $DIR/$tdir/$i/f- $fcount &
17815         done
17816         wait
17817
17818         $LCTL get_param mdc.*.rpc_stats
17819
17820         rm -rf $DIR/$tdir
17821 }
17822 run_test 182 "Test parallel modify metadata operations ================"
17823
17824 test_183() { # LU-2275
17825         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17826         remote_mds_nodsh && skip "remote MDS with nodsh"
17827         [[ $MDS1_VERSION -lt $(version_code 2.3.56) ]] &&
17828                 skip "Need MDS version at least 2.3.56"
17829
17830         mkdir_on_mdt0 $DIR/$tdir || error "creating dir $DIR/$tdir"
17831         echo aaa > $DIR/$tdir/$tfile
17832
17833 #define OBD_FAIL_MDS_NEGATIVE_POSITIVE  0x148
17834         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x148
17835
17836         ls -l $DIR/$tdir && error "ls succeeded, should have failed"
17837         cat $DIR/$tdir/$tfile && error "cat succeeded, should have failed"
17838
17839         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
17840
17841         # Flush negative dentry cache
17842         touch $DIR/$tdir/$tfile
17843
17844         # We are not checking for any leaked references here, they'll
17845         # become evident next time we do cleanup with module unload.
17846         rm -rf $DIR/$tdir
17847 }
17848 run_test 183 "No crash or request leak in case of strange dispositions ========"
17849
17850 # test suite 184 is for LU-2016, LU-2017
17851 test_184a() {
17852         check_swap_layouts_support
17853
17854         dir0=$DIR/$tdir/$testnum
17855         test_mkdir -p -c1 $dir0
17856         ref1=/etc/passwd
17857         ref2=/etc/group
17858         file1=$dir0/f1
17859         file2=$dir0/f2
17860         $LFS setstripe -c1 $file1
17861         cp $ref1 $file1
17862         $LFS setstripe -c2 $file2
17863         cp $ref2 $file2
17864         gen1=$($LFS getstripe -g $file1)
17865         gen2=$($LFS getstripe -g $file2)
17866
17867         $LFS swap_layouts $file1 $file2 || error "swap of file layout failed"
17868         gen=$($LFS getstripe -g $file1)
17869         [[ $gen1 != $gen ]] ||
17870                 error "Layout generation on $file1 does not change"
17871         gen=$($LFS getstripe -g $file2)
17872         [[ $gen2 != $gen ]] ||
17873                 error "Layout generation on $file2 does not change"
17874
17875         cmp $ref1 $file2 || error "content compare failed ($ref1 != $file2)"
17876         cmp $ref2 $file1 || error "content compare failed ($ref2 != $file1)"
17877
17878         lfsck_verify_pfid $file1 $file2 || error "PFID are not transferred"
17879 }
17880 run_test 184a "Basic layout swap"
17881
17882 test_184b() {
17883         check_swap_layouts_support
17884
17885         dir0=$DIR/$tdir/$testnum
17886         mkdir -p $dir0 || error "creating dir $dir0"
17887         file1=$dir0/f1
17888         file2=$dir0/f2
17889         file3=$dir0/f3
17890         dir1=$dir0/d1
17891         dir2=$dir0/d2
17892         mkdir $dir1 $dir2
17893         $LFS setstripe -c1 $file1
17894         $LFS setstripe -c2 $file2
17895         $LFS setstripe -c1 $file3
17896         chown $RUNAS_ID $file3
17897         gen1=$($LFS getstripe -g $file1)
17898         gen2=$($LFS getstripe -g $file2)
17899
17900         $LFS swap_layouts $dir1 $dir2 &&
17901                 error "swap of directories layouts should fail"
17902         $LFS swap_layouts $dir1 $file1 &&
17903                 error "swap of directory and file layouts should fail"
17904         $RUNAS $LFS swap_layouts $file1 $file2 &&
17905                 error "swap of file we cannot write should fail"
17906         $LFS swap_layouts $file1 $file3 &&
17907                 error "swap of file with different owner should fail"
17908         /bin/true # to clear error code
17909 }
17910 run_test 184b "Forbidden layout swap (will generate errors)"
17911
17912 test_184c() {
17913         local cmpn_arg=$(cmp -n 2>&1 | grep "invalid option")
17914         [ -n "$cmpn_arg" ] && skip_env "cmp does not support -n"
17915         check_swap_layouts_support
17916         check_swap_layout_no_dom $DIR
17917
17918         local dir0=$DIR/$tdir/$testnum
17919         mkdir -p $dir0 || error "creating dir $dir0"
17920
17921         local ref1=$dir0/ref1
17922         local ref2=$dir0/ref2
17923         local file1=$dir0/file1
17924         local file2=$dir0/file2
17925         # create a file large enough for the concurrent test
17926         dd if=/dev/urandom of=$ref1 bs=1M count=$((RANDOM % 50 + 20))
17927         dd if=/dev/urandom of=$ref2 bs=1M count=$((RANDOM % 50 + 20))
17928         echo "ref file size: ref1($(stat -c %s $ref1))," \
17929              "ref2($(stat -c %s $ref2))"
17930
17931         cp $ref2 $file2
17932         dd if=$ref1 of=$file1 bs=16k &
17933         local DD_PID=$!
17934
17935         # Make sure dd starts to copy file, but wait at most 5 seconds
17936         local loops=0
17937         while [ ! -s $file1 -a $((loops++)) -lt 50 ]; do sleep 0.1; done
17938
17939         $LFS swap_layouts $file1 $file2
17940         local rc=$?
17941         wait $DD_PID
17942         [[ $? == 0 ]] || error "concurrent write on $file1 failed"
17943         [[ $rc == 0 ]] || error "swap of $file1 and $file2 failed"
17944
17945         # how many bytes copied before swapping layout
17946         local copied=$(stat -c %s $file2)
17947         local remaining=$(stat -c %s $ref1)
17948         remaining=$((remaining - copied))
17949         echo "Copied $copied bytes before swapping layout..."
17950
17951         cmp -n $copied $file1 $ref2 | grep differ &&
17952                 error "Content mismatch [0, $copied) of ref2 and file1"
17953         cmp -n $copied $file2 $ref1 ||
17954                 error "Content mismatch [0, $copied) of ref1 and file2"
17955         cmp -i $copied:$copied -n $remaining $file1 $ref1 ||
17956                 error "Content mismatch [$copied, EOF) of ref1 and file1"
17957
17958         # clean up
17959         rm -f $ref1 $ref2 $file1 $file2
17960 }
17961 run_test 184c "Concurrent write and layout swap"
17962
17963 test_184d() {
17964         check_swap_layouts_support
17965         check_swap_layout_no_dom $DIR
17966         [ -z "$(which getfattr 2>/dev/null)" ] &&
17967                 skip_env "no getfattr command"
17968
17969         local file1=$DIR/$tdir/$tfile-1
17970         local file2=$DIR/$tdir/$tfile-2
17971         local file3=$DIR/$tdir/$tfile-3
17972         local lovea1
17973         local lovea2
17974
17975         mkdir -p $DIR/$tdir
17976         touch $file1 || error "create $file1 failed"
17977         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file2 ||
17978                 error "create $file2 failed"
17979         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file3 ||
17980                 error "create $file3 failed"
17981         lovea1=$(get_layout_param $file1)
17982
17983         $LFS swap_layouts $file2 $file3 ||
17984                 error "swap $file2 $file3 layouts failed"
17985         $LFS swap_layouts $file1 $file2 ||
17986                 error "swap $file1 $file2 layouts failed"
17987
17988         lovea2=$(get_layout_param $file2)
17989         echo "$lovea1"
17990         echo "$lovea2"
17991         [ "$lovea1" == "$lovea2" ] || error "lovea $lovea1 != $lovea2"
17992
17993         lovea1=$(getfattr -n trusted.lov $file1 | grep ^trusted)
17994         [[ -z "$lovea1" ]] || error "$file1 shouldn't have lovea"
17995 }
17996 run_test 184d "allow stripeless layouts swap"
17997
17998 test_184e() {
17999         [[ $MDS1_VERSION -ge $(version_code 2.6.94) ]] ||
18000                 skip "Need MDS version at least 2.6.94"
18001         check_swap_layouts_support
18002         check_swap_layout_no_dom $DIR
18003         [ -z "$(which getfattr 2>/dev/null)" ] &&
18004                 skip_env "no getfattr command"
18005
18006         local file1=$DIR/$tdir/$tfile-1
18007         local file2=$DIR/$tdir/$tfile-2
18008         local file3=$DIR/$tdir/$tfile-3
18009         local lovea
18010
18011         mkdir -p $DIR/$tdir
18012         touch $file1 || error "create $file1 failed"
18013         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file2 ||
18014                 error "create $file2 failed"
18015         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file3 ||
18016                 error "create $file3 failed"
18017
18018         $LFS swap_layouts $file1 $file2 ||
18019                 error "swap $file1 $file2 layouts failed"
18020
18021         lovea=$(getfattr -n trusted.lov $file1 | grep ^trusted)
18022         [[ -z "$lovea" ]] || error "$file1 shouldn't have lovea"
18023
18024         echo 123 > $file1 || error "Should be able to write into $file1"
18025
18026         $LFS swap_layouts $file1 $file3 ||
18027                 error "swap $file1 $file3 layouts failed"
18028
18029         echo 123 > $file1 || error "Should be able to write into $file1"
18030
18031         rm -rf $file1 $file2 $file3
18032 }
18033 run_test 184e "Recreate layout after stripeless layout swaps"
18034
18035 test_184f() {
18036         # Create a file with name longer than sizeof(struct stat) ==
18037         # 144 to see if we can get chars from the file name to appear
18038         # in the returned striping. Note that 'f' == 0x66.
18039         local file=$(for ((i = 0; i < 200; i++)); do echo -n f; done)
18040
18041         mkdir -p $DIR/$tdir
18042         mcreate $DIR/$tdir/$file
18043         if lfs find --stripe-count 0x6666 $DIR/$tdir | grep $file; then
18044                 error "IOC_MDC_GETFILEINFO returned garbage striping"
18045         fi
18046 }
18047 run_test 184f "IOC_MDC_GETFILEINFO for files with long names but no striping"
18048
18049 test_185() { # LU-2441
18050         # LU-3553 - no volatile file support in old servers
18051         [[ $MDS1_VERSION -ge $(version_code 2.3.60) ]] ||
18052                 skip "Need MDS version at least 2.3.60"
18053
18054         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
18055         touch $DIR/$tdir/spoo
18056         local mtime1=$(stat -c "%Y" $DIR/$tdir)
18057         local fid=$($MULTIOP $DIR/$tdir VFw4096c) ||
18058                 error "cannot create/write a volatile file"
18059         [ "$FILESET" == "" ] &&
18060         $CHECKSTAT -t file $MOUNT/.lustre/fid/$fid 2>/dev/null &&
18061                 error "FID is still valid after close"
18062
18063         multiop_bg_pause $DIR/$tdir vVw4096_c
18064         local multi_pid=$!
18065
18066         local OLD_IFS=$IFS
18067         IFS=":"
18068         local fidv=($fid)
18069         IFS=$OLD_IFS
18070         # assume that the next FID for this client is sequential, since stdout
18071         # is unfortunately eaten by multiop_bg_pause
18072         local n=$((${fidv[1]} + 1))
18073         local next_fid="${fidv[0]}:$(printf "0x%x" $n):${fidv[2]}"
18074         if [ "$FILESET" == "" ]; then
18075                 $CHECKSTAT -t file $MOUNT/.lustre/fid/$next_fid ||
18076                         error "FID is missing before close"
18077         fi
18078         kill -USR1 $multi_pid
18079         # 1 second delay, so if mtime change we will see it
18080         sleep 1
18081         local mtime2=$(stat -c "%Y" $DIR/$tdir)
18082         [[ $mtime1 == $mtime2 ]] || error "mtime has changed"
18083 }
18084 run_test 185 "Volatile file support"
18085
18086 function create_check_volatile() {
18087         local idx=$1
18088         local tgt
18089
18090         $MULTIOP $MOUNT/.lustre/fid V${idx}Fw4096_c >&/tmp/${tfile}.fid &
18091         local PID=$!
18092         sleep 1
18093         local FID=$(cat /tmp/${tfile}.fid)
18094         [ "$FID" == "" ] && error "can't get FID for volatile"
18095         $CHECKSTAT -t file $MOUNT/.lustre/fid/$FID || error "can't stat $FID"
18096         tgt=$($LFS getstripe -m $MOUNT/.lustre/fid/$FID)
18097         [ "$tgt" != "$idx" ] && error "wrong MDS $tgt, expected $idx"
18098         kill -USR1 $PID
18099         wait
18100         sleep 1
18101         cancel_lru_locks mdc # flush opencache
18102         $CHECKSTAT -t file $MOUNT/.lustre/fid/$FID && error "can stat $FID"
18103         return 0
18104 }
18105
18106 test_185a(){
18107         # LU-12516 - volatile creation via .lustre
18108         [[ $MDS1_VERSION -ge $(version_code 2.12.55) ]] ||
18109                 skip "Need MDS version at least 2.3.55"
18110
18111         create_check_volatile 0
18112         [ $MDSCOUNT -lt 2 ] && return 0
18113
18114         # DNE case
18115         create_check_volatile 1
18116
18117         return 0
18118 }
18119 run_test 185a "Volatile file creation in .lustre/fid/"
18120
18121 test_187a() {
18122         remote_mds_nodsh && skip "remote MDS with nodsh"
18123         [ $MDS1_VERSION -lt $(version_code 2.3.0) ] &&
18124                 skip "Need MDS version at least 2.3.0"
18125
18126         local dir0=$DIR/$tdir/$testnum
18127         mkdir -p $dir0 || error "creating dir $dir0"
18128
18129         local file=$dir0/file1
18130         dd if=/dev/urandom of=$file count=10 bs=1M conv=fsync
18131         local dv1=$($LFS data_version $file)
18132         dd if=/dev/urandom of=$file seek=10 count=1 bs=1M conv=fsync
18133         local dv2=$($LFS data_version $file)
18134         [[ $dv1 != $dv2 ]] ||
18135                 error "data version did not change on write $dv1 == $dv2"
18136
18137         # clean up
18138         rm -f $file1
18139 }
18140 run_test 187a "Test data version change"
18141
18142 test_187b() {
18143         remote_mds_nodsh && skip "remote MDS with nodsh"
18144         [ $MDS1_VERSION -lt $(version_code 2.3.0) ] &&
18145                 skip "Need MDS version at least 2.3.0"
18146
18147         local dir0=$DIR/$tdir/$testnum
18148         mkdir -p $dir0 || error "creating dir $dir0"
18149
18150         declare -a DV=$($MULTIOP $dir0 Vw1000xYw1000xY | cut -f3 -d" ")
18151         [[ ${DV[0]} != ${DV[1]} ]] ||
18152                 error "data version did not change on write"\
18153                       " ${DV[0]} == ${DV[1]}"
18154
18155         # clean up
18156         rm -f $file1
18157 }
18158 run_test 187b "Test data version change on volatile file"
18159
18160 test_200() {
18161         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18162         remote_mgs_nodsh && skip "remote MGS with nodsh"
18163         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
18164
18165         local POOL=${POOL:-cea1}
18166         local POOL_ROOT=${POOL_ROOT:-$DIR/d200.pools}
18167         local POOL_DIR_NAME=${POOL_DIR_NAME:-dir_tst}
18168         # Pool OST targets
18169         local first_ost=0
18170         local last_ost=$(($OSTCOUNT - 1))
18171         local ost_step=2
18172         local ost_list=$(seq $first_ost $ost_step $last_ost)
18173         local ost_range="$first_ost $last_ost $ost_step"
18174         local test_path=$POOL_ROOT/$POOL_DIR_NAME
18175         local file_dir=$POOL_ROOT/file_tst
18176         local subdir=$test_path/subdir
18177         local rc=0
18178
18179         while : ; do
18180                 # former test_200a test_200b
18181                 pool_add $POOL                          || { rc=$? ; break; }
18182                 pool_add_targets  $POOL $ost_range      || { rc=$? ; break; }
18183                 # former test_200c test_200d
18184                 mkdir -p $test_path
18185                 pool_set_dir      $POOL $test_path      || { rc=$? ; break; }
18186                 pool_check_dir    $POOL $test_path      || { rc=$? ; break; }
18187                 mkdir -p $subdir
18188                 pool_check_dir    $POOL $subdir         || { rc=$? ; break; }
18189                 pool_dir_rel_path $POOL $POOL_DIR_NAME $POOL_ROOT \
18190                                                         || { rc=$? ; break; }
18191                 # former test_200e test_200f
18192                 local files=$((OSTCOUNT*3))
18193                 pool_alloc_files  $POOL $test_path $files "$ost_list" \
18194                                                         || { rc=$? ; break; }
18195                 pool_create_files $POOL $file_dir $files "$ost_list" \
18196                                                         || { rc=$? ; break; }
18197                 # former test_200g test_200h
18198                 pool_lfs_df $POOL                       || { rc=$? ; break; }
18199                 pool_file_rel_path $POOL $test_path     || { rc=$? ; break; }
18200
18201                 # former test_201a test_201b test_201c
18202                 pool_remove_first_target $POOL          || { rc=$? ; break; }
18203
18204                 local f=$test_path/$tfile
18205                 pool_remove_all_targets $POOL $f        || { rc=$? ; break; }
18206                 pool_remove $POOL $f                    || { rc=$? ; break; }
18207                 break
18208         done
18209
18210         destroy_test_pools
18211
18212         return $rc
18213 }
18214 run_test 200 "OST pools"
18215
18216 # usage: default_attr <count | size | offset>
18217 default_attr() {
18218         $LCTL get_param -n lov.$FSNAME-clilov-\*.stripe${1}
18219 }
18220
18221 # usage: check_default_stripe_attr
18222 check_default_stripe_attr() {
18223         ACTUAL=$($LFS getstripe $* $DIR/$tdir)
18224         case $1 in
18225         --stripe-count|-c)
18226                 [ -n "$2" ] && EXPECTED=0 || EXPECTED=$(default_attr count);;
18227         --stripe-size|-S)
18228                 [ -n "$2" ] && EXPECTED=0 || EXPECTED=$(default_attr size);;
18229         --stripe-index|-i)
18230                 EXPECTED=-1;;
18231         *)
18232                 error "unknown getstripe attr '$1'"
18233         esac
18234
18235         [ $ACTUAL == $EXPECTED ] ||
18236                 error "$DIR/$tdir has $1 '$ACTUAL', not '$EXPECTED'"
18237 }
18238
18239 test_204a() {
18240         test_mkdir $DIR/$tdir
18241         $LFS setstripe --stripe-count 0 --stripe-size 0 --stripe-index -1 $DIR/$tdir
18242
18243         check_default_stripe_attr --stripe-count
18244         check_default_stripe_attr --stripe-size
18245         check_default_stripe_attr --stripe-index
18246 }
18247 run_test 204a "Print default stripe attributes"
18248
18249 test_204b() {
18250         test_mkdir $DIR/$tdir
18251         $LFS setstripe --stripe-count 1 $DIR/$tdir
18252
18253         check_default_stripe_attr --stripe-size
18254         check_default_stripe_attr --stripe-index
18255 }
18256 run_test 204b "Print default stripe size and offset"
18257
18258 test_204c() {
18259         test_mkdir $DIR/$tdir
18260         $LFS setstripe --stripe-size 65536 $DIR/$tdir
18261
18262         check_default_stripe_attr --stripe-count
18263         check_default_stripe_attr --stripe-index
18264 }
18265 run_test 204c "Print default stripe count and offset"
18266
18267 test_204d() {
18268         test_mkdir $DIR/$tdir
18269         $LFS setstripe --stripe-index 0 $DIR/$tdir
18270
18271         check_default_stripe_attr --stripe-count
18272         check_default_stripe_attr --stripe-size
18273 }
18274 run_test 204d "Print default stripe count and size"
18275
18276 test_204e() {
18277         test_mkdir $DIR/$tdir
18278         $LFS setstripe -d $DIR/$tdir
18279
18280         check_default_stripe_attr --stripe-count --raw
18281         check_default_stripe_attr --stripe-size --raw
18282         check_default_stripe_attr --stripe-index --raw
18283 }
18284 run_test 204e "Print raw stripe attributes"
18285
18286 test_204f() {
18287         test_mkdir $DIR/$tdir
18288         $LFS setstripe --stripe-count 1 $DIR/$tdir
18289
18290         check_default_stripe_attr --stripe-size --raw
18291         check_default_stripe_attr --stripe-index --raw
18292 }
18293 run_test 204f "Print raw stripe size and offset"
18294
18295 test_204g() {
18296         test_mkdir $DIR/$tdir
18297         $LFS setstripe --stripe-size 65536 $DIR/$tdir
18298
18299         check_default_stripe_attr --stripe-count --raw
18300         check_default_stripe_attr --stripe-index --raw
18301 }
18302 run_test 204g "Print raw stripe count and offset"
18303
18304 test_204h() {
18305         test_mkdir $DIR/$tdir
18306         $LFS setstripe --stripe-index 0 $DIR/$tdir
18307
18308         check_default_stripe_attr --stripe-count --raw
18309         check_default_stripe_attr --stripe-size --raw
18310 }
18311 run_test 204h "Print raw stripe count and size"
18312
18313 # Figure out which job scheduler is being used, if any,
18314 # or use a fake one
18315 if [ -n "$SLURM_JOB_ID" ]; then # SLURM
18316         JOBENV=SLURM_JOB_ID
18317 elif [ -n "$LSB_JOBID" ]; then # Load Sharing Facility
18318         JOBENV=LSB_JOBID
18319 elif [ -n "$PBS_JOBID" ]; then # PBS/Maui/Moab
18320         JOBENV=PBS_JOBID
18321 elif [ -n "$LOADL_STEPID" ]; then # LoadLeveller
18322         JOBENV=LOADL_STEP_ID
18323 elif [ -n "$JOB_ID" ]; then # Sun Grid Engine
18324         JOBENV=JOB_ID
18325 else
18326         $LCTL list_param jobid_name > /dev/null 2>&1
18327         if [ $? -eq 0 ]; then
18328                 JOBENV=nodelocal
18329         else
18330                 JOBENV=FAKE_JOBID
18331         fi
18332 fi
18333 LUSTRE_JOBID_SIZE=31 # plus NUL terminator
18334
18335 verify_jobstats() {
18336         local cmd=($1)
18337         shift
18338         local facets="$@"
18339
18340 # we don't really need to clear the stats for this test to work, since each
18341 # command has a unique jobid, but it makes debugging easier if needed.
18342 #       for facet in $facets; do
18343 #               local dev=$(convert_facet2label $facet)
18344 #               # clear old jobstats
18345 #               do_facet $facet lctl set_param *.$dev.job_stats="clear"
18346 #       done
18347
18348         # use a new JobID for each test, or we might see an old one
18349         [ "$JOBENV" = "FAKE_JOBID" ] &&
18350                 FAKE_JOBID=id.$testnum.$(basename ${cmd[0]}).$RANDOM
18351
18352         JOBVAL=${!JOBENV:0:$LUSTRE_JOBID_SIZE}
18353
18354         [ "$JOBENV" = "nodelocal" ] && {
18355                 FAKE_JOBID=id.$testnum.%e.$RANDOM
18356                 $LCTL set_param jobid_name=$FAKE_JOBID
18357                 JOBVAL=${FAKE_JOBID/\%e/$(basename ${cmd[0]})}
18358         }
18359
18360         log "Test: ${cmd[*]}"
18361         log "Using JobID environment $($LCTL get_param -n jobid_var)=$JOBVAL"
18362
18363         if [ $JOBENV = "FAKE_JOBID" ]; then
18364                 FAKE_JOBID=$JOBVAL ${cmd[*]}
18365         else
18366                 ${cmd[*]}
18367         fi
18368
18369         # all files are created on OST0000
18370         for facet in $facets; do
18371                 local stats="*.$(convert_facet2label $facet).job_stats"
18372
18373                 # strip out libtool wrappers for in-tree executables
18374                 if (( $(do_facet $facet lctl get_param $stats |
18375                         sed -e 's/\.lt-/./' | grep -cw $JOBVAL) != 1 )); then
18376                         do_facet $facet lctl get_param $stats
18377                         error "No jobstats for $JOBVAL found on $facet::$stats"
18378                 fi
18379         done
18380 }
18381
18382 jobstats_set() {
18383         local new_jobenv=$1
18384
18385         set_persistent_param_and_check client "jobid_var" \
18386                 "$FSNAME.sys.jobid_var" $new_jobenv
18387 }
18388
18389 test_205a() { # Job stats
18390         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18391         [[ $MDS1_VERSION -ge $(version_code 2.7.1) ]] ||
18392                 skip "Need MDS version with at least 2.7.1"
18393         remote_mgs_nodsh && skip "remote MGS with nodsh"
18394         remote_mds_nodsh && skip "remote MDS with nodsh"
18395         remote_ost_nodsh && skip "remote OST with nodsh"
18396         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep jobstats)" ] &&
18397                 skip "Server doesn't support jobstats"
18398         [[ $JOBID_VAR = disable ]] && skip_env "jobstats is disabled"
18399
18400         local old_jobenv=$($LCTL get_param -n jobid_var)
18401         [ $old_jobenv != $JOBENV ] && jobstats_set $JOBENV
18402
18403         if [[ $PERM_CMD == *"set_param -P"* ]]; then
18404                 stack_trap "do_facet mgs $PERM_CMD jobid_var=$old_jobenv" EXIT
18405         else
18406                 stack_trap "do_facet mgs $PERM_CMD \
18407                         $FSNAME.sys.jobid_var=$old_jobenv" EXIT
18408         fi
18409         changelog_register
18410
18411         local old_interval=$(do_facet $SINGLEMDS lctl get_param -n \
18412                                 mdt.*.job_cleanup_interval | head -n 1)
18413         local new_interval=5
18414         do_facet $SINGLEMDS \
18415                 $LCTL set_param mdt.*.job_cleanup_interval=$new_interval
18416         stack_trap "do_facet $SINGLEMDS \
18417                 $LCTL set_param mdt.*.job_cleanup_interval=$old_interval" EXIT
18418         local start=$SECONDS
18419
18420         local cmd
18421         # mkdir
18422         cmd="$LFS mkdir -i 0 -c 1 $DIR/$tdir"
18423         verify_jobstats "$cmd" "$SINGLEMDS"
18424         # rmdir
18425         cmd="rmdir $DIR/$tdir"
18426         verify_jobstats "$cmd" "$SINGLEMDS"
18427         # mkdir on secondary MDT
18428         if [ $MDSCOUNT -gt 1 ]; then
18429                 cmd="lfs mkdir -i 1 $DIR/$tdir.remote"
18430                 verify_jobstats "$cmd" "mds2"
18431         fi
18432         # mknod
18433         cmd="mknod $DIR/$tfile c 1 3"
18434         verify_jobstats "$cmd" "$SINGLEMDS"
18435         # unlink
18436         cmd="rm -f $DIR/$tfile"
18437         verify_jobstats "$cmd" "$SINGLEMDS"
18438         # create all files on OST0000 so verify_jobstats can find OST stats
18439         # open & close
18440         cmd="$LFS setstripe -i 0 -c 1 $DIR/$tfile"
18441         verify_jobstats "$cmd" "$SINGLEMDS"
18442         # setattr
18443         cmd="touch $DIR/$tfile"
18444         verify_jobstats "$cmd" "$SINGLEMDS ost1"
18445         # write
18446         cmd="dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=sync"
18447         verify_jobstats "$cmd" "ost1"
18448         # read
18449         cancel_lru_locks osc
18450         cmd="dd if=$DIR/$tfile of=/dev/null bs=1M count=1 iflag=direct"
18451         verify_jobstats "$cmd" "ost1"
18452         # truncate
18453         cmd="$TRUNCATE $DIR/$tfile 0"
18454         verify_jobstats "$cmd" "$SINGLEMDS ost1"
18455         # rename
18456         cmd="mv -f $DIR/$tfile $DIR/$tdir.rename"
18457         verify_jobstats "$cmd" "$SINGLEMDS"
18458         # jobstats expiry - sleep until old stats should be expired
18459         local left=$((new_interval + 5 - (SECONDS - start)))
18460         [ $left -ge 0 ] && wait_update_facet $SINGLEMDS \
18461                 "lctl get_param *.*.job_stats | grep -c 'job_id.*mkdir'" \
18462                         "0" $left
18463         cmd="$LFS mkdir -i 0 -c 1 $DIR/$tdir.expire"
18464         verify_jobstats "$cmd" "$SINGLEMDS"
18465         [ $(do_facet $SINGLEMDS lctl get_param *.*.job_stats |
18466             grep -c "job_id.*mkdir") -gt 1 ] && error "old jobstats not expired"
18467
18468         # Ensure that jobid are present in changelog (if supported by MDS)
18469         if [ $MDS1_VERSION -ge $(version_code 2.6.52) ];then
18470                 changelog_dump | tail -10
18471                 jobids=$(changelog_dump | tail -9 | grep -c "j=")
18472                 [ $jobids -eq 9 ] ||
18473                         error "Wrong changelog jobid count $jobids != 9"
18474
18475                 # LU-5862
18476                 JOBENV="disable"
18477                 jobstats_set $JOBENV
18478                 touch $DIR/$tfile
18479                 changelog_dump | grep $tfile
18480                 jobids=$(changelog_dump | grep $tfile | tail -1 | grep -c "j=")
18481                 [ $jobids -eq 0 ] ||
18482                         error "Unexpected jobids when jobid_var=$JOBENV"
18483         fi
18484
18485         # test '%j' access to environment variable - if supported
18486         if lctl set_param jobid_var=USER jobid_name="S.%j.%e.%u.%h.E"; then
18487                 JOBENV="JOBCOMPLEX"
18488                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname).E"
18489
18490                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
18491         fi
18492
18493         if lctl set_param jobid_var=USER jobid_name="S.%j.%e.%u.%H.E"; then
18494                 JOBENV="JOBCOMPLEX"
18495                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname -s).E"
18496
18497                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
18498         fi
18499
18500         # test '%j' access to per-session jobid - if supported
18501         if lctl list_param jobid_this_session > /dev/null 2>&1
18502         then
18503                 lctl set_param jobid_var=session jobid_name="S.%j.%e.%u.%h.E"
18504                 lctl set_param jobid_this_session=$USER
18505
18506                 JOBENV="JOBCOMPLEX"
18507                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname).E"
18508
18509                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
18510         fi
18511 }
18512 run_test 205a "Verify job stats"
18513
18514 # LU-13117, LU-13597
18515 test_205b() {
18516         (( $MDS1_VERSION >= $(version_code 2.13.54.91) )) ||
18517                 skip "Need MDS version at least 2.13.54.91"
18518
18519         job_stats="mdt.*.job_stats"
18520         $LCTL set_param $job_stats=clear
18521         # Setting jobid_var to USER might not be supported
18522         $LCTL set_param jobid_var=USER || true
18523         $LCTL set_param jobid_name="%e.%u"
18524         env -i USERTESTJOBSTATS=foolish touch $DIR/$tfile.1
18525         do_facet $SINGLEMDS $LCTL get_param $job_stats |
18526                 grep "job_id:.*foolish" &&
18527                         error "Unexpected jobid found"
18528         do_facet $SINGLEMDS $LCTL get_param $job_stats |
18529                 grep "open:.*min.*max.*sum" ||
18530                         error "wrong job_stats format found"
18531 }
18532 run_test 205b "Verify job stats jobid and output format"
18533
18534 # LU-13733
18535 test_205c() {
18536         $LCTL set_param llite.*.stats=0
18537         dd if=/dev/zero of=$DIR/$tfile.1 bs=4k count=1
18538         $LCTL get_param llite.*.stats
18539         $LCTL get_param llite.*.stats | grep \
18540                 "write_bytes *1 samples \[bytes\] 4096 4096 4096 16777216" ||
18541                         error "wrong client stats format found"
18542 }
18543 run_test 205c "Verify client stats format"
18544
18545 # LU-1480, LU-1773 and LU-1657
18546 test_206() {
18547         mkdir -p $DIR/$tdir
18548         $LFS setstripe -c -1 $DIR/$tdir
18549 #define OBD_FAIL_LOV_INIT 0x1403
18550         $LCTL set_param fail_loc=0xa0001403
18551         $LCTL set_param fail_val=1
18552         touch $DIR/$tdir/$tfile || true
18553 }
18554 run_test 206 "fail lov_init_raid0() doesn't lbug"
18555
18556 test_207a() {
18557         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((RANDOM%10+1))
18558         local fsz=`stat -c %s $DIR/$tfile`
18559         cancel_lru_locks mdc
18560
18561         # do not return layout in getattr intent
18562 #define OBD_FAIL_MDS_NO_LL_GETATTR 0x170
18563         $LCTL set_param fail_loc=0x170
18564         local sz=`stat -c %s $DIR/$tfile`
18565
18566         [ $fsz -eq $sz ] || error "file size expected $fsz, actual $sz"
18567
18568         rm -rf $DIR/$tfile
18569 }
18570 run_test 207a "can refresh layout at glimpse"
18571
18572 test_207b() {
18573         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((RANDOM%10+1))
18574         local cksum=`md5sum $DIR/$tfile`
18575         local fsz=`stat -c %s $DIR/$tfile`
18576         cancel_lru_locks mdc
18577         cancel_lru_locks osc
18578
18579         # do not return layout in getattr intent
18580 #define OBD_FAIL_MDS_NO_LL_OPEN 0x171
18581         $LCTL set_param fail_loc=0x171
18582
18583         # it will refresh layout after the file is opened but before read issues
18584         echo checksum is "$cksum"
18585         echo "$cksum" |md5sum -c --quiet || error "file differs"
18586
18587         rm -rf $DIR/$tfile
18588 }
18589 run_test 207b "can refresh layout at open"
18590
18591 test_208() {
18592         # FIXME: in this test suite, only RD lease is used. This is okay
18593         # for now as only exclusive open is supported. After generic lease
18594         # is done, this test suite should be revised. - Jinshan
18595
18596         remote_mds_nodsh && skip "remote MDS with nodsh"
18597         [[ $MDS1_VERSION -ge $(version_code 2.4.52) ]] ||
18598                 skip "Need MDS version at least 2.4.52"
18599
18600         echo "==== test 1: verify get lease work"
18601         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:eRE+eU || error "get lease error"
18602
18603         echo "==== test 2: verify lease can be broken by upcoming open"
18604         $MULTIOP $DIR/$tfile oO_RDWR:eR_E-eUc &
18605         local PID=$!
18606         sleep 2
18607
18608         $MULTIOP $DIR/$tfile oO_RDWR:c
18609         kill -USR1 $PID && wait $PID || error "break lease error"
18610
18611         echo "==== test 3: verify lease can't be granted if an open already exists"
18612         $MULTIOP $DIR/$tfile oO_RDWR:_c &
18613         local PID=$!
18614         sleep 2
18615
18616         $MULTIOP $DIR/$tfile oO_RDWR:eReUc && error "apply lease should fail"
18617         kill -USR1 $PID && wait $PID || error "open file error"
18618
18619         echo "==== test 4: lease can sustain over recovery"
18620         $MULTIOP $DIR/$tfile oO_RDWR:eR_E+eUc &
18621         PID=$!
18622         sleep 2
18623
18624         fail mds1
18625
18626         kill -USR1 $PID && wait $PID || error "lease broken over recovery"
18627
18628         echo "==== test 5: lease broken can't be regained by replay"
18629         $MULTIOP $DIR/$tfile oO_RDWR:eR_E-eUc &
18630         PID=$!
18631         sleep 2
18632
18633         # open file to break lease and then recovery
18634         $MULTIOP $DIR/$tfile oO_RDWR:c || error "open file error"
18635         fail mds1
18636
18637         kill -USR1 $PID && wait $PID || error "lease not broken over recovery"
18638
18639         rm -f $DIR/$tfile
18640 }
18641 run_test 208 "Exclusive open"
18642
18643 test_209() {
18644         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep disp_stripe)" ] &&
18645                 skip_env "must have disp_stripe"
18646
18647         touch $DIR/$tfile
18648         sync; sleep 5; sync;
18649
18650         echo 3 > /proc/sys/vm/drop_caches
18651         [ -f /sys/kernel/slab/ptlrpc_cache/shrink ] &&
18652                 echo 1 > /sys/kernel/slab/ptlrpc_cache/shrink
18653         req_before=$(awk '/ptlrpc_cache / { print $2 }' /proc/slabinfo)
18654
18655         # open/close 500 times
18656         for i in $(seq 500); do
18657                 cat $DIR/$tfile
18658         done
18659
18660         echo 3 > /proc/sys/vm/drop_caches
18661         [ -f /sys/kernel/slab/ptlrpc_cache/shrink ] &&
18662                 echo 1 > /sys/kernel/slab/ptlrpc_cache/shrink
18663         req_after=$(awk '/ptlrpc_cache / { print $2 }' /proc/slabinfo)
18664
18665         echo "before: $req_before, after: $req_after"
18666         [ $((req_after - req_before)) -ge 300 ] &&
18667                 error "open/close requests are not freed"
18668         return 0
18669 }
18670 run_test 209 "read-only open/close requests should be freed promptly"
18671
18672 test_210() {
18673         local pid
18674
18675         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:eW_E+eUc &
18676         pid=$!
18677         sleep 1
18678
18679         $LFS getstripe $DIR/$tfile
18680         kill -USR1 $pid
18681         wait $pid || error "multiop failed"
18682
18683         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E+eUc &
18684         pid=$!
18685         sleep 1
18686
18687         $LFS getstripe $DIR/$tfile
18688         kill -USR1 $pid
18689         wait $pid || error "multiop failed"
18690 }
18691 run_test 210 "lfs getstripe does not break leases"
18692
18693 test_212() {
18694         size=`date +%s`
18695         size=$((size % 8192 + 1))
18696         dd if=/dev/urandom of=$DIR/f212 bs=1k count=$size
18697         sendfile $DIR/f212 $DIR/f212.xyz || error "sendfile wrong"
18698         rm -f $DIR/f212 $DIR/f212.xyz
18699 }
18700 run_test 212 "Sendfile test ============================================"
18701
18702 test_213() {
18703         dd if=/dev/zero of=$DIR/$tfile bs=4k count=4
18704         cancel_lru_locks osc
18705         lctl set_param fail_loc=0x8000040f
18706         # generate a read lock
18707         cat $DIR/$tfile > /dev/null
18708         # write to the file, it will try to cancel the above read lock.
18709         cat /etc/hosts >> $DIR/$tfile
18710 }
18711 run_test 213 "OSC lock completion and cancel race don't crash - bug 18829"
18712
18713 test_214() { # for bug 20133
18714         mkdir -p $DIR/$tdir/d214c || error "mkdir $DIR/$tdir/d214c failed"
18715         for (( i=0; i < 340; i++ )) ; do
18716                 touch $DIR/$tdir/d214c/a$i
18717         done
18718
18719         ls -l $DIR/$tdir || error "ls -l $DIR/d214p failed"
18720         mv $DIR/$tdir/d214c $DIR/ || error "mv $DIR/d214p/d214c $DIR/ failed"
18721         ls $DIR/d214c || error "ls $DIR/d214c failed"
18722         rm -rf $DIR/$tdir || error "rm -rf $DIR/d214* failed"
18723         rm -rf $DIR/d214* || error "rm -rf $DIR/d214* failed"
18724 }
18725 run_test 214 "hash-indexed directory test - bug 20133"
18726
18727 # having "abc" as 1st arg, creates $TMP/lnet_abc.out and $TMP/lnet_abc.sys
18728 create_lnet_proc_files() {
18729         lctl get_param -n $1 >$TMP/lnet_$1.sys || error "cannot read lnet.$1"
18730 }
18731
18732 # counterpart of create_lnet_proc_files
18733 remove_lnet_proc_files() {
18734         rm -f $TMP/lnet_$1.sys
18735 }
18736
18737 # uses 1st arg as trailing part of filename, 2nd arg as description for reports,
18738 # 3rd arg as regexp for body
18739 check_lnet_proc_stats() {
18740         local l=$(cat "$TMP/lnet_$1" |wc -l)
18741         [ $l = 1 ] || (cat "$TMP/lnet_$1" && error "$2 is not of 1 line: $l")
18742
18743         grep -E "$3" "$TMP/lnet_$1" || (cat "$TMP/lnet_$1" && error "$2 misformatted")
18744 }
18745
18746 # uses 1st arg as trailing part of filename, 2nd arg as description for reports,
18747 # 3rd arg as regexp for body, 4th arg as regexp for 1st line, 5th arg is
18748 # optional and can be regexp for 2nd line (lnet.routes case)
18749 check_lnet_proc_entry() {
18750         local blp=2          # blp stands for 'position of 1st line of body'
18751         [ -z "$5" ] || blp=3 # lnet.routes case
18752
18753         local l=$(cat "$TMP/lnet_$1" |wc -l)
18754         # subtracting one from $blp because the body can be empty
18755         [ "$l" -ge "$(($blp - 1))" ] || (cat "$TMP/lnet_$1" && error "$2 is too short: $l")
18756
18757         sed -n '1 p' "$TMP/lnet_$1" |grep -E "$4" >/dev/null ||
18758                 (cat "$TMP/lnet_$1" && error "1st line of $2 misformatted")
18759
18760         [ "$5" = "" ] || sed -n '2 p' "$TMP/lnet_$1" |grep -E "$5" >/dev/null ||
18761                 (cat "$TMP/lnet_$1" && error "2nd line of $2 misformatted")
18762
18763         # bail out if any unexpected line happened
18764         sed -n "$blp p" "$TMP/lnet_$1" | grep -Ev "$3"
18765         [ "$?" != 0 ] || error "$2 misformatted"
18766 }
18767
18768 test_215() { # for bugs 18102, 21079, 21517
18769         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18770
18771         local N='(0|[1-9][0-9]*)'       # non-negative numeric
18772         local P='[1-9][0-9]*'           # positive numeric
18773         local I='(0|-?[1-9][0-9]*|NA)'  # any numeric (0 | >0 | <0) or NA if no value
18774         local NET='[a-z][a-z0-9]*'      # LNET net like o2ib2
18775         local ADDR='[0-9.]+'            # LNET addr like 10.0.0.1
18776         local NID="$ADDR@$NET"          # LNET nid like 10.0.0.1@o2ib2
18777
18778         local L1 # regexp for 1st line
18779         local L2 # regexp for 2nd line (optional)
18780         local BR # regexp for the rest (body)
18781
18782         # lnet.stats should look as 11 space-separated non-negative numerics
18783         BR="^$N $N $N $N $N $N $N $N $N $N $N$"
18784         create_lnet_proc_files "stats"
18785         check_lnet_proc_stats "stats.sys" "lnet.stats" "$BR"
18786         remove_lnet_proc_files "stats"
18787
18788         # lnet.routes should look like this:
18789         # Routing disabled/enabled
18790         # net hops priority state router
18791         # where net is a string like tcp0, hops > 0, priority >= 0,
18792         # state is up/down,
18793         # router is a string like 192.168.1.1@tcp2
18794         L1="^Routing (disabled|enabled)$"
18795         L2="^net +hops +priority +state +router$"
18796         BR="^$NET +$N +(0|1) +(up|down) +$NID$"
18797         create_lnet_proc_files "routes"
18798         check_lnet_proc_entry "routes.sys" "lnet.routes" "$BR" "$L1" "$L2"
18799         remove_lnet_proc_files "routes"
18800
18801         # lnet.routers should look like this:
18802         # ref rtr_ref alive_cnt state last_ping ping_sent deadline down_ni router
18803         # where ref > 0, rtr_ref > 0, alive_cnt >= 0, state is up/down,
18804         # last_ping >= 0, ping_sent is boolean (0/1), deadline and down_ni are
18805         # numeric (0 or >0 or <0), router is a string like 192.168.1.1@tcp2
18806         L1="^ref +rtr_ref +alive +router$"
18807         BR="^$P +$P +(up|down) +$NID$"
18808         create_lnet_proc_files "routers"
18809         check_lnet_proc_entry "routers.sys" "lnet.routers" "$BR" "$L1"
18810         remove_lnet_proc_files "routers"
18811
18812         # lnet.peers should look like this:
18813         # nid refs state last max rtr min tx min queue
18814         # where nid is a string like 192.168.1.1@tcp2, refs > 0,
18815         # state is up/down/NA, max >= 0. last, rtr, min, tx, min are
18816         # numeric (0 or >0 or <0), queue >= 0.
18817         L1="^nid +refs +state +last +max +rtr +min +tx +min +queue$"
18818         BR="^$NID +$P +(up|down|NA) +$I +$N +$I +$I +$I +$I +$N$"
18819         create_lnet_proc_files "peers"
18820         check_lnet_proc_entry "peers.sys" "lnet.peers" "$BR" "$L1"
18821         remove_lnet_proc_files "peers"
18822
18823         # lnet.buffers  should look like this:
18824         # pages count credits min
18825         # where pages >=0, count >=0, credits and min are numeric (0 or >0 or <0)
18826         L1="^pages +count +credits +min$"
18827         BR="^ +$N +$N +$I +$I$"
18828         create_lnet_proc_files "buffers"
18829         check_lnet_proc_entry "buffers.sys" "lnet.buffers" "$BR" "$L1"
18830         remove_lnet_proc_files "buffers"
18831
18832         # lnet.nis should look like this:
18833         # nid status alive refs peer rtr max tx min
18834         # where nid is a string like 192.168.1.1@tcp2, status is up/down,
18835         # alive is numeric (0 or >0 or <0), refs >= 0, peer >= 0,
18836         # rtr >= 0, max >=0, tx and min are numeric (0 or >0 or <0).
18837         L1="^nid +status +alive +refs +peer +rtr +max +tx +min$"
18838         BR="^$NID +(up|down) +$I +$N +$N +$N +$N +$I +$I$"
18839         create_lnet_proc_files "nis"
18840         check_lnet_proc_entry "nis.sys" "lnet.nis" "$BR" "$L1"
18841         remove_lnet_proc_files "nis"
18842
18843         # can we successfully write to lnet.stats?
18844         lctl set_param -n stats=0 || error "cannot write to lnet.stats"
18845 }
18846 run_test 215 "lnet exists and has proper content - bugs 18102, 21079, 21517"
18847
18848 test_216() { # bug 20317
18849         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18850         remote_ost_nodsh && skip "remote OST with nodsh"
18851
18852         local node
18853         local facets=$(get_facets OST)
18854         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
18855
18856         save_lustre_params client "osc.*.contention_seconds" > $p
18857         save_lustre_params $facets \
18858                 "ldlm.namespaces.filter-*.max_nolock_bytes" >> $p
18859         save_lustre_params $facets \
18860                 "ldlm.namespaces.filter-*.contended_locks" >> $p
18861         save_lustre_params $facets \
18862                 "ldlm.namespaces.filter-*.contention_seconds" >> $p
18863         clear_stats osc.*.osc_stats
18864
18865         # agressive lockless i/o settings
18866         do_nodes $(comma_list $(osts_nodes)) \
18867                 "lctl set_param -n ldlm.namespaces.*.max_nolock_bytes=2000000 \
18868                         ldlm.namespaces.filter-*.contended_locks=0 \
18869                         ldlm.namespaces.filter-*.contention_seconds=60"
18870         lctl set_param -n osc.*.contention_seconds=60
18871
18872         $DIRECTIO write $DIR/$tfile 0 10 4096
18873         $CHECKSTAT -s 40960 $DIR/$tfile
18874
18875         # disable lockless i/o
18876         do_nodes $(comma_list $(osts_nodes)) \
18877                 "lctl set_param -n ldlm.namespaces.filter-*.max_nolock_bytes=0 \
18878                         ldlm.namespaces.filter-*.contended_locks=32 \
18879                         ldlm.namespaces.filter-*.contention_seconds=0"
18880         lctl set_param -n osc.*.contention_seconds=0
18881         clear_stats osc.*.osc_stats
18882
18883         dd if=/dev/zero of=$DIR/$tfile count=0
18884         $CHECKSTAT -s 0 $DIR/$tfile
18885
18886         restore_lustre_params <$p
18887         rm -f $p
18888         rm $DIR/$tfile
18889 }
18890 run_test 216 "check lockless direct write updates file size and kms correctly"
18891
18892 test_217() { # bug 22430
18893         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18894
18895         local node
18896         local nid
18897
18898         for node in $(nodes_list); do
18899                 nid=$(host_nids_address $node $NETTYPE)
18900                 if [[ $nid = *-* ]] ; then
18901                         echo "lctl ping $(h2nettype $nid)"
18902                         lctl ping $(h2nettype $nid)
18903                 else
18904                         echo "skipping $node (no hyphen detected)"
18905                 fi
18906         done
18907 }
18908 run_test 217 "check lctl ping for hostnames with hiphen ('-')"
18909
18910 test_218() {
18911        # do directio so as not to populate the page cache
18912        log "creating a 10 Mb file"
18913        $MULTIOP $DIR/$tfile oO_CREAT:O_DIRECT:O_RDWR:w$((10*1048576))c || error "multiop failed while creating a file"
18914        log "starting reads"
18915        dd if=$DIR/$tfile of=/dev/null bs=4096 &
18916        log "truncating the file"
18917        $MULTIOP $DIR/$tfile oO_TRUNC:c || error "multiop failed while truncating the file"
18918        log "killing dd"
18919        kill %+ || true # reads might have finished
18920        echo "wait until dd is finished"
18921        wait
18922        log "removing the temporary file"
18923        rm -rf $DIR/$tfile || error "tmp file removal failed"
18924 }
18925 run_test 218 "parallel read and truncate should not deadlock"
18926
18927 test_219() {
18928         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18929
18930         # write one partial page
18931         dd if=/dev/zero of=$DIR/$tfile bs=1024 count=1
18932         # set no grant so vvp_io_commit_write will do sync write
18933         $LCTL set_param fail_loc=0x411
18934         # write a full page at the end of file
18935         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 seek=1 conv=notrunc
18936
18937         $LCTL set_param fail_loc=0
18938         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 seek=3
18939         $LCTL set_param fail_loc=0x411
18940         dd if=/dev/zero of=$DIR/$tfile bs=1024 count=1 seek=2 conv=notrunc
18941
18942         # LU-4201
18943         dd if=/dev/zero of=$DIR/$tfile-2 bs=1024 count=1
18944         $CHECKSTAT -s 1024 $DIR/$tfile-2 || error "checkstat wrong size"
18945 }
18946 run_test 219 "LU-394: Write partial won't cause uncontiguous pages vec at LND"
18947
18948 test_220() { #LU-325
18949         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18950         remote_ost_nodsh && skip "remote OST with nodsh"
18951         remote_mds_nodsh && skip "remote MDS with nodsh"
18952         remote_mgs_nodsh && skip "remote MGS with nodsh"
18953
18954         local OSTIDX=0
18955
18956         # create on MDT0000 so the last_id and next_id are correct
18957         mkdir_on_mdt0 $DIR/$tdir
18958         local OST=$($LFS df $DIR | awk '/OST:'$OSTIDX'/ { print $1 }')
18959         OST=${OST%_UUID}
18960
18961         # on the mdt's osc
18962         local mdtosc_proc1=$(get_mdtosc_proc_path $SINGLEMDS $OST)
18963         local last_id=$(do_facet $SINGLEMDS lctl get_param -n \
18964                         osp.$mdtosc_proc1.prealloc_last_id)
18965         local next_id=$(do_facet $SINGLEMDS lctl get_param -n \
18966                         osp.$mdtosc_proc1.prealloc_next_id)
18967
18968         $LFS df -i
18969
18970         do_facet ost$((OSTIDX + 1)) lctl set_param fail_val=-1
18971         #define OBD_FAIL_OST_ENOINO              0x229
18972         do_facet ost$((OSTIDX + 1)) lctl set_param fail_loc=0x229
18973         create_pool $FSNAME.$TESTNAME || return 1
18974         do_facet mgs $LCTL pool_add $FSNAME.$TESTNAME $OST || return 2
18975
18976         $LFS setstripe $DIR/$tdir -i $OSTIDX -c 1 -p $FSNAME.$TESTNAME
18977
18978         MDSOBJS=$((last_id - next_id))
18979         echo "preallocated objects on MDS is $MDSOBJS" "($last_id - $next_id)"
18980
18981         blocks=$($LFS df $MOUNT | awk '($1 == '$OSTIDX') { print $4 }')
18982         echo "OST still has $count kbytes free"
18983
18984         echo "create $MDSOBJS files @next_id..."
18985         createmany -o $DIR/$tdir/f $MDSOBJS || return 3
18986
18987         local last_id2=$(do_facet mds${MDSIDX} lctl get_param -n \
18988                         osp.$mdtosc_proc1.prealloc_last_id)
18989         local next_id2=$(do_facet mds${MDSIDX} lctl get_param -n \
18990                         osp.$mdtosc_proc1.prealloc_next_id)
18991
18992         echo "after creation, last_id=$last_id2, next_id=$next_id2"
18993         $LFS df -i
18994
18995         echo "cleanup..."
18996
18997         do_facet ost$((OSTIDX + 1)) lctl set_param fail_val=0
18998         do_facet ost$((OSTIDX + 1)) lctl set_param fail_loc=0
18999
19000         do_facet mgs $LCTL pool_remove $FSNAME.$TESTNAME $OST ||
19001                 error "$LCTL pool_remove $FSNAME.$TESTNAME $OST failed"
19002         do_facet mgs $LCTL pool_destroy $FSNAME.$TESTNAME ||
19003                 error "$LCTL pool_destroy $FSNAME.$TESTNAME failed"
19004         echo "unlink $MDSOBJS files @$next_id..."
19005         unlinkmany $DIR/$tdir/f $MDSOBJS || error "unlinkmany failed"
19006 }
19007 run_test 220 "preallocated MDS objects still used if ENOSPC from OST"
19008
19009 test_221() {
19010         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19011
19012         dd if=`which date` of=$MOUNT/date oflag=sync
19013         chmod +x $MOUNT/date
19014
19015         #define OBD_FAIL_LLITE_FAULT_TRUNC_RACE  0x1401
19016         $LCTL set_param fail_loc=0x80001401
19017
19018         $MOUNT/date > /dev/null
19019         rm -f $MOUNT/date
19020 }
19021 run_test 221 "make sure fault and truncate race to not cause OOM"
19022
19023 test_222a () {
19024         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19025
19026         rm -rf $DIR/$tdir
19027         test_mkdir $DIR/$tdir
19028         $LFS setstripe -c 1 -i 0 $DIR/$tdir
19029         createmany -o $DIR/$tdir/$tfile 10
19030         cancel_lru_locks mdc
19031         cancel_lru_locks osc
19032         #define OBD_FAIL_LDLM_AGL_DELAY           0x31a
19033         $LCTL set_param fail_loc=0x31a
19034         ls -l $DIR/$tdir > /dev/null || error "AGL for ls failed"
19035         $LCTL set_param fail_loc=0
19036         rm -r $DIR/$tdir
19037 }
19038 run_test 222a "AGL for ls should not trigger CLIO lock failure"
19039
19040 test_222b () {
19041         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19042
19043         rm -rf $DIR/$tdir
19044         test_mkdir $DIR/$tdir
19045         $LFS setstripe -c 1 -i 0 $DIR/$tdir
19046         createmany -o $DIR/$tdir/$tfile 10
19047         cancel_lru_locks mdc
19048         cancel_lru_locks osc
19049         #define OBD_FAIL_LDLM_AGL_DELAY           0x31a
19050         $LCTL set_param fail_loc=0x31a
19051         rm -r $DIR/$tdir || error "AGL for rmdir failed"
19052         $LCTL set_param fail_loc=0
19053 }
19054 run_test 222b "AGL for rmdir should not trigger CLIO lock failure"
19055
19056 test_223 () {
19057         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19058
19059         rm -rf $DIR/$tdir
19060         test_mkdir $DIR/$tdir
19061         $LFS setstripe -c 1 -i 0 $DIR/$tdir
19062         createmany -o $DIR/$tdir/$tfile 10
19063         cancel_lru_locks mdc
19064         cancel_lru_locks osc
19065         #define OBD_FAIL_LDLM_AGL_NOLOCK          0x31b
19066         $LCTL set_param fail_loc=0x31b
19067         ls -l $DIR/$tdir > /dev/null || error "reenqueue failed"
19068         $LCTL set_param fail_loc=0
19069         rm -r $DIR/$tdir
19070 }
19071 run_test 223 "osc reenqueue if without AGL lock granted ======================="
19072
19073 test_224a() { # LU-1039, MRP-303
19074         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19075         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB   0x508
19076         $LCTL set_param fail_loc=0x508
19077         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 conv=fsync
19078         $LCTL set_param fail_loc=0
19079         df $DIR
19080 }
19081 run_test 224a "Don't panic on bulk IO failure"
19082
19083 test_224bd_sub() { # LU-1039, MRP-303
19084         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19085         local timeout=$1
19086
19087         shift
19088         dd if=/dev/urandom of=$TMP/$tfile bs=1M count=1
19089
19090         $LFS setstripe -c 1 -i 0 $DIR/$tfile
19091
19092         dd if=$TMP/$tfile of=$DIR/$tfile bs=1M count=1
19093         cancel_lru_locks osc
19094         set_checksums 0
19095         stack_trap "set_checksums $ORIG_CSUM" EXIT
19096         local at_max_saved=0
19097
19098         # adaptive timeouts may prevent seeing the issue
19099         if at_is_enabled; then
19100                 at_max_saved=$(at_max_get mds)
19101                 at_max_set 0 mds client
19102                 stack_trap "at_max_set $at_max_saved mds client" EXIT
19103         fi
19104
19105         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB2   0x515
19106         do_facet ost1 $LCTL set_param fail_val=$timeout fail_loc=0x80000515
19107         dd of=$TMP/$tfile.new if=$DIR/$tfile bs=1M count=1 || "$@"
19108
19109         do_facet ost1 $LCTL set_param fail_loc=0
19110         cmp $TMP/$tfile $TMP/$tfile.new || error "file contents wrong"
19111         df $DIR
19112 }
19113
19114 test_224b() {
19115         test_224bd_sub 3 error "dd failed"
19116 }
19117 run_test 224b "Don't panic on bulk IO failure"
19118
19119 test_224c() { # LU-6441
19120         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19121         remote_mds_nodsh && skip "remote MDS with nodsh"
19122
19123         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
19124         save_writethrough $p
19125         set_cache writethrough on
19126
19127         local pages_per_rpc=$($LCTL get_param osc.*.max_pages_per_rpc)
19128         local at_max=$($LCTL get_param -n at_max)
19129         local timeout=$($LCTL get_param -n timeout)
19130         local test_at="at_max"
19131         local param_at="$FSNAME.sys.at_max"
19132         local test_timeout="timeout"
19133         local param_timeout="$FSNAME.sys.timeout"
19134
19135         $LCTL set_param -n osc.*.max_pages_per_rpc=1024
19136
19137         set_persistent_param_and_check client "$test_at" "$param_at" 0
19138         set_persistent_param_and_check client "$test_timeout" "$param_timeout" 5
19139
19140         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB3 0x520
19141         do_facet ost1 "$LCTL set_param fail_loc=0x520"
19142         $LFS setstripe -c 1 -i 0 $DIR/$tfile
19143         dd if=/dev/zero of=$DIR/$tfile bs=8MB count=1
19144         sync
19145         do_facet ost1 "$LCTL set_param fail_loc=0"
19146
19147         set_persistent_param_and_check client "$test_at" "$param_at" $at_max
19148         set_persistent_param_and_check client "$test_timeout" "$param_timeout" \
19149                 $timeout
19150
19151         $LCTL set_param -n $pages_per_rpc
19152         restore_lustre_params < $p
19153         rm -f $p
19154 }
19155 run_test 224c "Don't hang if one of md lost during large bulk RPC"
19156
19157 test_224d() { # LU-11169
19158         test_224bd_sub $((TIMEOUT + 2)) error "dd failed"
19159 }
19160 run_test 224d "Don't corrupt data on bulk IO timeout"
19161
19162 MDSSURVEY=${MDSSURVEY:-$(which mds-survey 2>/dev/null || true)}
19163 test_225a () {
19164         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19165         if [ -z ${MDSSURVEY} ]; then
19166                 skip_env "mds-survey not found"
19167         fi
19168         [ $MDS1_VERSION -ge $(version_code 2.2.51) ] ||
19169                 skip "Need MDS version at least 2.2.51"
19170
19171         local mds=$(facet_host $SINGLEMDS)
19172         local target=$(do_nodes $mds 'lctl dl' |
19173                        awk '{ if ($2 == "UP" && $3 == "mdt") { print $4 }}')
19174
19175         local cmd1="file_count=1000 thrhi=4"
19176         local cmd2="dir_count=2 layer=mdd stripe_count=0"
19177         local cmd3="rslt_loc=${TMP} targets=\"$mds:$target\" $MDSSURVEY"
19178         local cmd="$cmd1 $cmd2 $cmd3"
19179
19180         rm -f ${TMP}/mds_survey*
19181         echo + $cmd
19182         eval $cmd || error "mds-survey with zero-stripe failed"
19183         cat ${TMP}/mds_survey*
19184         rm -f ${TMP}/mds_survey*
19185 }
19186 run_test 225a "Metadata survey sanity with zero-stripe"
19187
19188 test_225b () {
19189         if [ -z ${MDSSURVEY} ]; then
19190                 skip_env "mds-survey not found"
19191         fi
19192         [ $MDS1_VERSION -ge $(version_code 2.2.51) ] ||
19193                 skip "Need MDS version at least 2.2.51"
19194         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19195         remote_mds_nodsh && skip "remote MDS with nodsh"
19196         if [ $($LCTL dl | grep -c osc) -eq 0 ]; then
19197                 skip_env "Need to mount OST to test"
19198         fi
19199
19200         local mds=$(facet_host $SINGLEMDS)
19201         local target=$(do_nodes $mds 'lctl dl' |
19202                        awk '{ if ($2 == "UP" && $3 == "mdt") { print $4 }}')
19203
19204         local cmd1="file_count=1000 thrhi=4"
19205         local cmd2="dir_count=2 layer=mdd stripe_count=1"
19206         local cmd3="rslt_loc=${TMP} targets=\"$mds:$target\" $MDSSURVEY"
19207         local cmd="$cmd1 $cmd2 $cmd3"
19208
19209         rm -f ${TMP}/mds_survey*
19210         echo + $cmd
19211         eval $cmd || error "mds-survey with stripe_count failed"
19212         cat ${TMP}/mds_survey*
19213         rm -f ${TMP}/mds_survey*
19214 }
19215 run_test 225b "Metadata survey sanity with stripe_count = 1"
19216
19217 mcreate_path2fid () {
19218         local mode=$1
19219         local major=$2
19220         local minor=$3
19221         local name=$4
19222         local desc=$5
19223         local path=$DIR/$tdir/$name
19224         local fid
19225         local rc
19226         local fid_path
19227
19228         $MCREATE --mode=$1 --major=$2 --minor=$3 $path ||
19229                 error "cannot create $desc"
19230
19231         fid=$($LFS path2fid $path | tr -d '[' | tr -d ']')
19232         rc=$?
19233         [ $rc -ne 0 ] && error "cannot get fid of a $desc"
19234
19235         fid_path=$($LFS fid2path $MOUNT $fid)
19236         rc=$?
19237         [ $rc -ne 0 ] && error "cannot get path of $desc by $DIR $path $fid"
19238
19239         [ "$path" == "$fid_path" ] ||
19240                 error "fid2path returned $fid_path, expected $path"
19241
19242         echo "pass with $path and $fid"
19243 }
19244
19245 test_226a () {
19246         rm -rf $DIR/$tdir
19247         mkdir -p $DIR/$tdir
19248
19249         mcreate_path2fid 0010666 0 0 fifo "FIFO"
19250         mcreate_path2fid 0020666 1 3 null "character special file (null)"
19251         mcreate_path2fid 0020666 1 255 none "character special file (no device)"
19252         mcreate_path2fid 0040666 0 0 dir "directory"
19253         mcreate_path2fid 0060666 7 0 loop0 "block special file (loop)"
19254         mcreate_path2fid 0100666 0 0 file "regular file"
19255         mcreate_path2fid 0120666 0 0 link "symbolic link"
19256         mcreate_path2fid 0140666 0 0 sock "socket"
19257 }
19258 run_test 226a "call path2fid and fid2path on files of all type"
19259
19260 test_226b () {
19261         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19262
19263         local MDTIDX=1
19264
19265         rm -rf $DIR/$tdir
19266         mkdir -p $DIR/$tdir
19267         $LFS setdirstripe -i $MDTIDX $DIR/$tdir/remote_dir ||
19268                 error "create remote directory failed"
19269         mcreate_path2fid 0010666 0 0 "remote_dir/fifo" "FIFO"
19270         mcreate_path2fid 0020666 1 3 "remote_dir/null" \
19271                                 "character special file (null)"
19272         mcreate_path2fid 0020666 1 255 "remote_dir/none" \
19273                                 "character special file (no device)"
19274         mcreate_path2fid 0040666 0 0 "remote_dir/dir" "directory"
19275         mcreate_path2fid 0060666 7 0 "remote_dir/loop0" \
19276                                 "block special file (loop)"
19277         mcreate_path2fid 0100666 0 0 "remote_dir/file" "regular file"
19278         mcreate_path2fid 0120666 0 0 "remote_dir/link" "symbolic link"
19279         mcreate_path2fid 0140666 0 0 "remote_dir/sock" "socket"
19280 }
19281 run_test 226b "call path2fid and fid2path on files of all type under remote dir"
19282
19283 test_226c () {
19284         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19285         [[ $MDS1_VERSION -ge $(version_code 2.13.55) ]] ||
19286                 skip "Need MDS version at least 2.13.55"
19287
19288         local submnt=/mnt/submnt
19289         local srcfile=/etc/passwd
19290         local dstfile=$submnt/passwd
19291         local path
19292         local fid
19293
19294         rm -rf $DIR/$tdir
19295         rm -rf $submnt
19296         $LFS setdirstripe -c -1 -i 1 $DIR/$tdir ||
19297                 error "create remote directory failed"
19298         mkdir -p $submnt || error "create $submnt failed"
19299         $MOUNT_CMD $MGSNID:/$FSNAME/$tdir $submnt ||
19300                 error "mount $submnt failed"
19301         stack_trap "umount $submnt" EXIT
19302
19303         cp $srcfile $dstfile
19304         fid=$($LFS path2fid $dstfile)
19305         path=$($LFS fid2path $submnt "$fid")
19306         [ "$path" = "$dstfile" ] ||
19307                 error "fid2path $submnt $fid failed ($path != $dstfile)"
19308 }
19309 run_test 226c "call path2fid and fid2path under remote dir with subdir mount"
19310
19311 # LU-1299 Executing or running ldd on a truncated executable does not
19312 # cause an out-of-memory condition.
19313 test_227() {
19314         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19315         [ -z "$(which ldd)" ] && skip_env "should have ldd tool"
19316
19317         dd if=$(which date) of=$MOUNT/date bs=1k count=1
19318         chmod +x $MOUNT/date
19319
19320         $MOUNT/date > /dev/null
19321         ldd $MOUNT/date > /dev/null
19322         rm -f $MOUNT/date
19323 }
19324 run_test 227 "running truncated executable does not cause OOM"
19325
19326 # LU-1512 try to reuse idle OI blocks
19327 test_228a() {
19328         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19329         remote_mds_nodsh && skip "remote MDS with nodsh"
19330         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
19331
19332         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
19333         local myDIR=$DIR/$tdir
19334
19335         mkdir -p $myDIR
19336         #define OBD_FAIL_SEQ_EXHAUST             0x1002
19337         $LCTL set_param fail_loc=0x80001002
19338         createmany -o $myDIR/t- 10000
19339         $LCTL set_param fail_loc=0
19340         # The guard is current the largest FID holder
19341         touch $myDIR/guard
19342         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
19343                     tr -d '[')
19344         local IDX=$(($SEQ % 64))
19345
19346         do_facet $SINGLEMDS sync
19347         # Make sure journal flushed.
19348         sleep 6
19349         local blk1=$(do_facet $SINGLEMDS \
19350                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
19351                      grep Blockcount | awk '{print $4}')
19352
19353         # Remove old files, some OI blocks will become idle.
19354         unlinkmany $myDIR/t- 10000
19355         # Create new files, idle OI blocks should be reused.
19356         createmany -o $myDIR/t- 2000
19357         do_facet $SINGLEMDS sync
19358         # Make sure journal flushed.
19359         sleep 6
19360         local blk2=$(do_facet $SINGLEMDS \
19361                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
19362                      grep Blockcount | awk '{print $4}')
19363
19364         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
19365 }
19366 run_test 228a "try to reuse idle OI blocks"
19367
19368 test_228b() {
19369         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19370         remote_mds_nodsh && skip "remote MDS with nodsh"
19371         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
19372
19373         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
19374         local myDIR=$DIR/$tdir
19375
19376         mkdir -p $myDIR
19377         #define OBD_FAIL_SEQ_EXHAUST             0x1002
19378         $LCTL set_param fail_loc=0x80001002
19379         createmany -o $myDIR/t- 10000
19380         $LCTL set_param fail_loc=0
19381         # The guard is current the largest FID holder
19382         touch $myDIR/guard
19383         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
19384                     tr -d '[')
19385         local IDX=$(($SEQ % 64))
19386
19387         do_facet $SINGLEMDS sync
19388         # Make sure journal flushed.
19389         sleep 6
19390         local blk1=$(do_facet $SINGLEMDS \
19391                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
19392                      grep Blockcount | awk '{print $4}')
19393
19394         # Remove old files, some OI blocks will become idle.
19395         unlinkmany $myDIR/t- 10000
19396
19397         # stop the MDT
19398         stop $SINGLEMDS || error "Fail to stop MDT."
19399         # remount the MDT
19400         start $SINGLEMDS $MDT_DEV $MDS_MOUNT_OPTS || error "Fail to start MDT."
19401
19402         df $MOUNT || error "Fail to df."
19403         # Create new files, idle OI blocks should be reused.
19404         createmany -o $myDIR/t- 2000
19405         do_facet $SINGLEMDS sync
19406         # Make sure journal flushed.
19407         sleep 6
19408         local blk2=$(do_facet $SINGLEMDS \
19409                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
19410                      grep Blockcount | awk '{print $4}')
19411
19412         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
19413 }
19414 run_test 228b "idle OI blocks can be reused after MDT restart"
19415
19416 #LU-1881
19417 test_228c() {
19418         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19419         remote_mds_nodsh && skip "remote MDS with nodsh"
19420         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
19421
19422         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
19423         local myDIR=$DIR/$tdir
19424
19425         mkdir -p $myDIR
19426         #define OBD_FAIL_SEQ_EXHAUST             0x1002
19427         $LCTL set_param fail_loc=0x80001002
19428         # 20000 files can guarantee there are index nodes in the OI file
19429         createmany -o $myDIR/t- 20000
19430         $LCTL set_param fail_loc=0
19431         # The guard is current the largest FID holder
19432         touch $myDIR/guard
19433         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
19434                     tr -d '[')
19435         local IDX=$(($SEQ % 64))
19436
19437         do_facet $SINGLEMDS sync
19438         # Make sure journal flushed.
19439         sleep 6
19440         local blk1=$(do_facet $SINGLEMDS \
19441                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
19442                      grep Blockcount | awk '{print $4}')
19443
19444         # Remove old files, some OI blocks will become idle.
19445         unlinkmany $myDIR/t- 20000
19446         rm -f $myDIR/guard
19447         # The OI file should become empty now
19448
19449         # Create new files, idle OI blocks should be reused.
19450         createmany -o $myDIR/t- 2000
19451         do_facet $SINGLEMDS sync
19452         # Make sure journal flushed.
19453         sleep 6
19454         local blk2=$(do_facet $SINGLEMDS \
19455                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
19456                      grep Blockcount | awk '{print $4}')
19457
19458         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
19459 }
19460 run_test 228c "NOT shrink the last entry in OI index node to recycle idle leaf"
19461
19462 test_229() { # LU-2482, LU-3448
19463         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19464         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
19465         [ $MDS1_VERSION -lt $(version_code 2.4.53) ] &&
19466                 skip "No HSM $(lustre_build_version $SINGLEMDS) MDS < 2.4.53"
19467
19468         rm -f $DIR/$tfile
19469
19470         # Create a file with a released layout and stripe count 2.
19471         $MULTIOP $DIR/$tfile H2c ||
19472                 error "failed to create file with released layout"
19473
19474         $LFS getstripe -v $DIR/$tfile
19475
19476         local pattern=$($LFS getstripe -L $DIR/$tfile)
19477         [ X"$pattern" = X"released" ] || error "pattern error ($pattern)"
19478
19479         local stripe_count=$($LFS getstripe -c $DIR/$tfile) ||
19480                 error "getstripe"
19481         [ $stripe_count -eq 2 ] || error "stripe count not 2 ($stripe_count)"
19482         stat $DIR/$tfile || error "failed to stat released file"
19483
19484         chown $RUNAS_ID $DIR/$tfile ||
19485                 error "chown $RUNAS_ID $DIR/$tfile failed"
19486
19487         chgrp $RUNAS_ID $DIR/$tfile ||
19488                 error "chgrp $RUNAS_ID $DIR/$tfile failed"
19489
19490         touch $DIR/$tfile || error "touch $DIR/$tfile failed"
19491         rm $DIR/$tfile || error "failed to remove released file"
19492 }
19493 run_test 229 "getstripe/stat/rm/attr changes work on released files"
19494
19495 test_230a() {
19496         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19497         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19498         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
19499                 skip "Need MDS version at least 2.11.52"
19500
19501         local MDTIDX=1
19502
19503         test_mkdir $DIR/$tdir
19504         test_mkdir -i0 -c1 $DIR/$tdir/test_230_local
19505         local mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230_local)
19506         [ $mdt_idx -ne 0 ] &&
19507                 error "create local directory on wrong MDT $mdt_idx"
19508
19509         $LFS mkdir -i $MDTIDX $DIR/$tdir/test_230 ||
19510                         error "create remote directory failed"
19511         local mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230)
19512         [ $mdt_idx -ne $MDTIDX ] &&
19513                 error "create remote directory on wrong MDT $mdt_idx"
19514
19515         createmany -o $DIR/$tdir/test_230/t- 10 ||
19516                 error "create files on remote directory failed"
19517         mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230/t-0)
19518         [ $mdt_idx -ne $MDTIDX ] && error "create files on wrong MDT $mdt_idx"
19519         rm -r $DIR/$tdir || error "unlink remote directory failed"
19520 }
19521 run_test 230a "Create remote directory and files under the remote directory"
19522
19523 test_230b() {
19524         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19525         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19526         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
19527                 skip "Need MDS version at least 2.11.52"
19528
19529         local MDTIDX=1
19530         local mdt_index
19531         local i
19532         local file
19533         local pid
19534         local stripe_count
19535         local migrate_dir=$DIR/$tdir/migrate_dir
19536         local other_dir=$DIR/$tdir/other_dir
19537
19538         test_mkdir $DIR/$tdir
19539         test_mkdir -i0 -c1 $migrate_dir
19540         test_mkdir -i0 -c1 $other_dir
19541         for ((i=0; i<10; i++)); do
19542                 mkdir -p $migrate_dir/dir_${i}
19543                 createmany -o $migrate_dir/dir_${i}/f 10 ||
19544                         error "create files under remote dir failed $i"
19545         done
19546
19547         cp /etc/passwd $migrate_dir/$tfile
19548         cp /etc/passwd $other_dir/$tfile
19549         chattr +SAD $migrate_dir
19550         chattr +SAD $migrate_dir/$tfile
19551
19552         local old_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
19553         local old_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
19554         local old_dir_mode=$(stat -c%f $migrate_dir)
19555         local old_file_mode=$(stat -c%f $migrate_dir/$tfile)
19556
19557         mkdir -p $migrate_dir/dir_default_stripe2
19558         $LFS setstripe -c 2 $migrate_dir/dir_default_stripe2
19559         $LFS setstripe -c 2 $migrate_dir/${tfile}_stripe2
19560
19561         mkdir -p $other_dir
19562         ln $migrate_dir/$tfile $other_dir/luna
19563         ln $migrate_dir/$tfile $migrate_dir/sofia
19564         ln $other_dir/$tfile $migrate_dir/david
19565         ln -s $migrate_dir/$tfile $other_dir/zachary
19566         ln -s $migrate_dir/$tfile $migrate_dir/${tfile}_ln
19567         ln -s $other_dir/$tfile $migrate_dir/${tfile}_ln_other
19568
19569         local len
19570         local lnktgt
19571
19572         # inline symlink
19573         for len in 58 59 60; do
19574                 lnktgt=$(str_repeat 'l' $len)
19575                 touch $migrate_dir/$lnktgt
19576                 ln -s $lnktgt $migrate_dir/${len}char_ln
19577         done
19578
19579         # PATH_MAX
19580         for len in 4094 4095; do
19581                 lnktgt=$(str_repeat 'l' $len)
19582                 ln -s $lnktgt $migrate_dir/${len}char_ln
19583         done
19584
19585         # NAME_MAX
19586         for len in 254 255; do
19587                 touch $migrate_dir/$(str_repeat 'l' $len)
19588         done
19589
19590         $LFS migrate -m $MDTIDX $migrate_dir ||
19591                 error "fails on migrating remote dir to MDT1"
19592
19593         echo "migratate to MDT1, then checking.."
19594         for ((i = 0; i < 10; i++)); do
19595                 for file in $(find $migrate_dir/dir_${i}); do
19596                         mdt_index=$($LFS getstripe -m $file)
19597                         # broken symlink getstripe will fail
19598                         [ $mdt_index -ne $MDTIDX ] && stat -L $file &&
19599                                 error "$file is not on MDT${MDTIDX}"
19600                 done
19601         done
19602
19603         # the multiple link file should still in MDT0
19604         mdt_index=$($LFS getstripe -m $migrate_dir/$tfile)
19605         [ $mdt_index == 0 ] ||
19606                 error "$file is not on MDT${MDTIDX}"
19607
19608         local new_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
19609         [ "$old_dir_flag" = "$new_dir_flag" ] ||
19610                 error " expect $old_dir_flag get $new_dir_flag"
19611
19612         local new_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
19613         [ "$old_file_flag" = "$new_file_flag" ] ||
19614                 error " expect $old_file_flag get $new_file_flag"
19615
19616         local new_dir_mode=$(stat -c%f $migrate_dir)
19617         [ "$old_dir_mode" = "$new_dir_mode" ] ||
19618                 error "expect mode $old_dir_mode get $new_dir_mode"
19619
19620         local new_file_mode=$(stat -c%f $migrate_dir/$tfile)
19621         [ "$old_file_mode" = "$new_file_mode" ] ||
19622                 error "expect mode $old_file_mode get $new_file_mode"
19623
19624         diff /etc/passwd $migrate_dir/$tfile ||
19625                 error "$tfile different after migration"
19626
19627         diff /etc/passwd $other_dir/luna ||
19628                 error "luna different after migration"
19629
19630         diff /etc/passwd $migrate_dir/sofia ||
19631                 error "sofia different after migration"
19632
19633         diff /etc/passwd $migrate_dir/david ||
19634                 error "david different after migration"
19635
19636         diff /etc/passwd $other_dir/zachary ||
19637                 error "zachary different after migration"
19638
19639         diff /etc/passwd $migrate_dir/${tfile}_ln ||
19640                 error "${tfile}_ln different after migration"
19641
19642         diff /etc/passwd $migrate_dir/${tfile}_ln_other ||
19643                 error "${tfile}_ln_other different after migration"
19644
19645         stripe_count=$($LFS getstripe -c $migrate_dir/dir_default_stripe2)
19646         [ $stripe_count = 2 ] ||
19647                 error "dir strpe_count $d != 2 after migration."
19648
19649         stripe_count=$($LFS getstripe -c $migrate_dir/${tfile}_stripe2)
19650         [ $stripe_count = 2 ] ||
19651                 error "file strpe_count $d != 2 after migration."
19652
19653         #migrate back to MDT0
19654         MDTIDX=0
19655
19656         $LFS migrate -m $MDTIDX $migrate_dir ||
19657                 error "fails on migrating remote dir to MDT0"
19658
19659         echo "migrate back to MDT0, checking.."
19660         for file in $(find $migrate_dir); do
19661                 mdt_index=$($LFS getstripe -m $file)
19662                 [ $mdt_index -ne $MDTIDX ] && stat -L $file &&
19663                         error "$file is not on MDT${MDTIDX}"
19664         done
19665
19666         local new_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
19667         [ "$old_dir_flag" = "$new_dir_flag" ] ||
19668                 error " expect $old_dir_flag get $new_dir_flag"
19669
19670         local new_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
19671         [ "$old_file_flag" = "$new_file_flag" ] ||
19672                 error " expect $old_file_flag get $new_file_flag"
19673
19674         local new_dir_mode=$(stat -c%f $migrate_dir)
19675         [ "$old_dir_mode" = "$new_dir_mode" ] ||
19676                 error "expect mode $old_dir_mode get $new_dir_mode"
19677
19678         local new_file_mode=$(stat -c%f $migrate_dir/$tfile)
19679         [ "$old_file_mode" = "$new_file_mode" ] ||
19680                 error "expect mode $old_file_mode get $new_file_mode"
19681
19682         diff /etc/passwd ${migrate_dir}/$tfile ||
19683                 error "$tfile different after migration"
19684
19685         diff /etc/passwd ${other_dir}/luna ||
19686                 error "luna different after migration"
19687
19688         diff /etc/passwd ${migrate_dir}/sofia ||
19689                 error "sofia different after migration"
19690
19691         diff /etc/passwd ${other_dir}/zachary ||
19692                 error "zachary different after migration"
19693
19694         diff /etc/passwd $migrate_dir/${tfile}_ln ||
19695                 error "${tfile}_ln different after migration"
19696
19697         diff /etc/passwd $migrate_dir/${tfile}_ln_other ||
19698                 error "${tfile}_ln_other different after migration"
19699
19700         stripe_count=$($LFS getstripe -c ${migrate_dir}/dir_default_stripe2)
19701         [ $stripe_count = 2 ] ||
19702                 error "dir strpe_count $d != 2 after migration."
19703
19704         stripe_count=$($LFS getstripe -c ${migrate_dir}/${tfile}_stripe2)
19705         [ $stripe_count = 2 ] ||
19706                 error "file strpe_count $d != 2 after migration."
19707
19708         rm -rf $DIR/$tdir || error "rm dir failed after migration"
19709 }
19710 run_test 230b "migrate directory"
19711
19712 test_230c() {
19713         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19714         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19715         remote_mds_nodsh && skip "remote MDS with nodsh"
19716         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
19717                 skip "Need MDS version at least 2.11.52"
19718
19719         local MDTIDX=1
19720         local total=3
19721         local mdt_index
19722         local file
19723         local migrate_dir=$DIR/$tdir/migrate_dir
19724
19725         #If migrating directory fails in the middle, all entries of
19726         #the directory is still accessiable.
19727         test_mkdir $DIR/$tdir
19728         test_mkdir -i0 -c1 $migrate_dir
19729         test_mkdir -i1 -c1 $DIR/$tdir/remote_dir
19730         stat $migrate_dir
19731         createmany -o $migrate_dir/f $total ||
19732                 error "create files under ${migrate_dir} failed"
19733
19734         # fail after migrating top dir, and this will fail only once, so the
19735         # first sub file migration will fail (currently f3), others succeed.
19736         #OBD_FAIL_MIGRATE_ENTRIES       0x1801
19737         do_facet mds1 lctl set_param fail_loc=0x1801
19738         local t=$(ls $migrate_dir | wc -l)
19739         $LFS migrate --mdt-index $MDTIDX $migrate_dir &&
19740                 error "migrate should fail"
19741         local u=$(ls $migrate_dir | wc -l)
19742         [ "$u" == "$t" ] || error "$u != $t during migration"
19743
19744         # add new dir/file should succeed
19745         mkdir $migrate_dir/dir ||
19746                 error "mkdir failed under migrating directory"
19747         touch $migrate_dir/file ||
19748                 error "create file failed under migrating directory"
19749
19750         # add file with existing name should fail
19751         for file in $migrate_dir/f*; do
19752                 stat $file > /dev/null || error "stat $file failed"
19753                 $OPENFILE -f O_CREAT:O_EXCL $file &&
19754                         error "open(O_CREAT|O_EXCL) $file should fail"
19755                 $MULTIOP $file m && error "create $file should fail"
19756                 touch $DIR/$tdir/remote_dir/$tfile ||
19757                         error "touch $tfile failed"
19758                 ln $DIR/$tdir/remote_dir/$tfile $file &&
19759                         error "link $file should fail"
19760                 mdt_index=$($LFS getstripe -m $file)
19761                 if [ $mdt_index == 0 ]; then
19762                         # file failed to migrate is not allowed to rename to
19763                         mv $DIR/$tdir/remote_dir/$tfile $file &&
19764                                 error "rename to $file should fail"
19765                 else
19766                         mv $DIR/$tdir/remote_dir/$tfile $file ||
19767                                 error "rename to $file failed"
19768                 fi
19769                 echo hello >> $file || error "write $file failed"
19770         done
19771
19772         # resume migration with different options should fail
19773         $LFS migrate -m 0 $migrate_dir &&
19774                 error "migrate -m 0 $migrate_dir should fail"
19775
19776         $LFS migrate -m $MDTIDX -c 2 $migrate_dir &&
19777                 error "migrate -c 2 $migrate_dir should fail"
19778
19779         # resume migration should succeed
19780         $LFS migrate -m $MDTIDX $migrate_dir ||
19781                 error "migrate $migrate_dir failed"
19782
19783         echo "Finish migration, then checking.."
19784         for file in $(find $migrate_dir); do
19785                 mdt_index=$($LFS getstripe -m $file)
19786                 [ $mdt_index == $MDTIDX ] ||
19787                         error "$file is not on MDT${MDTIDX}"
19788         done
19789
19790         rm -rf $DIR/$tdir || error "rm dir failed after migration"
19791 }
19792 run_test 230c "check directory accessiblity if migration failed"
19793
19794 test_230d() {
19795         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19796         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19797         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
19798                 skip "Need MDS version at least 2.11.52"
19799         # LU-11235
19800         [ "$mds1_FSTYPE" == "zfs" ] && skip "skip ZFS backend"
19801
19802         local migrate_dir=$DIR/$tdir/migrate_dir
19803         local old_index
19804         local new_index
19805         local old_count
19806         local new_count
19807         local new_hash
19808         local mdt_index
19809         local i
19810         local j
19811
19812         old_index=$((RANDOM % MDSCOUNT))
19813         old_count=$((MDSCOUNT - old_index))
19814         new_index=$((RANDOM % MDSCOUNT))
19815         new_count=$((MDSCOUNT - new_index))
19816         new_hash=1 # for all_char
19817
19818         [ $old_count -gt 1 ] && old_count=$((old_count - RANDOM % old_count))
19819         [ $new_count -gt 1 ] && new_count=$((new_count - RANDOM % new_count))
19820
19821         test_mkdir $DIR/$tdir
19822         test_mkdir -i $old_index -c $old_count $migrate_dir
19823
19824         for ((i=0; i<100; i++)); do
19825                 test_mkdir -i0 -c1 $migrate_dir/dir_${i}
19826                 createmany -o $migrate_dir/dir_${i}/f 100 ||
19827                         error "create files under remote dir failed $i"
19828         done
19829
19830         echo -n "Migrate from MDT$old_index "
19831         [ $old_count -gt 1 ] && echo -n "... MDT$((old_index + old_count - 1)) "
19832         echo -n "to MDT$new_index"
19833         [ $new_count -gt 1 ] && echo -n " ... MDT$((new_index + new_count - 1))"
19834         echo
19835
19836         echo "$LFS migrate -m$new_index -c$new_count -H $new_hash $migrate_dir"
19837         $LFS migrate -m $new_index -c $new_count -H $new_hash $migrate_dir ||
19838                 error "migrate remote dir error"
19839
19840         echo "Finish migration, then checking.."
19841         for file in $(find $migrate_dir -maxdepth 1); do
19842                 mdt_index=$($LFS getstripe -m $file)
19843                 if [ $mdt_index -lt $new_index ] ||
19844                    [ $mdt_index -gt $((new_index + new_count - 1)) ]; then
19845                         error "$file is on MDT$mdt_index"
19846                 fi
19847         done
19848
19849         rm -rf $DIR/$tdir || error "rm dir failed after migration"
19850 }
19851 run_test 230d "check migrate big directory"
19852
19853 test_230e() {
19854         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19855         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19856         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
19857                 skip "Need MDS version at least 2.11.52"
19858
19859         local i
19860         local j
19861         local a_fid
19862         local b_fid
19863
19864         mkdir_on_mdt0 $DIR/$tdir
19865         mkdir $DIR/$tdir/migrate_dir
19866         mkdir $DIR/$tdir/other_dir
19867         touch $DIR/$tdir/migrate_dir/a
19868         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/b
19869         ls $DIR/$tdir/other_dir
19870
19871         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
19872                 error "migrate dir fails"
19873
19874         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir)
19875         [ $mdt_index == 1 ] || error "migrate_dir is not on MDT1"
19876
19877         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
19878         [ $mdt_index == 0 ] || error "a is not on MDT0"
19879
19880         $LFS migrate -m 1 $DIR/$tdir/other_dir ||
19881                 error "migrate dir fails"
19882
19883         mdt_index=$($LFS getstripe -m $DIR/$tdir/other_dir)
19884         [ $mdt_index == 1 ] || error "other_dir is not on MDT1"
19885
19886         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
19887         [ $mdt_index == 1 ] || error "a is not on MDT1"
19888
19889         mdt_index=$($LFS getstripe -m $DIR/$tdir/other_dir/b)
19890         [ $mdt_index == 1 ] || error "b is not on MDT1"
19891
19892         a_fid=$($LFS path2fid $DIR/$tdir/migrate_dir/a)
19893         b_fid=$($LFS path2fid $DIR/$tdir/other_dir/b)
19894
19895         [ "$a_fid" = "$b_fid" ] || error "different fid after migration"
19896
19897         rm -rf $DIR/$tdir || error "rm dir failed after migration"
19898 }
19899 run_test 230e "migrate mulitple local link files"
19900
19901 test_230f() {
19902         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19903         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19904         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
19905                 skip "Need MDS version at least 2.11.52"
19906
19907         local a_fid
19908         local ln_fid
19909
19910         mkdir -p $DIR/$tdir
19911         mkdir $DIR/$tdir/migrate_dir
19912         $LFS mkdir -i1 $DIR/$tdir/other_dir
19913         touch $DIR/$tdir/migrate_dir/a
19914         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/ln1
19915         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/ln2
19916         ls $DIR/$tdir/other_dir
19917
19918         # a should be migrated to MDT1, since no other links on MDT0
19919         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
19920                 error "#1 migrate dir fails"
19921         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir)
19922         [ $mdt_index == 1 ] || error "migrate_dir is not on MDT1"
19923         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
19924         [ $mdt_index == 1 ] || error "a is not on MDT1"
19925
19926         # a should stay on MDT1, because it is a mulitple link file
19927         $LFS migrate -m 0 $DIR/$tdir/migrate_dir ||
19928                 error "#2 migrate dir fails"
19929         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
19930         [ $mdt_index == 1 ] || error "a is not on MDT1"
19931
19932         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
19933                 error "#3 migrate dir fails"
19934
19935         a_fid=$($LFS path2fid $DIR/$tdir/migrate_dir/a)
19936         ln_fid=$($LFS path2fid $DIR/$tdir/other_dir/ln1)
19937         [ "$a_fid" = "$ln_fid" ] || error "different fid after migrate to MDT1"
19938
19939         rm -rf $DIR/$tdir/other_dir/ln1 || error "unlink ln1 fails"
19940         rm -rf $DIR/$tdir/other_dir/ln2 || error "unlink ln2 fails"
19941
19942         # a should be migrated to MDT0, since no other links on MDT1
19943         $LFS migrate -m 0 $DIR/$tdir/migrate_dir ||
19944                 error "#4 migrate dir fails"
19945         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
19946         [ $mdt_index == 0 ] || error "a is not on MDT0"
19947
19948         rm -rf $DIR/$tdir || error "rm dir failed after migration"
19949 }
19950 run_test 230f "migrate mulitple remote link files"
19951
19952 test_230g() {
19953         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19954         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19955         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
19956                 skip "Need MDS version at least 2.11.52"
19957
19958         mkdir -p $DIR/$tdir/migrate_dir
19959
19960         $LFS migrate -m 1000 $DIR/$tdir/migrate_dir &&
19961                 error "migrating dir to non-exist MDT succeeds"
19962         true
19963 }
19964 run_test 230g "migrate dir to non-exist MDT"
19965
19966 test_230h() {
19967         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19968         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19969         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
19970                 skip "Need MDS version at least 2.11.52"
19971
19972         local mdt_index
19973
19974         mkdir -p $DIR/$tdir/migrate_dir
19975
19976         $LFS migrate -m1 $DIR &&
19977                 error "migrating mountpoint1 should fail"
19978
19979         $LFS migrate -m1 $DIR/$tdir/.. &&
19980                 error "migrating mountpoint2 should fail"
19981
19982         # same as mv
19983         $LFS migrate -m1 $DIR/$tdir/migrate_dir/.. &&
19984                 error "migrating $tdir/migrate_dir/.. should fail"
19985
19986         true
19987 }
19988 run_test 230h "migrate .. and root"
19989
19990 test_230i() {
19991         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19992         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19993         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
19994                 skip "Need MDS version at least 2.11.52"
19995
19996         mkdir -p $DIR/$tdir/migrate_dir
19997
19998         $LFS migrate -m 1 $DIR/$tdir/migrate_dir/ ||
19999                 error "migration fails with a tailing slash"
20000
20001         $LFS migrate -m 0 $DIR/$tdir/migrate_dir// ||
20002                 error "migration fails with two tailing slashes"
20003 }
20004 run_test 230i "lfs migrate -m tolerates trailing slashes"
20005
20006 test_230j() {
20007         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
20008         [ $MDS1_VERSION -lt $(version_code 2.13.52) ] &&
20009                 skip "Need MDS version at least 2.11.52"
20010
20011         $LFS mkdir -m 0 -c 1 $DIR/$tdir || error "mkdir $tdir failed"
20012         $LFS setstripe -E 1M -L mdt $DIR/$tdir/$tfile ||
20013                 error "create $tfile failed"
20014         cat /etc/passwd > $DIR/$tdir/$tfile
20015
20016         $LFS migrate -m 1 $DIR/$tdir || error "migrate failed"
20017
20018         cmp /etc/passwd $DIR/$tdir/$tfile ||
20019                 error "DoM file mismatch after migration"
20020 }
20021 run_test 230j "DoM file data not changed after dir migration"
20022
20023 test_230k() {
20024         [ $MDSCOUNT -lt 4 ] && skip "needs >= 4 MDTs"
20025         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
20026                 skip "Need MDS version at least 2.11.56"
20027
20028         local total=20
20029         local files_on_starting_mdt=0
20030
20031         $LFS mkdir -i -1 -c 2 $DIR/$tdir || error "mkdir failed"
20032         $LFS getdirstripe $DIR/$tdir
20033         for i in $(seq $total); do
20034                 echo $((i*i - i)) > $DIR/$tdir/$tfile.$i || error "write failed"
20035                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 0 ]] &&
20036                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
20037         done
20038
20039         echo "$files_on_starting_mdt files on MDT0"
20040
20041         $LFS migrate -m 1,3 $DIR/$tdir || error "migrate -m 1,3 failed"
20042         $LFS getdirstripe $DIR/$tdir
20043
20044         files_on_starting_mdt=0
20045         for i in $(seq $total); do
20046                 $(echo $((i*i - i)) | cmp $DIR/$tdir/$tfile.$i -) ||
20047                         error "file $tfile.$i mismatch after migration"
20048                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 1 ]] &&
20049                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
20050         done
20051
20052         echo "$files_on_starting_mdt files on MDT1 after migration"
20053         [[ $files_on_starting_mdt -eq $total ]] && error "all files on MDT1"
20054
20055         $LFS migrate -m 0 -c 2 $DIR/$tdir || error "migrate -m 0 -c 2 failed"
20056         $LFS getdirstripe $DIR/$tdir
20057
20058         files_on_starting_mdt=0
20059         for i in $(seq $total); do
20060                 $(echo $((i*i - i)) | cmp $DIR/$tdir/$tfile.$i -) ||
20061                         error "file $tfile.$i mismatch after 2nd migration"
20062                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 0 ]] &&
20063                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
20064         done
20065
20066         echo "$files_on_starting_mdt files on MDT0 after 2nd migration"
20067         [[ $files_on_starting_mdt -eq $total ]] && error "all files on MDT0"
20068
20069         true
20070 }
20071 run_test 230k "file data not changed after dir migration"
20072
20073 test_230l() {
20074         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
20075         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
20076                 skip "Need MDS version at least 2.11.56"
20077
20078         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "mkdir failed"
20079         createmany -o $DIR/$tdir/f___________________________________ 1000 ||
20080                 error "create files under remote dir failed $i"
20081         $LFS migrate -m 1 $DIR/$tdir || error "migrate failed"
20082 }
20083 run_test 230l "readdir between MDTs won't crash"
20084
20085 test_230m() {
20086         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
20087         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
20088                 skip "Need MDS version at least 2.11.56"
20089
20090         local MDTIDX=1
20091         local mig_dir=$DIR/$tdir/migrate_dir
20092         local longstr="aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
20093         local shortstr="b"
20094         local val
20095
20096         echo "Creating files and dirs with xattrs"
20097         test_mkdir $DIR/$tdir
20098         test_mkdir -i0 -c1 $mig_dir
20099         mkdir $mig_dir/dir
20100         setfattr -n user.attr1 -v $longstr $mig_dir/dir ||
20101                 error "cannot set xattr attr1 on dir"
20102         setfattr -n user.attr2 -v $shortstr $mig_dir/dir ||
20103                 error "cannot set xattr attr2 on dir"
20104         touch $mig_dir/dir/f0
20105         setfattr -n user.attr1 -v $longstr $mig_dir/dir/f0 ||
20106                 error "cannot set xattr attr1 on file"
20107         setfattr -n user.attr2 -v $shortstr $mig_dir/dir/f0 ||
20108                 error "cannot set xattr attr2 on file"
20109         sync ; sync ; echo 3 > /proc/sys/vm/drop_caches
20110         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir 2>/dev/null)
20111         [ "$val" = $longstr ] || error "xattr attr1 not set properly on dir"
20112         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir 2>/dev/null)
20113         [ "$val" = $shortstr ] || error "xattr attr2 not set properly on dir"
20114         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir/f0 2>/dev/null)
20115         [ "$val" = $longstr ] || error "xattr attr1 not set properly on file"
20116         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir/f0 2>/dev/null)
20117         [ "$val" = $shortstr ] || error "xattr attr2 not set properly on file"
20118
20119         echo "Migrating to MDT1"
20120         $LFS migrate -m $MDTIDX $mig_dir ||
20121                 error "fails on migrating dir to MDT1"
20122
20123         sync ; sync ; echo 3 > /proc/sys/vm/drop_caches
20124         echo "Checking xattrs"
20125         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir 2>/dev/null)
20126         [ "$val" = $longstr ] ||
20127                 error "expecting xattr1 $longstr on dir, found $val"
20128         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir 2>/dev/null)
20129         [ "$val" = $shortstr ] ||
20130                 error "expecting xattr2 $shortstr on dir, found $val"
20131         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir/f0 2>/dev/null)
20132         [ "$val" = $longstr ] ||
20133                 error "expecting xattr1 $longstr on file, found $val"
20134         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir/f0 2>/dev/null)
20135         [ "$val" = $shortstr ] ||
20136                 error "expecting xattr2 $shortstr on file, found $val"
20137 }
20138 run_test 230m "xattrs not changed after dir migration"
20139
20140 test_230n() {
20141         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
20142         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
20143                 skip "Need MDS version at least 2.13.53"
20144
20145         $LFS mkdir -i 0 $DIR/$tdir || error "mkdir $tdir failed"
20146         cat /etc/hosts > $DIR/$tdir/$tfile
20147         $LFS mirror extend -N1 $DIR/$tdir/$tfile || error "Mirroring failed"
20148         $LFS migrate -m 1 $DIR/$tdir || error "Migration failed"
20149
20150         cmp /etc/hosts $DIR/$tdir/$tfile ||
20151                 error "File data mismatch after migration"
20152 }
20153 run_test 230n "Dir migration with mirrored file"
20154
20155 test_230o() {
20156         [ $MDSCOUNT -ge 2 ] || skip "needs >= 2 MDTs"
20157         [ $MDS1_VERSION -ge $(version_code 2.13.52) ] ||
20158                 skip "Need MDS version at least 2.13.52"
20159
20160         local mdts=$(comma_list $(mdts_nodes))
20161         local timeout=100
20162         local restripe_status
20163         local delta
20164         local i
20165
20166         [[ $mds1_FSTYPE == zfs ]] && timeout=300
20167
20168         # in case "crush" hash type is not set
20169         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
20170
20171         restripe_status=$(do_facet mds1 $LCTL get_param -n \
20172                            mdt.*MDT0000.enable_dir_restripe)
20173         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=1"
20174         stack_trap "do_nodes $mdts $LCTL set_param \
20175                     mdt.*.enable_dir_restripe=$restripe_status"
20176
20177         mkdir $DIR/$tdir
20178         createmany -m $DIR/$tdir/f 100 ||
20179                 error "create files under remote dir failed $i"
20180         createmany -d $DIR/$tdir/d 100 ||
20181                 error "create dirs under remote dir failed $i"
20182
20183         for i in $(seq 2 $MDSCOUNT); do
20184                 do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear >/dev/null"
20185                 $LFS setdirstripe -c $i $DIR/$tdir ||
20186                         error "split -c $i $tdir failed"
20187                 wait_update $HOSTNAME \
20188                         "$LFS getdirstripe -H $DIR/$tdir" "crush" $timeout ||
20189                         error "dir split not finished"
20190                 delta=$(do_nodes $mdts "lctl get_param -n mdt.*MDT*.md_stats" |
20191                         awk '/migrate/ {sum += $2} END { print sum }')
20192                 echo "$delta migrated when dir split $((i - 1)) to $i stripes"
20193                 # delta is around total_files/stripe_count
20194                 (( $delta < 200 / (i - 1) + 4 )) ||
20195                         error "$delta files migrated >= $((200 / (i - 1) + 4))"
20196         done
20197 }
20198 run_test 230o "dir split"
20199
20200 test_230p() {
20201         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
20202         (( MDS1_VERSION >= $(version_code 2.13.52) )) ||
20203                 skip "Need MDS version at least 2.13.52"
20204
20205         local mdts=$(comma_list $(mdts_nodes))
20206         local timeout=100
20207         local restripe_status
20208         local delta
20209         local c
20210
20211         [[ $mds1_FSTYPE == zfs ]] && timeout=300
20212
20213         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
20214
20215         restripe_status=$(do_facet mds1 $LCTL get_param -n \
20216                            mdt.*MDT0000.enable_dir_restripe)
20217         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=1"
20218         stack_trap "do_nodes $mdts $LCTL set_param \
20219                     mdt.*.enable_dir_restripe=$restripe_status"
20220
20221         test_mkdir -c $MDSCOUNT -H crush $DIR/$tdir
20222         createmany -m $DIR/$tdir/f 100 ||
20223                 error "create files under remote dir failed"
20224         createmany -d $DIR/$tdir/d 100 ||
20225                 error "create dirs under remote dir failed"
20226
20227         for c in $(seq $((MDSCOUNT - 1)) -1 1); do
20228                 local mdt_hash="crush"
20229
20230                 do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear >/dev/null"
20231                 $LFS setdirstripe -c $c $DIR/$tdir ||
20232                         error "split -c $c $tdir failed"
20233                 if (( MDS1_VERSION >= $(version_code 2.14.51) )); then
20234                         mdt_hash="$mdt_hash,fixed"
20235                 elif [ $c -eq 1 ]; then
20236                         mdt_hash="none"
20237                 fi
20238                 wait_update $HOSTNAME \
20239                         "$LFS getdirstripe -H $DIR/$tdir" $mdt_hash $timeout ||
20240                         error "dir merge not finished"
20241                 delta=$(do_nodes $mdts "lctl get_param -n mdt.*MDT*.md_stats" |
20242                         awk '/migrate/ {sum += $2} END { print sum }')
20243                 echo "$delta migrated when dir merge $((c + 1)) to $c stripes"
20244                 # delta is around total_files/stripe_count
20245                 (( delta < 200 / c + 4 )) ||
20246                         error "$delta files migrated >= $((200 / c + 4))"
20247         done
20248 }
20249 run_test 230p "dir merge"
20250
20251 test_230q() {
20252         (( MDSCOUNT > 1)) || skip "needs >= 2 MDTs"
20253         (( MDS1_VERSION >= $(version_code 2.13.52) )) ||
20254                 skip "Need MDS version at least 2.13.52"
20255
20256         local mdts=$(comma_list $(mdts_nodes))
20257         local saved_threshold=$(do_facet mds1 \
20258                         $LCTL get_param -n mdt.*-MDT0000.dir_split_count)
20259         local saved_delta=$(do_facet mds1 \
20260                         $LCTL get_param -n mdt.*-MDT0000.dir_split_delta)
20261         local threshold=100
20262         local delta=2
20263         local total=0
20264         local stripe_count=0
20265         local stripe_index
20266         local nr_files
20267         local create
20268
20269         # test with fewer files on ZFS
20270         [ "$mds1_FSTYPE" == "zfs" ] && threshold=40
20271
20272         stack_trap "do_nodes $mdts $LCTL set_param \
20273                     mdt.*.dir_split_count=$saved_threshold"
20274         stack_trap "do_nodes $mdts $LCTL set_param \
20275                     mdt.*.dir_split_delta=$saved_delta"
20276         stack_trap "do_nodes $mdts $LCTL set_param mdt.*.dir_restripe_nsonly=1"
20277         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_auto_split=1"
20278         do_nodes $mdts "$LCTL set_param mdt.*.dir_split_count=$threshold"
20279         do_nodes $mdts "$LCTL set_param mdt.*.dir_split_delta=$delta"
20280         do_nodes $mdts "$LCTL set_param mdt.*.dir_restripe_nsonly=0"
20281         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
20282
20283         $LFS mkdir -i -1 -c 1 $DIR/$tdir || error "mkdir $tdir failed"
20284         stripe_index=$($LFS getdirstripe -i $DIR/$tdir)
20285
20286         create=$((threshold * 3 / 2))
20287         while [ $stripe_count -lt $MDSCOUNT ]; do
20288                 createmany -m $DIR/$tdir/f $total $create ||
20289                         error "create sub files failed"
20290                 stat $DIR/$tdir > /dev/null
20291                 total=$((total + create))
20292                 stripe_count=$((stripe_count + delta))
20293                 [ $stripe_count -gt $MDSCOUNT ] && stripe_count=$MDSCOUNT
20294
20295                 wait_update $HOSTNAME \
20296                         "$LFS getdirstripe -c $DIR/$tdir" "$stripe_count" 40 ||
20297                         error "stripe count $($LFS getdirstripe -c $DIR/$tdir) != $stripe_count"
20298
20299                 wait_update $HOSTNAME \
20300                         "$LFS getdirstripe -H $DIR/$tdir" "crush" 200 ||
20301                         error "stripe hash $($LFS getdirstripe -H $DIR/$tdir) != crush"
20302
20303                 nr_files=$($LFS find -m 1 $DIR/$tdir | grep -c -w $stripe_index)
20304                 echo "$nr_files/$total files on MDT$stripe_index after split"
20305                 # allow 10% margin of imbalance with crush hash
20306                 (( $nr_files <= $total / $stripe_count + $create / 10)) ||
20307                         error "$nr_files files on MDT$stripe_index after split"
20308
20309                 nr_files=$($LFS find -type f $DIR/$tdir | wc -l)
20310                 [ $nr_files -eq $total ] ||
20311                         error "total sub files $nr_files != $total"
20312         done
20313
20314         (( MDS1_VERSION >= $(version_code 2.14.51) )) || return 0
20315
20316         echo "fixed layout directory won't auto split"
20317         $LFS migrate -m 0 $DIR/$tdir || error "migrate $tdir failed"
20318         wait_update $HOSTNAME "$LFS getdirstripe -H $DIR/$tdir" "crush,fixed" \
20319                 10 || error "stripe hash $($LFS getdirstripe -H $DIR/$tdir)"
20320         wait_update $HOSTNAME "$LFS getdirstripe -c $DIR/$tdir" 1 10 ||
20321                 error "stripe count $($LFS getdirstripe -c $DIR/$tdir)"
20322 }
20323 run_test 230q "dir auto split"
20324
20325 test_230r() {
20326         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
20327         [[ $MDSCOUNT -ge 2 ]] || skip_env "needs >= 2 MDTs"
20328         [[ $MDS1_VERSION -ge $(version_code 2.13.54) ]] ||
20329                 skip "Need MDS version at least 2.13.54"
20330
20331         # maximum amount of local locks:
20332         # parent striped dir - 2 locks
20333         # new stripe in parent to migrate to - 1 lock
20334         # source and target - 2 locks
20335         # Total 5 locks for regular file
20336         mkdir -p $DIR/$tdir
20337         $LFS mkdir -i1 -c2 $DIR/$tdir/dir1
20338         touch $DIR/$tdir/dir1/eee
20339
20340         # create 4 hardlink for 4 more locks
20341         # Total: 9 locks > RS_MAX_LOCKS (8)
20342         $LFS mkdir -i1 -c1 $DIR/$tdir/dir2
20343         $LFS mkdir -i1 -c1 $DIR/$tdir/dir3
20344         $LFS mkdir -i1 -c1 $DIR/$tdir/dir4
20345         $LFS mkdir -i1 -c1 $DIR/$tdir/dir5
20346         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir2/eee
20347         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir3/eee
20348         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir4/eee
20349         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir5/eee
20350
20351         cancel_lru_locks mdc
20352
20353         $LFS migrate -m1 -c1 $DIR/$tdir/dir1 ||
20354                 error "migrate dir fails"
20355
20356         rm -rf $DIR/$tdir || error "rm dir failed after migration"
20357 }
20358 run_test 230r "migrate with too many local locks"
20359
20360 test_230s() {
20361         [ $MDS1_VERSION -ge $(version_code 2.13.57) ] ||
20362                 skip "Need MDS version at least 2.13.57"
20363
20364         local mdts=$(comma_list $(mdts_nodes))
20365         local restripe_status=$(do_facet mds1 $LCTL get_param -n \
20366                                 mdt.*MDT0000.enable_dir_restripe)
20367
20368         stack_trap "do_nodes $mdts $LCTL set_param \
20369                     mdt.*.enable_dir_restripe=$restripe_status"
20370
20371         local st
20372         for st in 0 1; do
20373                 do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=$st"
20374                 test_mkdir $DIR/$tdir
20375                 $LFS mkdir $DIR/$tdir |& grep "File exists" ||
20376                         error "$LFS mkdir doesn't return -EEXIST if target exists"
20377                 rmdir $DIR/$tdir
20378         done
20379 }
20380 run_test 230s "lfs mkdir should return -EEXIST if target exists"
20381
20382 test_230t()
20383 {
20384         [[ $MDSCOUNT -ge 2 ]] || skip_env "needs >= 2 MDTs"
20385         [[ $MDS1_VERSION -ge $(version_code 2.14.50) ]] ||
20386                 skip "Need MDS version at least 2.14.50"
20387
20388         test_mkdir $DIR/$tdir || error "mkdir $tdir failed"
20389         test_mkdir $DIR/$tdir/subdir || error "mkdir subdir failed"
20390         $LFS project -p 1 -s $DIR/$tdir ||
20391                 error "set $tdir project id failed"
20392         $LFS project -p 2 -s $DIR/$tdir/subdir ||
20393                 error "set subdir project id failed"
20394         $LFS migrate -m 1 -c $MDSCOUNT $DIR/$tdir || error "migrate failed"
20395 }
20396 run_test 230t "migrate directory with project ID set"
20397
20398 test_230u()
20399 {
20400         (( MDSCOUNT > 3 )) || skip_env "needs >= 4 MDTs"
20401         (( MDS1_VERSION >= $(version_code 2.14.53) )) ||
20402                 skip "Need MDS version at least 2.14.53"
20403
20404         local count
20405
20406         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
20407         mkdir $DIR/$tdir/sub{0..99} || error "mkdir sub failed"
20408         $LFS migrate -m -1 $DIR/$tdir/sub{0..99} || error "migrate sub failed"
20409         for i in $(seq 0 $((MDSCOUNT - 1))); do
20410                 count=$($LFS getstripe -m $DIR/$tdir/sub* | grep -c ^$i)
20411                 echo "$count dirs migrated to MDT$i"
20412         done
20413         count=$($LFS getstripe -m $DIR/$tdir/sub* | sort -u | wc -l)
20414         (( count >= MDSCOUNT - 1 )) || error "dirs migrated to $count MDTs"
20415 }
20416 run_test 230u "migrate directory by QOS"
20417
20418 test_230v()
20419 {
20420         (( MDSCOUNT > 3 )) || skip_env "needs >= 4 MDTs"
20421         (( MDS1_VERSION >= $(version_code 2.14.53) )) ||
20422                 skip "Need MDS version at least 2.14.53"
20423
20424         local count
20425
20426         mkdir $DIR/$tdir || error "mkdir $tdir failed"
20427         mkdir $DIR/$tdir/sub{0..99} || error "mkdir sub failed"
20428         $LFS migrate -m 0,2,1 $DIR/$tdir || error "migrate $tdir failed"
20429         for i in $(seq 0 $((MDSCOUNT - 1))); do
20430                 count=$($LFS getstripe -m $DIR/$tdir/sub* | grep -c ^$i)
20431                 echo "$count subdirs migrated to MDT$i"
20432                 (( i == 3 )) && (( count > 0 )) &&
20433                         error "subdir shouldn't be migrated to MDT3"
20434         done
20435         count=$($LFS getstripe -m $DIR/$tdir/sub* | sort -u | wc -l)
20436         (( count == 3 )) || error "dirs migrated to $count MDTs"
20437 }
20438 run_test 230v "subdir migrated to the MDT where its parent is located"
20439
20440 test_230w() {
20441         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
20442         (( MDS1_VERSION >= $(version_code 2.14.53) )) ||
20443                 skip "Need MDS version at least 2.14.53"
20444
20445         mkdir -p $DIR/$tdir/sub || error "mkdir failed"
20446
20447         $LFS migrate -m 1 -c $MDSCOUNT -d $DIR/$tdir ||
20448                 error "migrate failed"
20449
20450         (( $($LFS getdirstripe -c $DIR/$tdir) == MDSCOUNT )) ||
20451                 error "$tdir stripe count mismatch"
20452
20453         (( $($LFS getdirstripe -c $DIR/$tdir/sub) == 0 )) ||
20454                 error "$tdir/sub is striped"
20455 }
20456 run_test 230w "non-recursive mode dir migration"
20457
20458 test_231a()
20459 {
20460         # For simplicity this test assumes that max_pages_per_rpc
20461         # is the same across all OSCs
20462         local max_pages=$($LCTL get_param -n osc.*.max_pages_per_rpc | head -n1)
20463         local bulk_size=$((max_pages * PAGE_SIZE))
20464         local brw_size=$(do_facet ost1 $LCTL get_param -n obdfilter.*.brw_size |
20465                                        head -n 1)
20466
20467         mkdir -p $DIR/$tdir
20468         $LFS setstripe -S ${brw_size}M $DIR/$tdir ||
20469                 error "failed to set stripe with -S ${brw_size}M option"
20470
20471         # clear the OSC stats
20472         $LCTL set_param osc.*.stats=0 &>/dev/null
20473         stop_writeback
20474
20475         # Client writes $bulk_size - there must be 1 rpc for $max_pages.
20476         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=$bulk_size count=1 \
20477                 oflag=direct &>/dev/null || error "dd failed"
20478
20479         sync; sleep 1; sync # just to be safe
20480         local nrpcs=$($LCTL get_param osc.*.stats |awk '/ost_write/ {print $2}')
20481         if [ x$nrpcs != "x1" ]; then
20482                 $LCTL get_param osc.*.stats
20483                 error "found $nrpcs ost_write RPCs, not 1 as expected"
20484         fi
20485
20486         start_writeback
20487         # Drop the OSC cache, otherwise we will read from it
20488         cancel_lru_locks osc
20489
20490         # clear the OSC stats
20491         $LCTL set_param osc.*.stats=0 &>/dev/null
20492
20493         # Client reads $bulk_size.
20494         dd if=$DIR/$tdir/$tfile of=/dev/null bs=$bulk_size count=1 \
20495                 iflag=direct &>/dev/null || error "dd failed"
20496
20497         nrpcs=$($LCTL get_param osc.*.stats | awk '/ost_read/ { print $2 }')
20498         if [ x$nrpcs != "x1" ]; then
20499                 $LCTL get_param osc.*.stats
20500                 error "found $nrpcs ost_read RPCs, not 1 as expected"
20501         fi
20502 }
20503 run_test 231a "checking that reading/writing of BRW RPC size results in one RPC"
20504
20505 test_231b() {
20506         mkdir -p $DIR/$tdir
20507         local i
20508         for i in {0..1023}; do
20509                 dd if=/dev/zero of=$DIR/$tdir/$tfile conv=notrunc \
20510                         seek=$((2 * i)) bs=4096 count=1 &>/dev/null ||
20511                         error "dd of=$DIR/$tdir/$tfile seek=$((2 * i)) failed"
20512         done
20513         sync
20514 }
20515 run_test 231b "must not assert on fully utilized OST request buffer"
20516
20517 test_232a() {
20518         mkdir -p $DIR/$tdir
20519         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
20520
20521         #define OBD_FAIL_LDLM_OST_LVB            0x31c
20522         do_facet ost1 $LCTL set_param fail_loc=0x31c
20523
20524         # ignore dd failure
20525         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=1 || true
20526
20527         do_facet ost1 $LCTL set_param fail_loc=0
20528         umount_client $MOUNT || error "umount failed"
20529         mount_client $MOUNT || error "mount failed"
20530         stop ost1 || error "cannot stop ost1"
20531         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
20532 }
20533 run_test 232a "failed lock should not block umount"
20534
20535 test_232b() {
20536         [ $MDS1_VERSION -ge $(version_code 2.10.58) ] ||
20537                 skip "Need MDS version at least 2.10.58"
20538
20539         mkdir -p $DIR/$tdir
20540         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
20541         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=1
20542         sync
20543         cancel_lru_locks osc
20544
20545         #define OBD_FAIL_LDLM_OST_LVB            0x31c
20546         do_facet ost1 $LCTL set_param fail_loc=0x31c
20547
20548         # ignore failure
20549         $LFS data_version $DIR/$tdir/$tfile || true
20550
20551         do_facet ost1 $LCTL set_param fail_loc=0
20552         umount_client $MOUNT || error "umount failed"
20553         mount_client $MOUNT || error "mount failed"
20554         stop ost1 || error "cannot stop ost1"
20555         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
20556 }
20557 run_test 232b "failed data version lock should not block umount"
20558
20559 test_233a() {
20560         [ $MDS1_VERSION -ge $(version_code 2.3.64) ] ||
20561                 skip "Need MDS version at least 2.3.64"
20562         [ -n "$FILESET" ] && skip_env "SKIP due to FILESET set"
20563
20564         local fid=$($LFS path2fid $MOUNT)
20565
20566         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
20567                 error "cannot access $MOUNT using its FID '$fid'"
20568 }
20569 run_test 233a "checking that OBF of the FS root succeeds"
20570
20571 test_233b() {
20572         [ $MDS1_VERSION -ge $(version_code 2.5.90) ] ||
20573                 skip "Need MDS version at least 2.5.90"
20574         [ -n "$FILESET" ] && skip_env "SKIP due to FILESET set"
20575
20576         local fid=$($LFS path2fid $MOUNT/.lustre)
20577
20578         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
20579                 error "cannot access $MOUNT/.lustre using its FID '$fid'"
20580
20581         fid=$($LFS path2fid $MOUNT/.lustre/fid)
20582         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
20583                 error "cannot access $MOUNT/.lustre/fid using its FID '$fid'"
20584 }
20585 run_test 233b "checking that OBF of the FS .lustre succeeds"
20586
20587 test_234() {
20588         local p="$TMP/sanityN-$TESTNAME.parameters"
20589         save_lustre_params client "llite.*.xattr_cache" > $p
20590         lctl set_param llite.*.xattr_cache 1 ||
20591                 skip_env "xattr cache is not supported"
20592
20593         mkdir -p $DIR/$tdir || error "mkdir failed"
20594         touch $DIR/$tdir/$tfile || error "touch failed"
20595         # OBD_FAIL_LLITE_XATTR_ENOMEM
20596         $LCTL set_param fail_loc=0x1405
20597         getfattr -n user.attr $DIR/$tdir/$tfile &&
20598                 error "getfattr should have failed with ENOMEM"
20599         $LCTL set_param fail_loc=0x0
20600         rm -rf $DIR/$tdir
20601
20602         restore_lustre_params < $p
20603         rm -f $p
20604 }
20605 run_test 234 "xattr cache should not crash on ENOMEM"
20606
20607 test_235() {
20608         [ $MDS1_VERSION -lt $(version_code 2.4.52) ] &&
20609                 skip "Need MDS version at least 2.4.52"
20610
20611         flock_deadlock $DIR/$tfile
20612         local RC=$?
20613         case $RC in
20614                 0)
20615                 ;;
20616                 124) error "process hangs on a deadlock"
20617                 ;;
20618                 *) error "error executing flock_deadlock $DIR/$tfile"
20619                 ;;
20620         esac
20621 }
20622 run_test 235 "LU-1715: flock deadlock detection does not work properly"
20623
20624 #LU-2935
20625 test_236() {
20626         check_swap_layouts_support
20627
20628         local ref1=/etc/passwd
20629         local ref2=/etc/group
20630         local file1=$DIR/$tdir/f1
20631         local file2=$DIR/$tdir/f2
20632
20633         test_mkdir -c1 $DIR/$tdir
20634         $LFS setstripe -c 1 $file1 || error "cannot setstripe on '$file1': rc = $?"
20635         cp $ref1 $file1 || error "cp $ref1 $file1 failed: rc = $?"
20636         $LFS setstripe -c 2 $file2 || error "cannot setstripe on '$file2': rc = $?"
20637         cp $ref2 $file2 || error "cp $ref2 $file2 failed: rc = $?"
20638         local fd=$(free_fd)
20639         local cmd="exec $fd<>$file2"
20640         eval $cmd
20641         rm $file2
20642         $LFS swap_layouts $file1 /proc/self/fd/${fd} ||
20643                 error "cannot swap layouts of '$file1' and /proc/self/fd/${fd}"
20644         cmd="exec $fd>&-"
20645         eval $cmd
20646         cmp $ref2 $file1 || error "content compare failed ($ref2 != $file1)"
20647
20648         #cleanup
20649         rm -rf $DIR/$tdir
20650 }
20651 run_test 236 "Layout swap on open unlinked file"
20652
20653 # LU-4659 linkea consistency
20654 test_238() {
20655         [[ $MDS1_VERSION -gt $(version_code 2.5.57) ]] ||
20656                 [[ $MDS1_VERSION -gt $(version_code 2.5.1) &&
20657                    $MDS1_VERSION -lt $(version_code 2.5.50) ]] ||
20658                 skip "Need MDS version at least 2.5.58 or 2.5.2+"
20659
20660         touch $DIR/$tfile
20661         ln $DIR/$tfile $DIR/$tfile.lnk
20662         touch $DIR/$tfile.new
20663         mv $DIR/$tfile.new $DIR/$tfile
20664         local fid1=$($LFS path2fid $DIR/$tfile)
20665         local fid2=$($LFS path2fid $DIR/$tfile.lnk)
20666         local path1=$($LFS fid2path $FSNAME "$fid1")
20667         [ $tfile == $path1 ] || error "linkea inconsistent: $tfile $fid1 $path1"
20668         local path2=$($LFS fid2path $FSNAME "$fid2")
20669         [ $tfile.lnk == $path2 ] ||
20670                 error "linkea inconsistent: $tfile.lnk $fid2 $path2!"
20671         rm -f $DIR/$tfile*
20672 }
20673 run_test 238 "Verify linkea consistency"
20674
20675 test_239A() { # was test_239
20676         [ $MDS1_VERSION -lt $(version_code 2.5.60) ] &&
20677                 skip "Need MDS version at least 2.5.60"
20678
20679         local list=$(comma_list $(mdts_nodes))
20680
20681         mkdir -p $DIR/$tdir
20682         createmany -o $DIR/$tdir/f- 5000
20683         unlinkmany $DIR/$tdir/f- 5000
20684         [ $MDS1_VERSION -gt $(version_code 2.10.4) ] &&
20685                 do_nodes $list "lctl set_param -n osp.*.force_sync=1"
20686         changes=$(do_nodes $list "lctl get_param -n osp.*MDT*.sync_changes \
20687                         osp.*MDT*.sync_in_flight" | calc_sum)
20688         [ "$changes" -eq 0 ] || error "$changes not synced"
20689 }
20690 run_test 239A "osp_sync test"
20691
20692 test_239a() { #LU-5297
20693         remote_mds_nodsh && skip "remote MDS with nodsh"
20694
20695         touch $DIR/$tfile
20696         #define OBD_FAIL_OSP_CHECK_INVALID_REC     0x2100
20697         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2100
20698         chgrp $RUNAS_GID $DIR/$tfile
20699         wait_delete_completed
20700 }
20701 run_test 239a "process invalid osp sync record correctly"
20702
20703 test_239b() { #LU-5297
20704         remote_mds_nodsh && skip "remote MDS with nodsh"
20705
20706         touch $DIR/$tfile1
20707         #define OBD_FAIL_OSP_CHECK_ENOMEM     0x2101
20708         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2101
20709         chgrp $RUNAS_GID $DIR/$tfile1
20710         wait_delete_completed
20711         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
20712         touch $DIR/$tfile2
20713         chgrp $RUNAS_GID $DIR/$tfile2
20714         wait_delete_completed
20715 }
20716 run_test 239b "process osp sync record with ENOMEM error correctly"
20717
20718 test_240() {
20719         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20720         remote_mds_nodsh && skip "remote MDS with nodsh"
20721
20722         mkdir -p $DIR/$tdir
20723
20724         $LFS mkdir -i 0 $DIR/$tdir/d0 ||
20725                 error "failed to mkdir $DIR/$tdir/d0 on MDT0"
20726         $LFS mkdir -i 1 $DIR/$tdir/d0/d1 ||
20727                 error "failed to mkdir $DIR/$tdir/d0/d1 on MDT1"
20728
20729         umount_client $MOUNT || error "umount failed"
20730         #define OBD_FAIL_TGT_DELAY_CONDITIONAL   0x713
20731         do_facet mds2 lctl set_param fail_loc=0x713 fail_val=1
20732         mount_client $MOUNT || error "failed to mount client"
20733
20734         echo "stat $DIR/$tdir/d0/d1, should not fail/ASSERT"
20735         stat $DIR/$tdir/d0/d1 || error "fail to stat $DIR/$tdir/d0/d1"
20736 }
20737 run_test 240 "race between ldlm enqueue and the connection RPC (no ASSERT)"
20738
20739 test_241_bio() {
20740         local count=$1
20741         local bsize=$2
20742
20743         for LOOP in $(seq $count); do
20744                 dd if=$DIR/$tfile of=/dev/null bs=$bsize count=1 2>/dev/null
20745                 cancel_lru_locks $OSC || true
20746         done
20747 }
20748
20749 test_241_dio() {
20750         local count=$1
20751         local bsize=$2
20752
20753         for LOOP in $(seq $1); do
20754                 dd if=$DIR/$tfile of=/dev/null bs=$bsize count=1 iflag=direct \
20755                         2>/dev/null
20756         done
20757 }
20758
20759 test_241a() { # was test_241
20760         local bsize=$PAGE_SIZE
20761
20762         (( bsize < 40960 )) && bsize=40960
20763         dd if=/dev/zero of=$DIR/$tfile count=1 bs=$bsize
20764         ls -la $DIR/$tfile
20765         cancel_lru_locks $OSC
20766         test_241_bio 1000 $bsize &
20767         PID=$!
20768         test_241_dio 1000 $bsize
20769         wait $PID
20770 }
20771 run_test 241a "bio vs dio"
20772
20773 test_241b() {
20774         local bsize=$PAGE_SIZE
20775
20776         (( bsize < 40960 )) && bsize=40960
20777         dd if=/dev/zero of=$DIR/$tfile count=1 bs=$bsize
20778         ls -la $DIR/$tfile
20779         test_241_dio 1000 $bsize &
20780         PID=$!
20781         test_241_dio 1000 $bsize
20782         wait $PID
20783 }
20784 run_test 241b "dio vs dio"
20785
20786 test_242() {
20787         remote_mds_nodsh && skip "remote MDS with nodsh"
20788
20789         mkdir_on_mdt0 $DIR/$tdir
20790         touch $DIR/$tdir/$tfile
20791
20792         #define OBD_FAIL_MDS_READPAGE_PACK      0x105
20793         do_facet mds1 lctl set_param fail_loc=0x105
20794         /bin/ls $DIR/$tdir && error "ls $DIR/$tdir should fail"
20795
20796         do_facet mds1 lctl set_param fail_loc=0
20797         /bin/ls $DIR/$tdir || error "ls $DIR/$tdir failed"
20798 }
20799 run_test 242 "mdt_readpage failure should not cause directory unreadable"
20800
20801 test_243()
20802 {
20803         test_mkdir $DIR/$tdir
20804         group_lock_test -d $DIR/$tdir || error "A group lock test failed"
20805 }
20806 run_test 243 "various group lock tests"
20807
20808 test_244a()
20809 {
20810         test_mkdir $DIR/$tdir
20811         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=35
20812         sendfile_grouplock $DIR/$tdir/$tfile || \
20813                 error "sendfile+grouplock failed"
20814         rm -rf $DIR/$tdir
20815 }
20816 run_test 244a "sendfile with group lock tests"
20817
20818 test_244b()
20819 {
20820         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
20821
20822         local threads=50
20823         local size=$((1024*1024))
20824
20825         test_mkdir $DIR/$tdir
20826         for i in $(seq 1 $threads); do
20827                 local file=$DIR/$tdir/file_$((i / 10))
20828                 $MULTIOP $file OG1234w$size_$((i % 3))w$size_$((i % 4))g1234c &
20829                 local pids[$i]=$!
20830         done
20831         for i in $(seq 1 $threads); do
20832                 wait ${pids[$i]}
20833         done
20834 }
20835 run_test 244b "multi-threaded write with group lock"
20836
20837 test_245() {
20838         local flagname="multi_mod_rpcs"
20839         local connect_data_name="max_mod_rpcs"
20840         local out
20841
20842         # check if multiple modify RPCs flag is set
20843         out=$($LCTL get_param mdc.$FSNAME-MDT0000-*.import |
20844                 grep "connect_flags:")
20845         echo "$out"
20846
20847         echo "$out" | grep -qw $flagname
20848         if [ $? -ne 0 ]; then
20849                 echo "connect flag $flagname is not set"
20850                 return
20851         fi
20852
20853         # check if multiple modify RPCs data is set
20854         out=$($LCTL get_param mdc.$FSNAME-MDT0000-*.import)
20855         echo "$out"
20856
20857         echo "$out" | grep -qw $connect_data_name ||
20858                 error "import should have connect data $connect_data_name"
20859 }
20860 run_test 245 "check mdc connection flag/data: multiple modify RPCs"
20861
20862 cleanup_247() {
20863         local submount=$1
20864
20865         trap 0
20866         umount_client $submount
20867         rmdir $submount
20868 }
20869
20870 test_247a() {
20871         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
20872                 grep -q subtree ||
20873                 skip_env "Fileset feature is not supported"
20874
20875         local submount=${MOUNT}_$tdir
20876
20877         mkdir $MOUNT/$tdir
20878         mkdir -p $submount || error "mkdir $submount failed"
20879         FILESET="$FILESET/$tdir" mount_client $submount ||
20880                 error "mount $submount failed"
20881         trap "cleanup_247 $submount" EXIT
20882         echo foo > $submount/$tfile || error "write $submount/$tfile failed"
20883         [ $(cat $MOUNT/$tdir/$tfile) = "foo" ] ||
20884                 error "read $MOUNT/$tdir/$tfile failed"
20885         cleanup_247 $submount
20886 }
20887 run_test 247a "mount subdir as fileset"
20888
20889 test_247b() {
20890         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
20891                 skip_env "Fileset feature is not supported"
20892
20893         local submount=${MOUNT}_$tdir
20894
20895         rm -rf $MOUNT/$tdir
20896         mkdir -p $submount || error "mkdir $submount failed"
20897         SKIP_FILESET=1
20898         FILESET="$FILESET/$tdir" mount_client $submount &&
20899                 error "mount $submount should fail"
20900         rmdir $submount
20901 }
20902 run_test 247b "mount subdir that dose not exist"
20903
20904 test_247c() {
20905         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
20906                 skip_env "Fileset feature is not supported"
20907
20908         local submount=${MOUNT}_$tdir
20909
20910         mkdir -p $MOUNT/$tdir/dir1
20911         mkdir -p $submount || error "mkdir $submount failed"
20912         trap "cleanup_247 $submount" EXIT
20913         FILESET="$FILESET/$tdir" mount_client $submount ||
20914                 error "mount $submount failed"
20915         local fid=$($LFS path2fid $MOUNT/)
20916         $LFS fid2path $submount $fid && error "fid2path should fail"
20917         cleanup_247 $submount
20918 }
20919 run_test 247c "running fid2path outside subdirectory root"
20920
20921 test_247d() {
20922         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
20923                 skip "Fileset feature is not supported"
20924
20925         local submount=${MOUNT}_$tdir
20926
20927         mkdir -p $MOUNT/$tdir/dir1
20928         mkdir -p $submount || error "mkdir $submount failed"
20929         FILESET="$FILESET/$tdir" mount_client $submount ||
20930                 error "mount $submount failed"
20931         trap "cleanup_247 $submount" EXIT
20932
20933         local td=$submount/dir1
20934         local fid=$($LFS path2fid $td)
20935         [ -z "$fid" ] && error "path2fid unable to get $td FID"
20936
20937         # check that we get the same pathname back
20938         local rootpath
20939         local found
20940         for rootpath in "$submount" "$submount///" "$submount/dir1"; do
20941                 echo "$rootpath $fid"
20942                 found=$($LFS fid2path $rootpath "$fid")
20943                 [ -n "found" ] || error "fid2path should succeed"
20944                 [ "$found" == "$td" ] || error "fid2path $found != $td"
20945         done
20946         # check wrong root path format
20947         rootpath=$submount"_wrong"
20948         found=$($LFS fid2path $rootpath "$fid")
20949         [ -z "$found" ] || error "fid2path should fail ($rootpath != $submount)"
20950
20951         cleanup_247 $submount
20952 }
20953 run_test 247d "running fid2path inside subdirectory root"
20954
20955 # LU-8037
20956 test_247e() {
20957         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
20958                 grep -q subtree ||
20959                 skip "Fileset feature is not supported"
20960
20961         local submount=${MOUNT}_$tdir
20962
20963         mkdir $MOUNT/$tdir
20964         mkdir -p $submount || error "mkdir $submount failed"
20965         FILESET="$FILESET/.." mount_client $submount &&
20966                 error "mount $submount should fail"
20967         rmdir $submount
20968 }
20969 run_test 247e "mount .. as fileset"
20970
20971 test_247f() {
20972         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20973         [ $MDS1_VERSION -lt $(version_code 2.13.52) ] &&
20974                 skip "Need at least version 2.13.52"
20975         [ $CLIENT_VERSION -lt $(version_code 2.14.50) ] &&
20976                 skip "Need at least version 2.14.50"
20977         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
20978                 grep -q subtree ||
20979                 skip "Fileset feature is not supported"
20980
20981         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
20982         $LFS mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir/remote ||
20983                 error "mkdir remote failed"
20984         $LFS mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir/remote/subdir ||
20985                 error "mkdir remote/subdir failed"
20986         $LFS mkdir -i 0 -c $MDSCOUNT $DIR/$tdir/striped ||
20987                 error "mkdir striped failed"
20988         mkdir $DIR/$tdir/striped/subdir || error "mkdir striped/subdir failed"
20989
20990         local submount=${MOUNT}_$tdir
20991
20992         mkdir -p $submount || error "mkdir $submount failed"
20993         stack_trap "rmdir $submount"
20994
20995         local dir
20996         local stat
20997         local fileset=$FILESET
20998         local mdts=$(comma_list $(mdts_nodes))
20999
21000         stat=$(do_facet mds1 $LCTL get_param -n \
21001                 mdt.*MDT0000.enable_remote_subdir_mount)
21002         stack_trap "do_nodes $mdts $LCTL set_param \
21003                 mdt.*.enable_remote_subdir_mount=$stat"
21004
21005         do_nodes $mdts "$LCTL set_param mdt.*.enable_remote_subdir_mount=0"
21006         stack_trap "umount_client $submount"
21007         FILESET="$fileset/$tdir/remote" mount_client $submount &&
21008                 error "mount remote dir $dir should fail"
21009
21010         for dir in $tdir/remote/subdir $tdir/striped $tdir/striped/subdir \
21011                 $tdir/striped/. ; do
21012                 FILESET="$fileset/$dir" mount_client $submount ||
21013                         error "mount $dir failed"
21014                 umount_client $submount
21015         done
21016
21017         do_nodes $mdts "$LCTL set_param mdt.*.enable_remote_subdir_mount=1"
21018         FILESET="$fileset/$tdir/remote" mount_client $submount ||
21019                 error "mount $tdir/remote failed"
21020 }
21021 run_test 247f "mount striped or remote directory as fileset"
21022
21023 test_247g() {
21024         [ $MDSCOUNT -lt 4 ] && skip_env "needs >= 4 MDTs"
21025         [ $CLIENT_VERSION -lt $(version_code 2.14.50) ] &&
21026                 skip "Need at least version 2.14.50"
21027
21028         $LFS mkdir -i 0 -c 4 -H fnv_1a_64 $DIR/$tdir ||
21029                 error "mkdir $tdir failed"
21030         touch $DIR/$tdir/$tfile || error "touch $tfile failed"
21031
21032         local submount=${MOUNT}_$tdir
21033
21034         mkdir -p $submount || error "mkdir $submount failed"
21035         stack_trap "rmdir $submount"
21036
21037         FILESET="$fileset/$tdir" mount_client $submount ||
21038                 error "mount $dir failed"
21039         stack_trap "umount $submount"
21040
21041         local mdts=$(comma_list $(mdts_nodes))
21042
21043         local nrpcs
21044
21045         stat $submount > /dev/null
21046         cancel_lru_locks $MDC
21047         stat $submount > /dev/null
21048         stat $submount/$tfile > /dev/null
21049         do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear > /dev/null"
21050         stat $submount/$tfile > /dev/null
21051         nrpcs=$(do_nodes $mdts "lctl get_param -n mdt.*.md_stats" |
21052                 awk '/getattr/ {sum += $2} END {print sum}')
21053
21054         [ -z "$nrpcs" ] || error "$nrpcs extra getattr sent"
21055 }
21056 run_test 247g "mount striped directory as fileset caches ROOT lookup lock"
21057
21058 test_248a() {
21059         local fast_read_sav=$($LCTL get_param -n llite.*.fast_read 2>/dev/null)
21060         [ -z "$fast_read_sav" ] && skip "no fast read support"
21061
21062         # create a large file for fast read verification
21063         dd if=/dev/zero of=$DIR/$tfile bs=1M count=128 > /dev/null 2>&1
21064
21065         # make sure the file is created correctly
21066         $CHECKSTAT -s $((128*1024*1024)) $DIR/$tfile ||
21067                 { rm -f $DIR/$tfile; skip "file creation error"; }
21068
21069         echo "Test 1: verify that fast read is 4 times faster on cache read"
21070
21071         # small read with fast read enabled
21072         $LCTL set_param -n llite.*.fast_read=1
21073         local t_fast=$(dd if=$DIR/$tfile of=/dev/null bs=4k 2>&1 |
21074                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
21075                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
21076         # small read with fast read disabled
21077         $LCTL set_param -n llite.*.fast_read=0
21078         local t_slow=$(dd if=$DIR/$tfile of=/dev/null bs=4k 2>&1 |
21079                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
21080                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
21081
21082         # verify that fast read is 4 times faster for cache read
21083         [ $(bc <<< "4 * $t_fast < $t_slow") -eq 1 ] ||
21084                 error_not_in_vm "fast read was not 4 times faster: " \
21085                            "$t_fast vs $t_slow"
21086
21087         echo "Test 2: verify the performance between big and small read"
21088         $LCTL set_param -n llite.*.fast_read=1
21089
21090         # 1k non-cache read
21091         cancel_lru_locks osc
21092         local t_1k=$(dd if=$DIR/$tfile of=/dev/null bs=1k 2>&1 |
21093                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
21094                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
21095
21096         # 1M non-cache read
21097         cancel_lru_locks osc
21098         local t_1m=$(dd if=$DIR/$tfile of=/dev/null bs=1k 2>&1 |
21099                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
21100                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
21101
21102         # verify that big IO is not 4 times faster than small IO
21103         [ $(bc <<< "4 * $t_1k >= $t_1m") -eq 1 ] ||
21104                 error_not_in_vm "bigger IO is way too fast: $t_1k vs $t_1m"
21105
21106         $LCTL set_param -n llite.*.fast_read=$fast_read_sav
21107         rm -f $DIR/$tfile
21108 }
21109 run_test 248a "fast read verification"
21110
21111 test_248b() {
21112         # Default short_io_bytes=16384, try both smaller and larger sizes.
21113         # Lustre O_DIRECT read and write needs to be a multiple of PAGE_SIZE.
21114         # 6017024 = 2^12*13*113 = 47008*128 = 11752*512 = 4096*1469 = 53248*113
21115         echo "bs=53248 count=113 normal buffered write"
21116         dd if=/dev/urandom of=$TMP/$tfile.0 bs=53248 count=113 ||
21117                 error "dd of initial data file failed"
21118         stack_trap "rm -f $DIR/$tfile.[0-3] $TMP/$tfile.[0-3]" EXIT
21119
21120         echo "bs=47008 count=128 oflag=dsync normal write $tfile.0"
21121         dd if=$TMP/$tfile.0 of=$DIR/$tfile.0 bs=47008 count=128 oflag=dsync ||
21122                 error "dd with sync normal writes failed"
21123         cmp $TMP/$tfile.0 $DIR/$tfile.0 || error "compare $DIR/$tfile.0 failed"
21124
21125         echo "bs=11752 count=512 oflag=dsync small write $tfile.1"
21126         dd if=$TMP/$tfile.0 of=$DIR/$tfile.1 bs=11752 count=512 oflag=dsync ||
21127                 error "dd with sync small writes failed"
21128         cmp $TMP/$tfile.0 $DIR/$tfile.1 || error "compare $DIR/$tfile.1 failed"
21129
21130         cancel_lru_locks osc
21131
21132         # calculate the small O_DIRECT size and count for the client PAGE_SIZE
21133         local num=$((13 * 113 / (PAGE_SIZE / 4096)))
21134         echo "bs=$PAGE_SIZE count=$num iflag=direct small read $tfile.1"
21135         dd if=$DIR/$tfile.1 of=$TMP/$tfile.1 bs=$PAGE_SIZE count=$num \
21136                 iflag=direct || error "dd with O_DIRECT small read failed"
21137         # adjust bytes checked to handle larger PAGE_SIZE for ARM/PPC
21138         cmp --bytes=$((PAGE_SIZE * num)) $TMP/$tfile.0 $TMP/$tfile.1 ||
21139                 error "compare $TMP/$tfile.1 failed"
21140
21141         local save=$($LCTL get_param -n osc.*OST000*.short_io_bytes | head -n 1)
21142         stack_trap "$LCTL set_param osc.$FSNAME-*.short_io_bytes=$save" EXIT
21143
21144         # just to see what the maximum tunable value is, and test parsing
21145         echo "test invalid parameter 2MB"
21146         $LCTL set_param osc.$FSNAME-OST0000*.short_io_bytes=2M &&
21147                 error "too-large short_io_bytes allowed"
21148         echo "test maximum parameter 512KB"
21149         # if we can set a larger short_io_bytes, run test regardless of version
21150         if ! $LCTL set_param osc.$FSNAME-OST0000*.short_io_bytes=512K; then
21151                 # older clients may not allow setting it this large, that's OK
21152                 [ $CLIENT_VERSION -ge $(version_code 2.13.50) ] ||
21153                         skip "Need at least client version 2.13.50"
21154                 error "medium short_io_bytes failed"
21155         fi
21156         $LCTL get_param osc.$FSNAME-OST0000*.short_io_bytes
21157         size=$($LCTL get_param -n osc.$FSNAME-OST0000*.short_io_bytes)
21158
21159         echo "test large parameter 64KB"
21160         $LCTL set_param osc.$FSNAME-*.short_io_bytes=65536
21161         $LCTL get_param osc.$FSNAME-OST0000*.short_io_bytes
21162
21163         echo "bs=47008 count=128 oflag=dsync large write $tfile.2"
21164         dd if=$TMP/$tfile.0 of=$DIR/$tfile.2 bs=47008 count=128 oflag=dsync ||
21165                 error "dd with sync large writes failed"
21166         cmp $TMP/$tfile.0 $DIR/$tfile.2 || error "compare $DIR/$tfile.2 failed"
21167
21168         # calculate the large O_DIRECT size and count for the client PAGE_SIZE
21169         local size=$(((4096 * 13 + PAGE_SIZE - 1) / PAGE_SIZE * PAGE_SIZE))
21170         num=$((113 * 4096 / PAGE_SIZE))
21171         echo "bs=$size count=$num oflag=direct large write $tfile.3"
21172         dd if=$TMP/$tfile.0 of=$DIR/$tfile.3 bs=$size count=$num oflag=direct ||
21173                 error "dd with O_DIRECT large writes failed"
21174         cmp --bytes=$((size * num)) $TMP/$tfile.0 $DIR/$tfile.3 ||
21175                 error "compare $DIR/$tfile.3 failed"
21176
21177         cancel_lru_locks osc
21178
21179         echo "bs=$size count=$num iflag=direct large read $tfile.2"
21180         dd if=$DIR/$tfile.2 of=$TMP/$tfile.2 bs=$size count=$num iflag=direct ||
21181                 error "dd with O_DIRECT large read failed"
21182         cmp --bytes=$((size * num)) $TMP/$tfile.0 $TMP/$tfile.2 ||
21183                 error "compare $TMP/$tfile.2 failed"
21184
21185         echo "bs=$size count=$num iflag=direct large read $tfile.3"
21186         dd if=$DIR/$tfile.3 of=$TMP/$tfile.3 bs=$size count=$num iflag=direct ||
21187                 error "dd with O_DIRECT large read failed"
21188         cmp --bytes=$((size * num)) $TMP/$tfile.0 $TMP/$tfile.3 ||
21189                 error "compare $TMP/$tfile.3 failed"
21190 }
21191 run_test 248b "test short_io read and write for both small and large sizes"
21192
21193 test_249() { # LU-7890
21194         [ $MDS1_VERSION -lt $(version_code 2.8.53) ] &&
21195                 skip "Need at least version 2.8.54"
21196
21197         rm -f $DIR/$tfile
21198         $LFS setstripe -c 1 $DIR/$tfile
21199         # Offset 2T == 4k * 512M
21200         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 seek=512M ||
21201                 error "dd to 2T offset failed"
21202 }
21203 run_test 249 "Write above 2T file size"
21204
21205 test_250() {
21206         [ "$(facet_fstype ost$(($($LFS getstripe -i $DIR/$tfile) + 1)))" = "zfs" ] \
21207          && skip "no 16TB file size limit on ZFS"
21208
21209         $LFS setstripe -c 1 $DIR/$tfile
21210         # ldiskfs extent file size limit is (16TB - 4KB - 1) bytes
21211         local size=$((16 * 1024 * 1024 * 1024 * 1024 - 4096 - 1))
21212         $TRUNCATE $DIR/$tfile $size || error "truncate $tfile to $size failed"
21213         dd if=/dev/zero of=$DIR/$tfile bs=10 count=1 oflag=append \
21214                 conv=notrunc,fsync && error "append succeeded"
21215         return 0
21216 }
21217 run_test 250 "Write above 16T limit"
21218
21219 test_251() {
21220         $LFS setstripe -c -1 -S 1048576 $DIR/$tfile
21221
21222         #define OBD_FAIL_LLITE_LOST_LAYOUT 0x1407
21223         #Skip once - writing the first stripe will succeed
21224         $LCTL set_param fail_loc=0xa0001407 fail_val=1
21225         $MULTIOP $DIR/$tfile o:O_RDWR:w2097152c 2>&1 | grep -q "short write" &&
21226                 error "short write happened"
21227
21228         $LCTL set_param fail_loc=0xa0001407 fail_val=1
21229         $MULTIOP $DIR/$tfile or2097152c 2>&1 | grep -q "short read" &&
21230                 error "short read happened"
21231
21232         rm -f $DIR/$tfile
21233 }
21234 run_test 251 "Handling short read and write correctly"
21235
21236 test_252() {
21237         remote_mds_nodsh && skip "remote MDS with nodsh"
21238         remote_ost_nodsh && skip "remote OST with nodsh"
21239         if [ "$ost1_FSTYPE" != ldiskfs ] || [ "$mds1_FSTYPE" != ldiskfs ]; then
21240                 skip_env "ldiskfs only test"
21241         fi
21242
21243         local tgt
21244         local dev
21245         local out
21246         local uuid
21247         local num
21248         local gen
21249
21250         # check lr_reader on OST0000
21251         tgt=ost1
21252         dev=$(facet_device $tgt)
21253         out=$(do_facet $tgt $LR_READER $dev)
21254         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
21255         echo "$out"
21256         uuid=$(echo "$out" | grep -i uuid | awk '{ print $2 }')
21257         [ "$uuid" == "$(ostuuid_from_index 0)" ] ||
21258                 error "Invalid uuid returned by $LR_READER on target $tgt"
21259         echo -e "uuid returned by $LR_READER is '$uuid'\n"
21260
21261         # check lr_reader -c on MDT0000
21262         tgt=mds1
21263         dev=$(facet_device $tgt)
21264         if ! do_facet $tgt $LR_READER -h | grep -q OPTIONS; then
21265                 skip "$LR_READER does not support additional options"
21266         fi
21267         out=$(do_facet $tgt $LR_READER -c $dev)
21268         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
21269         echo "$out"
21270         num=$(echo "$out" | grep -c "mdtlov")
21271         [ "$num" -eq $((MDSCOUNT - 1)) ] ||
21272                 error "Invalid number of mdtlov clients returned by $LR_READER"
21273         echo -e "Number of mdtlov clients returned by $LR_READER is '$num'\n"
21274
21275         # check lr_reader -cr on MDT0000
21276         out=$(do_facet $tgt $LR_READER -cr $dev)
21277         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
21278         echo "$out"
21279         echo "$out" | grep -q "^reply_data:$" ||
21280                 error "$LR_READER should have returned 'reply_data' section"
21281         num=$(echo "$out" | grep -c "client_generation")
21282         echo -e "Number of reply data returned by $LR_READER is '$num'\n"
21283 }
21284 run_test 252 "check lr_reader tool"
21285
21286 test_253() {
21287         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21288         remote_mds_nodsh && skip "remote MDS with nodsh"
21289         remote_mgs_nodsh && skip "remote MGS with nodsh"
21290
21291         local ostidx=0
21292         local rc=0
21293         local ost_name=$(ostname_from_index $ostidx)
21294
21295         # on the mdt's osc
21296         local mdtosc_proc1=$(get_mdtosc_proc_path $SINGLEMDS $ost_name)
21297         do_facet $SINGLEMDS $LCTL get_param -n \
21298                 osp.$mdtosc_proc1.reserved_mb_high ||
21299                 skip  "remote MDS does not support reserved_mb_high"
21300
21301         rm -rf $DIR/$tdir
21302         wait_mds_ost_sync
21303         wait_delete_completed
21304         mkdir $DIR/$tdir
21305
21306         pool_add $TESTNAME || error "Pool creation failed"
21307         pool_add_targets $TESTNAME 0 || error "Pool add targets failed"
21308
21309         $LFS setstripe $DIR/$tdir -i $ostidx -c 1 -p $FSNAME.$TESTNAME ||
21310                 error "Setstripe failed"
21311
21312         dd if=/dev/zero of=$DIR/$tdir/$tfile.0 bs=1M count=10
21313
21314         local wms=$(ost_watermarks_set_enospc $tfile $ostidx |
21315                     grep "watermarks")
21316         stack_trap "ost_watermarks_clear_enospc $tfile $ostidx $wms" EXIT
21317
21318         local oa_status=$(do_facet $SINGLEMDS $LCTL get_param -n \
21319                         osp.$mdtosc_proc1.prealloc_status)
21320         echo "prealloc_status $oa_status"
21321
21322         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=1M count=1 &&
21323                 error "File creation should fail"
21324
21325         #object allocation was stopped, but we still able to append files
21326         dd if=/dev/zero of=$DIR/$tdir/$tfile.0 bs=1M seek=6 count=5 \
21327                 oflag=append || error "Append failed"
21328
21329         rm -f $DIR/$tdir/$tfile.0
21330
21331         # For this test, we want to delete the files we created to go out of
21332         # space but leave the watermark, so we remain nearly out of space
21333         ost_watermarks_enospc_delete_files $tfile $ostidx
21334
21335         wait_delete_completed
21336
21337         sleep_maxage
21338
21339         for i in $(seq 10 12); do
21340                 dd if=/dev/zero of=$DIR/$tdir/$tfile.$i bs=1M count=1 \
21341                         2>/dev/null || error "File creation failed after rm"
21342         done
21343
21344         oa_status=$(do_facet $SINGLEMDS $LCTL get_param -n \
21345                         osp.$mdtosc_proc1.prealloc_status)
21346         echo "prealloc_status $oa_status"
21347
21348         if (( oa_status != 0 )); then
21349                 error "Object allocation still disable after rm"
21350         fi
21351 }
21352 run_test 253 "Check object allocation limit"
21353
21354 test_254() {
21355         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21356         remote_mds_nodsh && skip "remote MDS with nodsh"
21357
21358         local mdt=$(facet_svc $SINGLEMDS)
21359
21360         do_facet $SINGLEMDS $LCTL get_param -n mdd.$mdt.changelog_size ||
21361                 skip "MDS does not support changelog_size"
21362
21363         local cl_user
21364
21365         changelog_register || error "changelog_register failed"
21366
21367         changelog_clear 0 || error "changelog_clear failed"
21368
21369         local size1=$(do_facet $SINGLEMDS \
21370                       $LCTL get_param -n mdd.$mdt.changelog_size)
21371         echo "Changelog size $size1"
21372
21373         rm -rf $DIR/$tdir
21374         $LFS mkdir -i 0 $DIR/$tdir
21375         # change something
21376         mkdir -p $DIR/$tdir/pics/2008/zachy
21377         touch $DIR/$tdir/pics/2008/zachy/timestamp
21378         cp /etc/hosts $DIR/$tdir/pics/2008/zachy/pic1.jpg
21379         mv $DIR/$tdir/pics/2008/zachy $DIR/$tdir/pics/zach
21380         ln $DIR/$tdir/pics/zach/pic1.jpg $DIR/$tdir/pics/2008/portland.jpg
21381         ln -s $DIR/$tdir/pics/2008/portland.jpg $DIR/$tdir/pics/desktop.jpg
21382         rm $DIR/$tdir/pics/desktop.jpg
21383
21384         local size2=$(do_facet $SINGLEMDS \
21385                       $LCTL get_param -n mdd.$mdt.changelog_size)
21386         echo "Changelog size after work $size2"
21387
21388         (( $size2 > $size1 )) ||
21389                 error "new Changelog size=$size2 less than old size=$size1"
21390 }
21391 run_test 254 "Check changelog size"
21392
21393 ladvise_no_type()
21394 {
21395         local type=$1
21396         local file=$2
21397
21398         lfs ladvise -a invalid $file 2>&1 | grep "Valid types" |
21399                 awk -F: '{print $2}' | grep $type > /dev/null
21400         if [ $? -ne 0 ]; then
21401                 return 0
21402         fi
21403         return 1
21404 }
21405
21406 ladvise_no_ioctl()
21407 {
21408         local file=$1
21409
21410         lfs ladvise -a willread $file > /dev/null 2>&1
21411         if [ $? -eq 0 ]; then
21412                 return 1
21413         fi
21414
21415         lfs ladvise -a willread $file 2>&1 |
21416                 grep "Inappropriate ioctl for device" > /dev/null
21417         if [ $? -eq 0 ]; then
21418                 return 0
21419         fi
21420         return 1
21421 }
21422
21423 percent() {
21424         bc <<<"scale=2; ($1 - $2) * 100 / $2"
21425 }
21426
21427 # run a random read IO workload
21428 # usage: random_read_iops <filename> <filesize> <iosize>
21429 random_read_iops() {
21430         local file=$1
21431         local fsize=$2
21432         local iosize=${3:-4096}
21433
21434         $READS -f $file -s $fsize -b $iosize -n $((fsize / iosize)) -t 60 |
21435                 sed -e '/^$/d' -e 's#.*s, ##' -e 's#MB/s##'
21436 }
21437
21438 drop_file_oss_cache() {
21439         local file="$1"
21440         local nodes="$2"
21441
21442         $LFS ladvise -a dontneed $file 2>/dev/null ||
21443                 do_nodes $nodes "echo 3 > /proc/sys/vm/drop_caches"
21444 }
21445
21446 ladvise_willread_performance()
21447 {
21448         local repeat=10
21449         local average_origin=0
21450         local average_cache=0
21451         local average_ladvise=0
21452
21453         for ((i = 1; i <= $repeat; i++)); do
21454                 echo "Iter $i/$repeat: reading without willread hint"
21455                 cancel_lru_locks osc
21456                 drop_file_oss_cache $DIR/$tfile $(comma_list $(osts_nodes))
21457                 local speed_origin=$(random_read_iops $DIR/$tfile $size)
21458                 echo "Iter $i/$repeat: uncached speed: $speed_origin"
21459                 average_origin=$(bc <<<"$average_origin + $speed_origin")
21460
21461                 cancel_lru_locks osc
21462                 local speed_cache=$(random_read_iops $DIR/$tfile $size)
21463                 echo "Iter $i/$repeat: OSS cache speed: $speed_cache"
21464                 average_cache=$(bc <<<"$average_cache + $speed_cache")
21465
21466                 cancel_lru_locks osc
21467                 drop_file_oss_cache $DIR/$tfile $(comma_list $(osts_nodes))
21468                 $LFS ladvise -a willread $DIR/$tfile || error "ladvise failed"
21469                 local speed_ladvise=$(random_read_iops $DIR/$tfile $size)
21470                 echo "Iter $i/$repeat: ladvise speed: $speed_ladvise"
21471                 average_ladvise=$(bc <<<"$average_ladvise + $speed_ladvise")
21472         done
21473         average_origin=$(bc <<<"scale=2; $average_origin / $repeat")
21474         average_cache=$(bc <<<"scale=2; $average_cache / $repeat")
21475         average_ladvise=$(bc <<<"scale=2; $average_ladvise / $repeat")
21476
21477         speedup_cache=$(percent $average_cache $average_origin)
21478         speedup_ladvise=$(percent $average_ladvise $average_origin)
21479
21480         echo "Average uncached read: $average_origin"
21481         echo "Average speedup with OSS cached read: " \
21482                 "$average_cache = +$speedup_cache%"
21483         echo "Average speedup with ladvise willread: " \
21484                 "$average_ladvise = +$speedup_ladvise%"
21485
21486         local lowest_speedup=20
21487         if [ ${average_cache%.*} -lt $lowest_speedup ]; then
21488                 echo "Speedup with OSS cached read less than $lowest_speedup%," \
21489                         "got $average_cache%. Skipping ladvise willread check."
21490                 return 0
21491         fi
21492
21493         # the test won't work on ZFS until it supports 'ladvise dontneed', but
21494         # it is still good to run until then to exercise 'ladvise willread'
21495         ! $LFS ladvise -a dontneed $DIR/$tfile &&
21496                 [ "$ost1_FSTYPE" = "zfs" ] &&
21497                 echo "osd-zfs does not support dontneed or drop_caches" &&
21498                 return 0
21499
21500         lowest_speedup=$(bc <<<"scale=2; $average_cache / 2")
21501         [[ ${average_ladvise%.*} > $lowest_speedup ]] ||
21502                 error_not_in_vm "Speedup with willread is less than " \
21503                         "$lowest_speedup%, got $average_ladvise%"
21504 }
21505
21506 test_255a() {
21507         [ $OST1_VERSION -lt $(version_code 2.8.54) ] &&
21508                 skip "lustre < 2.8.54 does not support ladvise "
21509         remote_ost_nodsh && skip "remote OST with nodsh"
21510
21511         stack_trap "rm -f $DIR/$tfile"
21512         lfs setstripe -c -1 -i 0 $DIR/$tfile || error "$tfile failed"
21513
21514         ladvise_no_type willread $DIR/$tfile &&
21515                 skip "willread ladvise is not supported"
21516
21517         ladvise_no_ioctl $DIR/$tfile &&
21518                 skip "ladvise ioctl is not supported"
21519
21520         local size_mb=100
21521         local size=$((size_mb * 1048576))
21522         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=$size_mb ||
21523                 error "dd to $DIR/$tfile failed"
21524
21525         lfs ladvise -a willread $DIR/$tfile ||
21526                 error "Ladvise failed with no range argument"
21527
21528         lfs ladvise -a willread -s 0 $DIR/$tfile ||
21529                 error "Ladvise failed with no -l or -e argument"
21530
21531         lfs ladvise -a willread -e 1 $DIR/$tfile ||
21532                 error "Ladvise failed with only -e argument"
21533
21534         lfs ladvise -a willread -l 1 $DIR/$tfile ||
21535                 error "Ladvise failed with only -l argument"
21536
21537         lfs ladvise -a willread -s 2 -e 1 $DIR/$tfile &&
21538                 error "End offset should not be smaller than start offset"
21539
21540         lfs ladvise -a willread -s 2 -e 2 $DIR/$tfile &&
21541                 error "End offset should not be equal to start offset"
21542
21543         lfs ladvise -a willread -s $size -l 1 $DIR/$tfile ||
21544                 error "Ladvise failed with overflowing -s argument"
21545
21546         lfs ladvise -a willread -s 1 -e $((size + 1)) $DIR/$tfile ||
21547                 error "Ladvise failed with overflowing -e argument"
21548
21549         lfs ladvise -a willread -s 1 -l $size $DIR/$tfile ||
21550                 error "Ladvise failed with overflowing -l argument"
21551
21552         lfs ladvise -a willread -l 1 -e 2 $DIR/$tfile &&
21553                 error "Ladvise succeeded with conflicting -l and -e arguments"
21554
21555         echo "Synchronous ladvise should wait"
21556         local delay=4
21557 #define OBD_FAIL_OST_LADVISE_PAUSE       0x237
21558         do_nodes $(comma_list $(osts_nodes)) \
21559                 $LCTL set_param fail_val=$delay fail_loc=0x237
21560
21561         local start_ts=$SECONDS
21562         lfs ladvise -a willread $DIR/$tfile ||
21563                 error "Ladvise failed with no range argument"
21564         local end_ts=$SECONDS
21565         local inteval_ts=$((end_ts - start_ts))
21566
21567         if [ $inteval_ts -lt $(($delay - 1)) ]; then
21568                 error "Synchronous advice didn't wait reply"
21569         fi
21570
21571         echo "Asynchronous ladvise shouldn't wait"
21572         local start_ts=$SECONDS
21573         lfs ladvise -a willread -b $DIR/$tfile ||
21574                 error "Ladvise failed with no range argument"
21575         local end_ts=$SECONDS
21576         local inteval_ts=$((end_ts - start_ts))
21577
21578         if [ $inteval_ts -gt $(($delay / 2)) ]; then
21579                 error "Asynchronous advice blocked"
21580         fi
21581
21582         do_nodes $(comma_list $(osts_nodes)) $LCTL set_param fail_loc=0
21583         ladvise_willread_performance
21584 }
21585 run_test 255a "check 'lfs ladvise -a willread'"
21586
21587 facet_meminfo() {
21588         local facet=$1
21589         local info=$2
21590
21591         do_facet $facet "cat /proc/meminfo | grep ^${info}:" | awk '{print $2}'
21592 }
21593
21594 test_255b() {
21595         [ $OST1_VERSION -lt $(version_code 2.8.54) ] &&
21596                 skip "lustre < 2.8.54 does not support ladvise "
21597         remote_ost_nodsh && skip "remote OST with nodsh"
21598
21599         stack_trap "rm -f $DIR/$tfile"
21600         lfs setstripe -c 1 -i 0 $DIR/$tfile
21601
21602         ladvise_no_type dontneed $DIR/$tfile &&
21603                 skip "dontneed ladvise is not supported"
21604
21605         ladvise_no_ioctl $DIR/$tfile &&
21606                 skip "ladvise ioctl is not supported"
21607
21608         ! $LFS ladvise -a dontneed $DIR/$tfile &&
21609                 [ "$ost1_FSTYPE" = "zfs" ] &&
21610                 skip "zfs-osd does not support 'ladvise dontneed'"
21611
21612         local size_mb=100
21613         local size=$((size_mb * 1048576))
21614         # In order to prevent disturbance of other processes, only check 3/4
21615         # of the memory usage
21616         local kibibytes=$((size_mb * 1024 * 3 / 4))
21617
21618         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=$size_mb ||
21619                 error "dd to $DIR/$tfile failed"
21620
21621         #force write to complete before dropping OST cache & checking memory
21622         sync
21623
21624         local total=$(facet_meminfo ost1 MemTotal)
21625         echo "Total memory: $total KiB"
21626
21627         do_facet ost1 "sync && echo 3 > /proc/sys/vm/drop_caches"
21628         local before_read=$(facet_meminfo ost1 Cached)
21629         echo "Cache used before read: $before_read KiB"
21630
21631         lfs ladvise -a willread $DIR/$tfile ||
21632                 error "Ladvise willread failed"
21633         local after_read=$(facet_meminfo ost1 Cached)
21634         echo "Cache used after read: $after_read KiB"
21635
21636         lfs ladvise -a dontneed $DIR/$tfile ||
21637                 error "Ladvise dontneed again failed"
21638         local no_read=$(facet_meminfo ost1 Cached)
21639         echo "Cache used after dontneed ladvise: $no_read KiB"
21640
21641         if [ $total -lt $((before_read + kibibytes)) ]; then
21642                 echo "Memory is too small, abort checking"
21643                 return 0
21644         fi
21645
21646         if [ $((before_read + kibibytes)) -gt $after_read ]; then
21647                 error "Ladvise willread should use more memory" \
21648                         "than $kibibytes KiB"
21649         fi
21650
21651         if [ $((no_read + kibibytes)) -gt $after_read ]; then
21652                 error "Ladvise dontneed should release more memory" \
21653                         "than $kibibytes KiB"
21654         fi
21655 }
21656 run_test 255b "check 'lfs ladvise -a dontneed'"
21657
21658 test_255c() {
21659         [ $OST1_VERSION -lt $(version_code 2.10.50) ] &&
21660                 skip "lustre < 2.10.50 does not support lockahead"
21661
21662         local ost1_imp=$(get_osc_import_name client ost1)
21663         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
21664                          cut -d'.' -f2)
21665         local count
21666         local new_count
21667         local difference
21668         local i
21669         local rc
21670
21671         test_mkdir -p $DIR/$tdir
21672         $LFS setstripe -i 0 -c 1 $DIR/$tdir
21673
21674         #test 10 returns only success/failure
21675         i=10
21676         lockahead_test -d $DIR/$tdir -t $i -f $tfile
21677         rc=$?
21678         if [ $rc -eq 255 ]; then
21679                 error "Ladvise test${i} failed, ${rc}"
21680         fi
21681
21682         #test 11 counts lock enqueue requests, all others count new locks
21683         i=11
21684         count=$(do_facet ost1 \
21685                 $LCTL get_param -n ost.OSS.ost.stats)
21686         count=$(echo "$count" | grep ldlm_extent_enqueue | awk '{ print $2 }')
21687
21688         lockahead_test -d $DIR/$tdir -t $i -f $tfile
21689         rc=$?
21690         if [ $rc -eq 255 ]; then
21691                 error "Ladvise test${i} failed, ${rc}"
21692         fi
21693
21694         new_count=$(do_facet ost1 \
21695                 $LCTL get_param -n ost.OSS.ost.stats)
21696         new_count=$(echo "$new_count" | grep ldlm_extent_enqueue | \
21697                    awk '{ print $2 }')
21698
21699         difference="$((new_count - count))"
21700         if [ $difference -ne $rc ]; then
21701                 error "Ladvise test${i}, bad enqueue count, returned " \
21702                       "${rc}, actual ${difference}"
21703         fi
21704
21705         for i in $(seq 12 21); do
21706                 # If we do not do this, we run the risk of having too many
21707                 # locks and starting lock cancellation while we are checking
21708                 # lock counts.
21709                 cancel_lru_locks osc
21710
21711                 count=$($LCTL get_param -n \
21712                        ldlm.namespaces.$imp_name.lock_unused_count)
21713
21714                 lockahead_test -d $DIR/$tdir -t $i -f $tfile
21715                 rc=$?
21716                 if [ $rc -eq 255 ]; then
21717                         error "Ladvise test ${i} failed, ${rc}"
21718                 fi
21719
21720                 new_count=$($LCTL get_param -n \
21721                        ldlm.namespaces.$imp_name.lock_unused_count)
21722                 difference="$((new_count - count))"
21723
21724                 # Test 15 output is divided by 100 to map down to valid return
21725                 if [ $i -eq 15 ]; then
21726                         rc="$((rc * 100))"
21727                 fi
21728
21729                 if [ $difference -ne $rc ]; then
21730                         error "Ladvise test ${i}, bad lock count, returned " \
21731                               "${rc}, actual ${difference}"
21732                 fi
21733         done
21734
21735         #test 22 returns only success/failure
21736         i=22
21737         lockahead_test -d $DIR/$tdir -t $i -f $tfile
21738         rc=$?
21739         if [ $rc -eq 255 ]; then
21740                 error "Ladvise test${i} failed, ${rc}"
21741         fi
21742 }
21743 run_test 255c "suite of ladvise lockahead tests"
21744
21745 test_256() {
21746         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21747         remote_mds_nodsh && skip "remote MDS with nodsh"
21748         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip "ldiskfs only test"
21749         changelog_users $SINGLEMDS | grep "^cl" &&
21750                 skip "active changelog user"
21751
21752         local cl_user
21753         local cat_sl
21754         local mdt_dev
21755
21756         mdt_dev=$(mdsdevname 1)
21757         echo $mdt_dev
21758
21759         changelog_register || error "changelog_register failed"
21760
21761         rm -rf $DIR/$tdir
21762         mkdir_on_mdt0 $DIR/$tdir
21763
21764         changelog_clear 0 || error "changelog_clear failed"
21765
21766         # change something
21767         touch $DIR/$tdir/{1..10}
21768
21769         # stop the MDT
21770         stop $SINGLEMDS || error "Fail to stop MDT"
21771
21772         # remount the MDT
21773
21774         start $SINGLEMDS $mdt_dev $MDS_MOUNT_OPTS || error "Fail to start MDT"
21775
21776         #after mount new plainllog is used
21777         touch $DIR/$tdir/{11..19}
21778         local tmpfile="$(mktemp --tmpdir -u $tfile.XXXXXX)"
21779         stack_trap "rm -f $tmpfile"
21780         cat_sl=$(do_facet $SINGLEMDS "sync; \
21781                  $DEBUGFS -c -R 'dump changelog_catalog $tmpfile' $mdt_dev; \
21782                  llog_reader $tmpfile | grep -c type=1064553b")
21783         do_facet $SINGLEMDS llog_reader $tmpfile
21784
21785         [ $cat_sl != 2 ] && error "Changelog catalog has $cat_sl != 2 slots"
21786
21787         changelog_clear 0 || error "changelog_clear failed"
21788
21789         cat_sl=$(do_facet $SINGLEMDS "sync; \
21790                  $DEBUGFS -c -R 'dump changelog_catalog $tmpfile' $mdt_dev; \
21791                  llog_reader $tmpfile | grep -c type=1064553b")
21792
21793         if (( cat_sl == 2 )); then
21794                 error "Empty plain llog was not deleted from changelog catalog"
21795         elif (( cat_sl != 1 )); then
21796                 error "Active plain llog shouldn't be deleted from catalog"
21797         fi
21798 }
21799 run_test 256 "Check llog delete for empty and not full state"
21800
21801 test_257() {
21802         remote_mds_nodsh && skip "remote MDS with nodsh"
21803         [[ $MDS1_VERSION -lt $(version_code 2.8.55) ]] &&
21804                 skip "Need MDS version at least 2.8.55"
21805
21806         test_mkdir $DIR/$tdir
21807
21808         setfattr -n trusted.name1 -v value1 $DIR/$tdir ||
21809                 error "setfattr -n trusted.name1=value1 $DIR/$tdir failed"
21810         stat $DIR/$tdir
21811
21812 #define OBD_FAIL_MDS_XATTR_REP                  0x161
21813         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
21814         local facet=mds$((mdtidx + 1))
21815         set_nodes_failloc $(facet_active_host $facet) 0x80000161
21816         getfattr -n trusted.name1 $DIR/$tdir 2> /dev/null
21817
21818         stop $facet || error "stop MDS failed"
21819         start $facet $(mdsdevname $((mdtidx + 1))) $MDS_MOUNT_OPTS ||
21820                 error "start MDS fail"
21821         wait_recovery_complete $facet
21822 }
21823 run_test 257 "xattr locks are not lost"
21824
21825 # Verify we take the i_mutex when security requires it
21826 test_258a() {
21827 #define OBD_FAIL_IMUTEX_SEC 0x141c
21828         $LCTL set_param fail_loc=0x141c
21829         touch $DIR/$tfile
21830         chmod u+s $DIR/$tfile
21831         chmod a+rwx $DIR/$tfile
21832         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 oflag=append
21833         RC=$?
21834         if [ $RC -ne 0 ]; then
21835                 error "error, failed to take i_mutex, rc=$?"
21836         fi
21837         rm -f $DIR/$tfile
21838 }
21839 run_test 258a "verify i_mutex security behavior when suid attributes is set"
21840
21841 # Verify we do NOT take the i_mutex in the normal case
21842 test_258b() {
21843 #define OBD_FAIL_IMUTEX_NOSEC 0x141d
21844         $LCTL set_param fail_loc=0x141d
21845         touch $DIR/$tfile
21846         chmod a+rwx $DIR
21847         chmod a+rw $DIR/$tfile
21848         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 oflag=append
21849         RC=$?
21850         if [ $RC -ne 0 ]; then
21851                 error "error, took i_mutex unnecessarily, rc=$?"
21852         fi
21853         rm -f $DIR/$tfile
21854
21855 }
21856 run_test 258b "verify i_mutex security behavior"
21857
21858 test_259() {
21859         local file=$DIR/$tfile
21860         local before
21861         local after
21862
21863         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip "ldiskfs only test"
21864
21865         stack_trap "rm -f $file" EXIT
21866
21867         wait_delete_completed
21868         before=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
21869         echo "before: $before"
21870
21871         $LFS setstripe -i 0 -c 1 $file
21872         dd if=/dev/zero of=$file bs=1M count=10 || error "couldn't write"
21873         sync_all_data
21874         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
21875         echo "after write: $after"
21876
21877 #define OBD_FAIL_OSD_FAIL_AT_TRUNCATE          0x2301
21878         do_facet ost1 $LCTL set_param fail_loc=0x2301
21879         $TRUNCATE $file 0
21880         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
21881         echo "after truncate: $after"
21882
21883         stop ost1
21884         do_facet ost1 $LCTL set_param fail_loc=0
21885         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
21886         sleep 2
21887         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
21888         echo "after restart: $after"
21889         [ $((after - before)) -ge $(fs_log_size ost1) ] &&
21890                 error "missing truncate?"
21891
21892         return 0
21893 }
21894 run_test 259 "crash at delayed truncate"
21895
21896 test_260() {
21897 #define OBD_FAIL_MDC_CLOSE               0x806
21898         $LCTL set_param fail_loc=0x80000806
21899         touch $DIR/$tfile
21900
21901 }
21902 run_test 260 "Check mdc_close fail"
21903
21904 ### Data-on-MDT sanity tests ###
21905 test_270a() {
21906         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
21907                 skip "Need MDS version at least 2.10.55 for DoM"
21908
21909         # create DoM file
21910         local dom=$DIR/$tdir/dom_file
21911         local tmp=$DIR/$tdir/tmp_file
21912
21913         mkdir_on_mdt0 $DIR/$tdir
21914
21915         # basic checks for DoM component creation
21916         $LFS setstripe -E 1024K -E 2048K -L mdt $dom 2>/dev/null &&
21917                 error "Can set MDT layout to non-first entry"
21918
21919         $LFS setstripe -E 1024K -L mdt -E 2048K -L mdt $dom 2>/dev/null &&
21920                 error "Can define multiple entries as MDT layout"
21921
21922         $LFS setstripe -E 1M -L mdt $dom || error "Can't create DoM layout"
21923
21924         [ $($LFS getstripe -L $dom) == "mdt" ] || error "bad pattern"
21925         [ $($LFS getstripe -c $dom) == 0 ] || error "bad stripe count"
21926         [ $($LFS getstripe -S $dom) == 1048576 ] || error "bad stripe size"
21927
21928         local mdtidx=$($LFS getstripe -m $dom)
21929         local mdtname=MDT$(printf %04x $mdtidx)
21930         local facet=mds$((mdtidx + 1))
21931         local space_check=1
21932
21933         # Skip free space checks with ZFS
21934         [ "$(facet_fstype $facet)" == "zfs" ] && space_check=0
21935
21936         # write
21937         sync
21938         local size_tmp=$((65536 * 3))
21939         local mdtfree1=$(do_facet $facet \
21940                          lctl get_param -n osd*.*$mdtname.kbytesfree)
21941
21942         dd if=/dev/urandom of=$tmp bs=1024 count=$((size_tmp / 1024))
21943         # check also direct IO along write
21944         # IO size must be a multiple of PAGE_SIZE on all platforms (ARM=64KB)
21945         dd if=$tmp of=$dom bs=65536 count=$((size_tmp / 65536)) oflag=direct
21946         sync
21947         cmp $tmp $dom || error "file data is different"
21948         [ $(stat -c%s $dom) == $size_tmp ] ||
21949                 error "bad size after write: $(stat -c%s $dom) != $size_tmp"
21950         if [ $space_check == 1 ]; then
21951                 local mdtfree2=$(do_facet $facet \
21952                                  lctl get_param -n osd*.*$mdtname.kbytesfree)
21953
21954                 # increase in usage from by $size_tmp
21955                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_tmp / 1024)) ] ||
21956                         error "MDT free space wrong after write: " \
21957                               "$mdtfree1 >= $mdtfree2 + $size_tmp/1024"
21958         fi
21959
21960         # truncate
21961         local size_dom=10000
21962
21963         $TRUNCATE $dom $size_dom
21964         [ $(stat -c%s $dom) == $size_dom ] ||
21965                 error "bad size after truncate: $(stat -c%s $dom) != $size_dom"
21966         if [ $space_check == 1 ]; then
21967                 mdtfree1=$(do_facet $facet \
21968                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
21969                 # decrease in usage from $size_tmp to new $size_dom
21970                 [ $(($mdtfree1 - $mdtfree2)) -ge \
21971                   $(((size_tmp - size_dom) / 1024)) ] ||
21972                         error "MDT free space is wrong after truncate: " \
21973                               "$mdtfree1 >= $mdtfree2 + ($size_tmp - $size_dom) / 1024"
21974         fi
21975
21976         # append
21977         cat $tmp >> $dom
21978         sync
21979         size_dom=$((size_dom + size_tmp))
21980         [ $(stat -c%s $dom) == $size_dom ] ||
21981                 error "bad size after append: $(stat -c%s $dom) != $size_dom"
21982         if [ $space_check == 1 ]; then
21983                 mdtfree2=$(do_facet $facet \
21984                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
21985                 # increase in usage by $size_tmp from previous
21986                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_tmp / 1024)) ] ||
21987                         error "MDT free space is wrong after append: " \
21988                               "$mdtfree1 >= $mdtfree2 + $size_tmp/1024"
21989         fi
21990
21991         # delete
21992         rm $dom
21993         if [ $space_check == 1 ]; then
21994                 mdtfree1=$(do_facet $facet \
21995                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
21996                 # decrease in usage by $size_dom from previous
21997                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_dom / 1024)) ] ||
21998                         error "MDT free space is wrong after removal: " \
21999                               "$mdtfree1 >= $mdtfree2 + $size_dom/1024"
22000         fi
22001
22002         # combined striping
22003         $LFS setstripe -E 1024K -L mdt -E EOF $dom ||
22004                 error "Can't create DoM + OST striping"
22005
22006         size_tmp=2031616 # must be a multiple of PAGE_SIZE=65536 on ARM
22007         dd if=/dev/urandom of=$tmp bs=1024 count=$((size_tmp / 1024))
22008         # check also direct IO along write
22009         dd if=$tmp of=$dom bs=65536 count=$((size_tmp / 65536)) oflag=direct
22010         sync
22011         cmp $tmp $dom || error "file data is different"
22012         [ $(stat -c%s $dom) == $size_tmp ] ||
22013                 error "bad size after write: $(stat -c%s $dom) != $size_tmp"
22014         rm $dom $tmp
22015
22016         return 0
22017 }
22018 run_test 270a "DoM: basic functionality tests"
22019
22020 test_270b() {
22021         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
22022                 skip "Need MDS version at least 2.10.55"
22023
22024         local dom=$DIR/$tdir/dom_file
22025         local max_size=1048576
22026
22027         mkdir -p $DIR/$tdir
22028         $LFS setstripe -E $max_size -L mdt $dom
22029
22030         # truncate over the limit
22031         $TRUNCATE $dom $(($max_size + 1)) &&
22032                 error "successful truncate over the maximum size"
22033         # write over the limit
22034         dd if=/dev/zero of=$dom bs=$max_size seek=1 count=1 &&
22035                 error "successful write over the maximum size"
22036         # append over the limit
22037         dd if=/dev/zero of=$dom bs=$(($max_size - 3)) count=1
22038         echo "12345" >> $dom && error "successful append over the maximum size"
22039         rm $dom
22040
22041         return 0
22042 }
22043 run_test 270b "DoM: maximum size overflow checks for DoM-only file"
22044
22045 test_270c() {
22046         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
22047                 skip "Need MDS version at least 2.10.55"
22048
22049         mkdir -p $DIR/$tdir
22050         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
22051
22052         # check files inherit DoM EA
22053         touch $DIR/$tdir/first
22054         [ $($LFS getstripe -L $DIR/$tdir/first) == "mdt" ] ||
22055                 error "bad pattern"
22056         [ $($LFS getstripe -c $DIR/$tdir/first) == 0 ] ||
22057                 error "bad stripe count"
22058         [ $($LFS getstripe -S $DIR/$tdir/first) == 1048576 ] ||
22059                 error "bad stripe size"
22060
22061         # check directory inherits DoM EA and uses it as default
22062         mkdir $DIR/$tdir/subdir
22063         touch $DIR/$tdir/subdir/second
22064         [ $($LFS getstripe -L $DIR/$tdir/subdir/second) == "mdt" ] ||
22065                 error "bad pattern in sub-directory"
22066         [ $($LFS getstripe -c $DIR/$tdir/subdir/second) == 0 ] ||
22067                 error "bad stripe count in sub-directory"
22068         [ $($LFS getstripe -S $DIR/$tdir/subdir/second) == 1048576 ] ||
22069                 error "bad stripe size in sub-directory"
22070         return 0
22071 }
22072 run_test 270c "DoM: DoM EA inheritance tests"
22073
22074 test_270d() {
22075         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
22076                 skip "Need MDS version at least 2.10.55"
22077
22078         mkdir -p $DIR/$tdir
22079         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
22080
22081         # inherit default DoM striping
22082         mkdir $DIR/$tdir/subdir
22083         touch $DIR/$tdir/subdir/f1
22084
22085         # change default directory striping
22086         $LFS setstripe -c 1 $DIR/$tdir/subdir
22087         touch $DIR/$tdir/subdir/f2
22088         [ $($LFS getstripe -c $DIR/$tdir/subdir/f2) == 1 ] ||
22089                 error "wrong default striping in file 2"
22090         [ $($LFS getstripe -L $DIR/$tdir/subdir/f2) == "raid0" ] ||
22091                 error "bad pattern in file 2"
22092         return 0
22093 }
22094 run_test 270d "DoM: change striping from DoM to RAID0"
22095
22096 test_270e() {
22097         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
22098                 skip "Need MDS version at least 2.10.55"
22099
22100         mkdir -p $DIR/$tdir/dom
22101         mkdir -p $DIR/$tdir/norm
22102         DOMFILES=20
22103         NORMFILES=10
22104         $LFS setstripe -E 1M -L mdt $DIR/$tdir/dom
22105         $LFS setstripe -i 0 -S 2M $DIR/$tdir/norm
22106
22107         createmany -o $DIR/$tdir/dom/dom- $DOMFILES
22108         createmany -o $DIR/$tdir/norm/norm- $NORMFILES
22109
22110         # find DoM files by layout
22111         NUM=$($LFS find -L mdt -type f $DIR/$tdir 2>/dev/null | wc -l)
22112         [ $NUM -eq  $DOMFILES ] ||
22113                 error "lfs find -L: found $NUM, expected $DOMFILES"
22114         echo "Test 1: lfs find 20 DOM files by layout: OK"
22115
22116         # there should be 1 dir with default DOM striping
22117         NUM=$($LFS find -L mdt -type d $DIR/$tdir 2>/dev/null | wc -l)
22118         [ $NUM -eq  1 ] ||
22119                 error "lfs find -L: found $NUM, expected 1 dir"
22120         echo "Test 2: lfs find 1 DOM dir by layout: OK"
22121
22122         # find DoM files by stripe size
22123         NUM=$($LFS find -S -1200K -type f $DIR/$tdir 2>/dev/null | wc -l)
22124         [ $NUM -eq  $DOMFILES ] ||
22125                 error "lfs find -S: found $NUM, expected $DOMFILES"
22126         echo "Test 4: lfs find 20 DOM files by stripe size: OK"
22127
22128         # find files by stripe offset except DoM files
22129         NUM=$($LFS find -i 0 -type f $DIR/$tdir 2>/dev/null | wc -l)
22130         [ $NUM -eq  $NORMFILES ] ||
22131                 error "lfs find -i: found $NUM, expected $NORMFILES"
22132         echo "Test 5: lfs find no DOM files by stripe index: OK"
22133         return 0
22134 }
22135 run_test 270e "DoM: lfs find with DoM files test"
22136
22137 test_270f() {
22138         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
22139                 skip "Need MDS version at least 2.10.55"
22140
22141         local mdtname=${FSNAME}-MDT0000-mdtlov
22142         local dom=$DIR/$tdir/dom_file
22143         local dom_limit_saved=$(do_facet mds1 $LCTL get_param -n \
22144                                                 lod.$mdtname.dom_stripesize)
22145         local dom_limit=131072
22146
22147         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=$dom_limit
22148         local dom_current=$(do_facet mds1 $LCTL get_param -n \
22149                                                 lod.$mdtname.dom_stripesize)
22150         [ ${dom_limit} -eq ${dom_current} ] ||
22151                 error "Cannot change per-MDT DoM stripe limit to $dom_limit"
22152
22153         $LFS mkdir -i 0 -c 1 $DIR/$tdir
22154         $LFS setstripe -d $DIR/$tdir
22155         $LFS setstripe -E $dom_limit -L mdt $DIR/$tdir ||
22156                 error "Can't set directory default striping"
22157
22158         # exceed maximum stripe size
22159         $LFS setstripe -E $((dom_limit * 2)) -L mdt $dom ||
22160                 error "Can't create file with $((dom_limit * 2)) DoM stripe"
22161         [ $($LFS getstripe -S $dom) -eq $((dom_limit * 2)) ] &&
22162                 error "Able to create DoM component size more than LOD limit"
22163
22164         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=0
22165         dom_current=$(do_facet mds1 $LCTL get_param -n \
22166                                                 lod.$mdtname.dom_stripesize)
22167         [ 0 -eq ${dom_current} ] ||
22168                 error "Can't set zero DoM stripe limit"
22169         rm $dom
22170
22171         # attempt to create DoM file on server with disabled DoM should
22172         # remove DoM entry from layout and be succeed
22173         $LFS setstripe -E $dom_limit -L mdt -E -1 $dom ||
22174                 error "Can't create DoM file (DoM is disabled)"
22175         [ $($LFS getstripe -L $dom) == "mdt" ] &&
22176                 error "File has DoM component while DoM is disabled"
22177         rm $dom
22178
22179         # attempt to create DoM file with only DoM stripe should return error
22180         $LFS setstripe -E $dom_limit -L mdt $dom &&
22181                 error "Able to create DoM-only file while DoM is disabled"
22182
22183         # too low values to be aligned with smallest stripe size 64K
22184         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=30000
22185         dom_current=$(do_facet mds1 $LCTL get_param -n \
22186                                                 lod.$mdtname.dom_stripesize)
22187         [ 30000 -eq ${dom_current} ] &&
22188                 error "Can set too small DoM stripe limit"
22189
22190         # 64K is a minimal stripe size in Lustre, expect limit of that size
22191         [ 65536 -eq ${dom_current} ] ||
22192                 error "Limit is not set to 64K but ${dom_current}"
22193
22194         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=2147483648
22195         dom_current=$(do_facet mds1 $LCTL get_param -n \
22196                                                 lod.$mdtname.dom_stripesize)
22197         echo $dom_current
22198         [ 2147483648 -eq ${dom_current} ] &&
22199                 error "Can set too large DoM stripe limit"
22200
22201         do_facet mds1 $LCTL set_param -n \
22202                                 lod.$mdtname.dom_stripesize=$((dom_limit * 2))
22203         $LFS setstripe -E $((dom_limit * 2)) -L mdt $dom ||
22204                 error "Can't create DoM component size after limit change"
22205         do_facet mds1 $LCTL set_param -n \
22206                                 lod.$mdtname.dom_stripesize=$((dom_limit / 2))
22207         $LFS setstripe -E $dom_limit -L mdt ${dom}_big ||
22208                 error "Can't create DoM file after limit decrease"
22209         [ $($LFS getstripe -S ${dom}_big) -eq $((dom_limit / 2)) ] ||
22210                 error "Can create big DoM component after limit decrease"
22211         touch ${dom}_def ||
22212                 error "Can't create file with old default layout"
22213
22214         do_facet mds1 $LCTL set_param -n lod.*.dom_stripesize=$dom_limit_saved
22215         return 0
22216 }
22217 run_test 270f "DoM: maximum DoM stripe size checks"
22218
22219 test_270g() {
22220         [ $MDS1_VERSION -ge $(version_code 2.13.52) ] ||
22221                 skip "Need MDS version at least 2.13.52"
22222         local dom=$DIR/$tdir/$tfile
22223
22224         $LFS mkdir -i 0 -c 1 $DIR/$tdir
22225         local lodname=${FSNAME}-MDT0000-mdtlov
22226
22227         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
22228         save_lustre_params mds1 "lod.${lodname}.dom_stripesize_max_kb" > $save
22229         save_lustre_params mds1 "lod.${lodname}.dom_threshold_free_mb" >> $save
22230         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
22231
22232         local dom_limit=1024
22233         local dom_threshold="50%"
22234
22235         $LFS setstripe -d $DIR/$tdir
22236         $LFS setstripe -E ${dom_limit}K -L mdt $DIR/$tdir ||
22237                 error "Can't set directory default striping"
22238
22239         do_facet mds1 $LCTL set_param -n \
22240                                 lod.${lodname}.dom_stripesize_max_kb=$dom_limit
22241         # set 0 threshold and create DOM file to change tunable stripesize
22242         do_facet mds1 $LCTL set_param -n lod.${lodname}.dom_threshold_free_mb=0
22243         $LFS setstripe -E ${dom_limit}K -L mdt -E -1 $dom ||
22244                 error "Failed to create $dom file"
22245         # now tunable dom_cur_stripesize should reach maximum
22246         local dom_current=$(do_facet mds1 $LCTL get_param -n \
22247                                         lod.${lodname}.dom_stripesize_cur_kb)
22248         [[ $dom_current == $dom_limit ]] ||
22249                 error "Current DOM stripesize is not maximum"
22250         rm $dom
22251
22252         # set threshold for further tests
22253         do_facet mds1 $LCTL set_param -n \
22254                         lod.${lodname}.dom_threshold_free_mb=$dom_threshold
22255         echo "DOM threshold is $dom_threshold free space"
22256         local dom_def
22257         local dom_set
22258         # Spoof bfree to exceed threshold
22259         #define OBD_FAIL_MDS_STATFS_SPOOF   0x168
22260         do_facet mds1 $LCTL set_param -n fail_loc=0x0168
22261         for spfree in 40 20 0 15 30 55; do
22262                 do_facet mds1 $LCTL set_param -n fail_val=$spfree
22263                 $LFS setstripe -E ${dom_limit}K -L mdt -E -1 $dom ||
22264                         error "Failed to create $dom file"
22265                 dom_def=$(do_facet mds1 $LCTL get_param -n \
22266                                         lod.${lodname}.dom_stripesize_cur_kb)
22267                 echo "Free space: ${spfree}%, default DOM stripe: ${dom_def}K"
22268                 [[ $dom_def != $dom_current ]] ||
22269                         error "Default stripe size was not changed"
22270                 if [[ $spfree > 0 ]] ; then
22271                         dom_set=$($LFS getstripe -S $dom)
22272                         [[ $dom_set == $((dom_def * 1024)) ]] ||
22273                                 error "DOM component size is still old"
22274                 else
22275                         [[ $($LFS getstripe -L $dom) != "mdt" ]] ||
22276                                 error "DoM component is set with no free space"
22277                 fi
22278                 rm $dom
22279                 dom_current=$dom_def
22280         done
22281 }
22282 run_test 270g "DoM: default DoM stripe size depends on free space"
22283
22284 test_270h() {
22285         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
22286                 skip "Need MDS version at least 2.13.53"
22287
22288         local mdtname=${FSNAME}-MDT0000-mdtlov
22289         local dom=$DIR/$tdir/$tfile
22290         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
22291
22292         save_lustre_params mds1 "lod.*.dom_stripesize" > $save
22293         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
22294
22295         $LFS mkdir -i 0 -c 1 $DIR/$tdir
22296         $LFS setstripe -E 1M -c1  -E -1 -c2 ${dom}_1 ||
22297                 error "can't create OST file"
22298         # mirrored file with DOM entry in the second mirror
22299         $LFS mirror extend -N -E 1M -L mdt -E eof -c2 ${dom}_1 ||
22300                 error "can't create mirror with DoM component"
22301
22302         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=0
22303
22304         # DOM component in the middle and has other enries in the same mirror,
22305         # should succeed but lost DoM component
22306         $LFS setstripe --copy=${dom}_1 $dom ||
22307                 error "Can't create file from OST|DOM mirror layout"
22308         # check new file has no DoM layout after all
22309         [[ $($LFS getstripe -L $dom) != "mdt" ]] ||
22310                 error "File has DoM component while DoM is disabled"
22311 }
22312 run_test 270h "DoM: DoM stripe removal when disabled on server"
22313
22314 test_270i() {
22315         (( $MDS1_VERSION >= $(version_code 2.14.54) )) ||
22316                 skip "Need MDS version at least 2.14.54"
22317
22318         mkdir $DIR/$tdir
22319         $LFS setstripe -L mdt -S 128k -c -1 $DIR/$tdir &&
22320                 error "setstripe should fail" || true
22321 }
22322 run_test 270i "DoM: setting invalid DoM striping should fail"
22323
22324 test_271a() {
22325         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
22326                 skip "Need MDS version at least 2.10.55"
22327
22328         local dom=$DIR/$tdir/dom
22329
22330         mkdir -p $DIR/$tdir
22331
22332         $LFS setstripe -E 1024K -L mdt $dom
22333
22334         lctl set_param -n mdc.*.stats=clear
22335         dd if=/dev/zero of=$dom bs=4096 count=1 || return 1
22336         cat $dom > /dev/null
22337         local reads=$(lctl get_param -n mdc.*.stats | grep -c ost_read)
22338         [ $reads -eq 0 ] || error "Unexpected $reads READ RPCs"
22339         ls $dom
22340         rm -f $dom
22341 }
22342 run_test 271a "DoM: data is cached for read after write"
22343
22344 test_271b() {
22345         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
22346                 skip "Need MDS version at least 2.10.55"
22347
22348         local dom=$DIR/$tdir/dom
22349
22350         mkdir -p $DIR/$tdir
22351
22352         $LFS setstripe -E 1024K -L mdt -E EOF $dom
22353
22354         lctl set_param -n mdc.*.stats=clear
22355         dd if=/dev/zero of=$dom bs=4096 count=1 || return 1
22356         cancel_lru_locks mdc
22357         $CHECKSTAT -t file -s 4096 $dom || error "stat #1 fails"
22358         # second stat to check size is cached on client
22359         $CHECKSTAT -t file -s 4096 $dom || error "stat #2 fails"
22360         local gls=$(lctl get_param -n mdc.*.stats | grep -c ldlm_glimpse)
22361         [ $gls -eq 0 ] || error "Unexpected $gls glimpse RPCs"
22362         rm -f $dom
22363 }
22364 run_test 271b "DoM: no glimpse RPC for stat (DoM only file)"
22365
22366 test_271ba() {
22367         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
22368                 skip "Need MDS version at least 2.10.55"
22369
22370         local dom=$DIR/$tdir/dom
22371
22372         mkdir -p $DIR/$tdir
22373
22374         $LFS setstripe -E 1024K -L mdt -E EOF $dom
22375
22376         lctl set_param -n mdc.*.stats=clear
22377         lctl set_param -n osc.*.stats=clear
22378         dd if=/dev/zero of=$dom bs=2048K count=1 || return 1
22379         cancel_lru_locks mdc
22380         $CHECKSTAT -t file -s 2097152 $dom || error "stat"
22381         # second stat to check size is cached on client
22382         $CHECKSTAT -t file -s 2097152 $dom || error "stat"
22383         local gls=$(lctl get_param -n mdc.*.stats | grep -c ldlm_glimpse)
22384         [ $gls == 0 ] || error "Unexpected $gls glimpse RPCs"
22385         local gls=$(lctl get_param -n osc.*.stats | grep -c ldlm_glimpse)
22386         [ $gls == 0 ] || error "Unexpected $gls OSC glimpse RPCs"
22387         rm -f $dom
22388 }
22389 run_test 271ba "DoM: no glimpse RPC for stat (combined file)"
22390
22391
22392 get_mdc_stats() {
22393         local mdtidx=$1
22394         local param=$2
22395         local mdt=MDT$(printf %04x $mdtidx)
22396
22397         if [ -z $param ]; then
22398                 lctl get_param -n mdc.*$mdt*.stats
22399         else
22400                 lctl get_param -n mdc.*$mdt*.stats | awk "/$param/"'{print $2}'
22401         fi
22402 }
22403
22404 test_271c() {
22405         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
22406                 skip "Need MDS version at least 2.10.55"
22407
22408         local dom=$DIR/$tdir/dom
22409
22410         mkdir -p $DIR/$tdir
22411
22412         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
22413
22414         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
22415         local facet=mds$((mdtidx + 1))
22416
22417         cancel_lru_locks mdc
22418         do_facet $facet lctl set_param -n mdt.*.dom_lock=0
22419         createmany -o $dom 1000
22420         lctl set_param -n mdc.*.stats=clear
22421         smalliomany -w $dom 1000 200
22422         get_mdc_stats $mdtidx
22423         local enq=$(get_mdc_stats $mdtidx ldlm_ibits_enqueue)
22424         # Each file has 1 open, 1 IO enqueues, total 2000
22425         # but now we have also +1 getxattr for security.capability, total 3000
22426         [ $enq -ge 2000 ] || error "Too few enqueues $enq, expected > 2000"
22427         unlinkmany $dom 1000
22428
22429         cancel_lru_locks mdc
22430         do_facet $facet lctl set_param -n mdt.*.dom_lock=1
22431         createmany -o $dom 1000
22432         lctl set_param -n mdc.*.stats=clear
22433         smalliomany -w $dom 1000 200
22434         local enq_2=$(get_mdc_stats $mdtidx ldlm_ibits_enqueue)
22435         # Expect to see reduced amount of RPCs by 1000 due to single enqueue
22436         # for OPEN and IO lock.
22437         [ $((enq - enq_2)) -ge 1000 ] ||
22438                 error "Too many enqueues $enq_2, expected about $((enq - 1000))"
22439         unlinkmany $dom 1000
22440         return 0
22441 }
22442 run_test 271c "DoM: IO lock at open saves enqueue RPCs"
22443
22444 cleanup_271def_tests() {
22445         trap 0
22446         rm -f $1
22447 }
22448
22449 test_271d() {
22450         [ $MDS1_VERSION -lt $(version_code 2.10.57) ] &&
22451                 skip "Need MDS version at least 2.10.57"
22452
22453         local dom=$DIR/$tdir/dom
22454         local tmp=$TMP/$tfile
22455         trap "cleanup_271def_tests $tmp" EXIT
22456
22457         mkdir -p $DIR/$tdir
22458
22459         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
22460
22461         local mdtidx=$($LFS getstripe --mdt-index $DIR/$tdir)
22462
22463         cancel_lru_locks mdc
22464         dd if=/dev/urandom of=$tmp bs=1000 count=1
22465         dd if=$tmp of=$dom bs=1000 count=1
22466         cancel_lru_locks mdc
22467
22468         cat /etc/hosts >> $tmp
22469         lctl set_param -n mdc.*.stats=clear
22470
22471         # append data to the same file it should update local page
22472         echo "Append to the same page"
22473         cat /etc/hosts >> $dom
22474         local num=$(get_mdc_stats $mdtidx ost_read)
22475         local ra=$(get_mdc_stats $mdtidx req_active)
22476         local rw=$(get_mdc_stats $mdtidx req_waittime)
22477
22478         [ -z $num ] || error "$num READ RPC occured"
22479         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
22480         echo "... DONE"
22481
22482         # compare content
22483         cmp $tmp $dom || error "file miscompare"
22484
22485         cancel_lru_locks mdc
22486         lctl set_param -n mdc.*.stats=clear
22487
22488         echo "Open and read file"
22489         cat $dom > /dev/null
22490         local num=$(get_mdc_stats $mdtidx ost_read)
22491         local ra=$(get_mdc_stats $mdtidx req_active)
22492         local rw=$(get_mdc_stats $mdtidx req_waittime)
22493
22494         [ -z $num ] || error "$num READ RPC occured"
22495         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
22496         echo "... DONE"
22497
22498         # compare content
22499         cmp $tmp $dom || error "file miscompare"
22500
22501         return 0
22502 }
22503 run_test 271d "DoM: read on open (1K file in reply buffer)"
22504
22505 test_271f() {
22506         [ $MDS1_VERSION -lt $(version_code 2.10.57) ] &&
22507                 skip "Need MDS version at least 2.10.57"
22508
22509         local dom=$DIR/$tdir/dom
22510         local tmp=$TMP/$tfile
22511         trap "cleanup_271def_tests $tmp" EXIT
22512
22513         mkdir -p $DIR/$tdir
22514
22515         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
22516
22517         local mdtidx=$($LFS getstripe --mdt-index $DIR/$tdir)
22518
22519         cancel_lru_locks mdc
22520         dd if=/dev/urandom of=$tmp bs=265000 count=1
22521         dd if=$tmp of=$dom bs=265000 count=1
22522         cancel_lru_locks mdc
22523         cat /etc/hosts >> $tmp
22524         lctl set_param -n mdc.*.stats=clear
22525
22526         echo "Append to the same page"
22527         cat /etc/hosts >> $dom
22528         local num=$(get_mdc_stats $mdtidx ost_read)
22529         local ra=$(get_mdc_stats $mdtidx req_active)
22530         local rw=$(get_mdc_stats $mdtidx req_waittime)
22531
22532         [ -z $num ] || error "$num READ RPC occured"
22533         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
22534         echo "... DONE"
22535
22536         # compare content
22537         cmp $tmp $dom || error "file miscompare"
22538
22539         cancel_lru_locks mdc
22540         lctl set_param -n mdc.*.stats=clear
22541
22542         echo "Open and read file"
22543         cat $dom > /dev/null
22544         local num=$(get_mdc_stats $mdtidx ost_read)
22545         local ra=$(get_mdc_stats $mdtidx req_active)
22546         local rw=$(get_mdc_stats $mdtidx req_waittime)
22547
22548         [ -z $num ] && num=0
22549         [ $num -eq 1 ] || error "expect 1 READ RPC, $num occured"
22550         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
22551         echo "... DONE"
22552
22553         # compare content
22554         cmp $tmp $dom || error "file miscompare"
22555
22556         return 0
22557 }
22558 run_test 271f "DoM: read on open (200K file and read tail)"
22559
22560 test_271g() {
22561         [[ $($LCTL get_param mdc.*.import) =~ async_discard ]] ||
22562                 skip "Skipping due to old client or server version"
22563
22564         $LFS setstripe -E 1024K -L mdt -E EOF $DIR1/$tfile
22565         # to get layout
22566         $CHECKSTAT -t file $DIR1/$tfile
22567
22568         $MULTIOP $DIR1/$tfile Ow40960_w4096c &
22569         MULTIOP_PID=$!
22570         sleep 1
22571         #define OBD_FAIL_LDLM_CANCEL_BL_CB_RACE
22572         $LCTL set_param fail_loc=0x80000314
22573         rm $DIR1/$tfile || error "Unlink fails"
22574         RC=$?
22575         kill -USR1 $MULTIOP_PID && wait $MULTIOP_PID || error "multiop failure"
22576         [ $RC -eq 0 ] || error "Failed write to stale object"
22577 }
22578 run_test 271g "Discard DoM data vs client flush race"
22579
22580 test_272a() {
22581         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
22582                 skip "Need MDS version at least 2.11.50"
22583
22584         local dom=$DIR/$tdir/dom
22585         mkdir -p $DIR/$tdir
22586
22587         $LFS setstripe -E 256K -L mdt -E -1 -c1 $dom
22588         dd if=/dev/urandom of=$dom bs=512K count=1 ||
22589                 error "failed to write data into $dom"
22590         local old_md5=$(md5sum $dom)
22591
22592         $LFS migrate -E 256K -L mdt -E -1 -c2 $dom ||
22593                 error "failed to migrate to the same DoM component"
22594
22595         local new_md5=$(md5sum $dom)
22596
22597         [ "$old_md5" == "$new_md5" ] ||
22598                 error "md5sum differ: $old_md5, $new_md5"
22599
22600         [ $($LFS getstripe -c $dom) -eq 2 ] ||
22601                 error "bad final stripe count: $($LFS getstripe -c $dom) != 2"
22602 }
22603 run_test 272a "DoM migration: new layout with the same DOM component"
22604
22605 test_272b() {
22606         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
22607                 skip "Need MDS version at least 2.11.50"
22608
22609         local dom=$DIR/$tdir/dom
22610         mkdir -p $DIR/$tdir
22611         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
22612
22613         local mdtidx=$($LFS getstripe -m $dom)
22614         local mdtname=MDT$(printf %04x $mdtidx)
22615         local facet=mds$((mdtidx + 1))
22616
22617         local mdtfree1=$(do_facet $facet \
22618                 lctl get_param -n osd*.*$mdtname.kbytesfree)
22619         dd if=/dev/urandom of=$dom bs=2M count=1 ||
22620                 error "failed to write data into $dom"
22621         local old_md5=$(md5sum $dom)
22622         cancel_lru_locks mdc
22623         local mdtfree1=$(do_facet $facet \
22624                 lctl get_param -n osd*.*$mdtname.kbytesfree)
22625
22626         $LFS migrate -c2 $dom ||
22627                 error "failed to migrate to the new composite layout"
22628         [ $($LFS getstripe -L $dom) != 'mdt' ] ||
22629                 error "MDT stripe was not removed"
22630
22631         cancel_lru_locks mdc
22632         local new_md5=$(md5sum $dom)
22633         [ "$old_md5" == "$new_md5" ] ||
22634                 error "$old_md5 != $new_md5"
22635
22636         # Skip free space checks with ZFS
22637         if [ "$(facet_fstype $facet)" != "zfs" ]; then
22638                 local mdtfree2=$(do_facet $facet \
22639                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
22640                 [ $mdtfree2 -gt $mdtfree1 ] ||
22641                         error "MDT space is not freed after migration"
22642         fi
22643         return 0
22644 }
22645 run_test 272b "DoM migration: DOM file to the OST-striped file (plain)"
22646
22647 test_272c() {
22648         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
22649                 skip "Need MDS version at least 2.11.50"
22650
22651         local dom=$DIR/$tdir/$tfile
22652         mkdir -p $DIR/$tdir
22653         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
22654
22655         local mdtidx=$($LFS getstripe -m $dom)
22656         local mdtname=MDT$(printf %04x $mdtidx)
22657         local facet=mds$((mdtidx + 1))
22658
22659         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
22660                 error "failed to write data into $dom"
22661         local old_md5=$(md5sum $dom)
22662         cancel_lru_locks mdc
22663         local mdtfree1=$(do_facet $facet \
22664                 lctl get_param -n osd*.*$mdtname.kbytesfree)
22665
22666         $LFS migrate -E 2M -c1 -E -1 -c2 $dom ||
22667                 error "failed to migrate to the new composite layout"
22668         [ $($LFS getstripe -L $dom) == 'mdt' ] &&
22669                 error "MDT stripe was not removed"
22670
22671         cancel_lru_locks mdc
22672         local new_md5=$(md5sum $dom)
22673         [ "$old_md5" == "$new_md5" ] ||
22674                 error "$old_md5 != $new_md5"
22675
22676         # Skip free space checks with ZFS
22677         if [ "$(facet_fstype $facet)" != "zfs" ]; then
22678                 local mdtfree2=$(do_facet $facet \
22679                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
22680                 [ $mdtfree2 -gt $mdtfree1 ] ||
22681                         error "MDS space is not freed after migration"
22682         fi
22683         return 0
22684 }
22685 run_test 272c "DoM migration: DOM file to the OST-striped file (composite)"
22686
22687 test_272d() {
22688         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
22689                 skip "Need MDS version at least 2.12.55"
22690
22691         local dom=$DIR/$tdir/$tfile
22692         mkdir -p $DIR/$tdir
22693         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
22694
22695         local mdtidx=$($LFS getstripe -m $dom)
22696         local mdtname=MDT$(printf %04x $mdtidx)
22697         local facet=mds$((mdtidx + 1))
22698
22699         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
22700                 error "failed to write data into $dom"
22701         local old_md5=$(md5sum $dom)
22702         cancel_lru_locks mdc
22703         local mdtfree1=$(do_facet $facet \
22704                 lctl get_param -n osd*.*$mdtname.kbytesfree)
22705
22706         $LFS mirror extend -N -E 2M -c1 -E -1 -c2 $dom ||
22707                 error "failed mirroring to the new composite layout"
22708         $LFS mirror resync $dom ||
22709                 error "failed mirror resync"
22710         $LFS mirror split --mirror-id 1 -d $dom ||
22711                 error "failed mirror split"
22712
22713         [ $($LFS getstripe -L $dom) != 'mdt' ] ||
22714                 error "MDT stripe was not removed"
22715
22716         cancel_lru_locks mdc
22717         local new_md5=$(md5sum $dom)
22718         [ "$old_md5" == "$new_md5" ] ||
22719                 error "$old_md5 != $new_md5"
22720
22721         # Skip free space checks with ZFS
22722         if [ "$(facet_fstype $facet)" != "zfs" ]; then
22723                 local mdtfree2=$(do_facet $facet \
22724                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
22725                 [ $mdtfree2 -gt $mdtfree1 ] ||
22726                         error "MDS space is not freed after DOM mirror deletion"
22727         fi
22728         return 0
22729 }
22730 run_test 272d "DoM mirroring: OST-striped mirror to DOM file"
22731
22732 test_272e() {
22733         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
22734                 skip "Need MDS version at least 2.12.55"
22735
22736         local dom=$DIR/$tdir/$tfile
22737         mkdir -p $DIR/$tdir
22738         $LFS setstripe -c 2 $dom
22739
22740         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
22741                 error "failed to write data into $dom"
22742         local old_md5=$(md5sum $dom)
22743         cancel_lru_locks
22744
22745         $LFS mirror extend -N -E 1M -L mdt -E eof -c2 $dom ||
22746                 error "failed mirroring to the DOM layout"
22747         $LFS mirror resync $dom ||
22748                 error "failed mirror resync"
22749         $LFS mirror split --mirror-id 1 -d $dom ||
22750                 error "failed mirror split"
22751
22752         [[ $($LFS getstripe -L --component-start=0 $dom) == 'mdt' ]] ||
22753                 error "MDT stripe wasn't set"
22754
22755         cancel_lru_locks
22756         local new_md5=$(md5sum $dom)
22757         [ "$old_md5" == "$new_md5" ] ||
22758                 error "$old_md5 != $new_md5"
22759
22760         return 0
22761 }
22762 run_test 272e "DoM mirroring: DOM mirror to the OST-striped file"
22763
22764 test_272f() {
22765         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
22766                 skip "Need MDS version at least 2.12.55"
22767
22768         local dom=$DIR/$tdir/$tfile
22769         mkdir -p $DIR/$tdir
22770         $LFS setstripe -c 2 $dom
22771
22772         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
22773                 error "failed to write data into $dom"
22774         local old_md5=$(md5sum $dom)
22775         cancel_lru_locks
22776
22777         $LFS migrate -E 1M -L mdt -E eof -c2 -v $dom ||
22778                 error "failed migrating to the DOM file"
22779
22780         [[ $($LFS getstripe -L --component-start=0 $dom) == 'mdt' ]] ||
22781                 error "MDT stripe wasn't set"
22782
22783         cancel_lru_locks
22784         local new_md5=$(md5sum $dom)
22785         [ "$old_md5" != "$new_md5" ] &&
22786                 error "$old_md5 != $new_md5"
22787
22788         return 0
22789 }
22790 run_test 272f "DoM migration: OST-striped file to DOM file"
22791
22792 test_273a() {
22793         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
22794                 skip "Need MDS version at least 2.11.50"
22795
22796         # Layout swap cannot be done if either file has DOM component,
22797         # this will never be supported, migration should be used instead
22798
22799         local dom=$DIR/$tdir/$tfile
22800         mkdir -p $DIR/$tdir
22801
22802         $LFS setstripe -c2 ${dom}_plain
22803         $LFS setstripe -E 1M -L mdt -E -1 -c2 ${dom}_dom
22804         $LFS swap_layouts ${dom}_plain ${dom}_dom &&
22805                 error "can swap layout with DoM component"
22806         $LFS swap_layouts ${dom}_dom ${dom}_plain &&
22807                 error "can swap layout with DoM component"
22808
22809         $LFS setstripe -E 1M -c1 -E -1 -c2 ${dom}_comp
22810         $LFS swap_layouts ${dom}_comp ${dom}_dom &&
22811                 error "can swap layout with DoM component"
22812         $LFS swap_layouts ${dom}_dom ${dom}_comp &&
22813                 error "can swap layout with DoM component"
22814         return 0
22815 }
22816 run_test 273a "DoM: layout swapping should fail with DOM"
22817
22818 test_273b() {
22819         mkdir -p $DIR/$tdir
22820         $LFS setstripe -E 1M -L mdt -E -1 -c -1 $DIR/$tdir
22821
22822 #define OBD_FAIL_MDS_COMMITRW_DELAY      0x16b
22823         do_facet mds1 $LCTL set_param fail_loc=0x8000016b fail_val=2
22824
22825         $MULTIOP $DIR/$tdir/$tfile Ouw2097152c
22826 }
22827 run_test 273b "DoM: race writeback and object destroy"
22828
22829 test_275() {
22830         remote_ost_nodsh && skip "remote OST with nodsh"
22831         [ $OST1_VERSION -lt $(version_code 2.10.57) ] &&
22832                 skip "Need OST version >= 2.10.57"
22833
22834         local file=$DIR/$tfile
22835         local oss
22836
22837         oss=$(comma_list $(osts_nodes))
22838
22839         dd if=/dev/urandom of=$file bs=1M count=2 ||
22840                 error "failed to create a file"
22841         cancel_lru_locks osc
22842
22843         #lock 1
22844         dd if=$file of=/dev/null bs=1M count=1 iflag=direct ||
22845                 error "failed to read a file"
22846
22847 #define OBD_FAIL_LDLM_PAUSE_CANCEL2      0x31f
22848         $LCTL set_param fail_loc=0x8000031f
22849
22850         cancel_lru_locks osc &
22851         sleep 1
22852
22853 #define OBD_FAIL_LDLM_PROLONG_PAUSE      0x32b
22854         do_nodes $oss $LCTL set_param fail_loc=0x8000032b
22855         #IO takes another lock, but matches the PENDING one
22856         #and places it to the IO RPC
22857         dd if=$file of=/dev/null bs=1M count=1 iflag=direct ||
22858                 error "failed to read a file with PENDING lock"
22859 }
22860 run_test 275 "Read on a canceled duplicate lock"
22861
22862 test_276() {
22863         remote_ost_nodsh && skip "remote OST with nodsh"
22864         local pid
22865
22866         do_facet ost1 "(while true; do \
22867                 $LCTL get_param obdfilter.*.filesfree > /dev/null 2>&1; \
22868                 done) & pid=\\\$!; echo \\\$pid > $TMP/sanity_276_pid" &
22869         pid=$!
22870
22871         for LOOP in $(seq 20); do
22872                 stop ost1
22873                 start ost1 $(ostdevname 1) $OST_MOUNT_OPTS
22874         done
22875         kill -9 $pid
22876         do_facet ost1 "pid=\\\$(cat $TMP/sanity_276_pid); kill -9 \\\$pid; \
22877                 rm $TMP/sanity_276_pid"
22878 }
22879 run_test 276 "Race between mount and obd_statfs"
22880
22881 test_277() {
22882         $LCTL set_param ldlm.namespaces.*.lru_size=0
22883         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
22884         local cached_mb=$($LCTL get_param llite.*.max_cached_mb |
22885                         grep ^used_mb | awk '{print $2}')
22886         [ $cached_mb -eq 1 ] || error "expected mb 1 got $cached_mb"
22887         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 \
22888                 oflag=direct conv=notrunc
22889         cached_mb=$($LCTL get_param llite.*.max_cached_mb |
22890                         grep ^used_mb | awk '{print $2}')
22891         [ $cached_mb -eq 0 ] || error "expected mb 0 got $cached_mb"
22892 }
22893 run_test 277 "Direct IO shall drop page cache"
22894
22895 test_278() {
22896         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
22897         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
22898         [[ "$(facet_host mds1)" != "$(facet_host mds2)" ]] &&
22899                 skip "needs the same host for mdt1 mdt2" && return
22900
22901         local pid1
22902         local pid2
22903
22904 #define OBD_FAIL_OBD_STOP_MDS_RACE     0x60b
22905         do_facet mds2 $LCTL set_param fail_loc=0x8000060c
22906         stop mds2 &
22907         pid2=$!
22908
22909         stop mds1
22910
22911         echo "Starting MDTs"
22912         start mds1 $(mdsdevname 1) $MDS_MOUNT_OPTS
22913         wait $pid2
22914 #For the error assertion will happen. lu_env_get_key(..., &mdt_thread_key)
22915 #will return NULL
22916         do_facet mds2 $LCTL set_param fail_loc=0
22917
22918         start mds2 $(mdsdevname 2) $MDS_MOUNT_OPTS
22919         wait_recovery_complete mds2
22920 }
22921 run_test 278 "Race starting MDS between MDTs stop/start"
22922
22923 test_280() {
22924         [ $MGS_VERSION -lt $(version_code 2.13.52) ] &&
22925                 skip "Need MGS version at least 2.13.52"
22926         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22927         combined_mgs_mds || skip "needs combined MGS/MDT"
22928
22929         umount_client $MOUNT
22930 #define OBD_FAIL_MDS_LLOG_UMOUNT_RACE   0x15e
22931         do_facet mgs $LCTL set_param fail_loc=0x8000015e fail_val=0
22932
22933         mount_client $MOUNT &
22934         sleep 1
22935         stop mgs || error "stop mgs failed"
22936         #for a race mgs would crash
22937         start mgs $(mgsdevname) $MGS_MOUNT_OPTS || error "start mgs failed"
22938         # make sure we unmount client before remounting
22939         wait
22940         umount_client $MOUNT
22941         mount_client $MOUNT || error "mount client failed"
22942 }
22943 run_test 280 "Race between MGS umount and client llog processing"
22944
22945 cleanup_test_300() {
22946         trap 0
22947         umask $SAVE_UMASK
22948 }
22949 test_striped_dir() {
22950         local mdt_index=$1
22951         local stripe_count
22952         local stripe_index
22953
22954         mkdir -p $DIR/$tdir
22955
22956         SAVE_UMASK=$(umask)
22957         trap cleanup_test_300 RETURN EXIT
22958
22959         $LFS setdirstripe -i $mdt_index -c 2 -H all_char -o 755 \
22960                                                 $DIR/$tdir/striped_dir ||
22961                 error "set striped dir error"
22962
22963         local mode=$(stat -c%a $DIR/$tdir/striped_dir)
22964         [ "$mode" = "755" ] || error "expect 755 got $mode"
22965
22966         $LFS getdirstripe $DIR/$tdir/striped_dir > /dev/null 2>&1 ||
22967                 error "getdirstripe failed"
22968         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir)
22969         if [ "$stripe_count" != "2" ]; then
22970                 error "1:stripe_count is $stripe_count, expect 2"
22971         fi
22972         stripe_count=$($LFS getdirstripe -T $DIR/$tdir/striped_dir)
22973         if [ "$stripe_count" != "2" ]; then
22974                 error "2:stripe_count is $stripe_count, expect 2"
22975         fi
22976
22977         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir)
22978         if [ "$stripe_index" != "$mdt_index" ]; then
22979                 error "stripe_index is $stripe_index, expect $mdt_index"
22980         fi
22981
22982         [ $(stat -c%h $DIR/$tdir/striped_dir) == '2' ] ||
22983                 error "nlink error after create striped dir"
22984
22985         mkdir $DIR/$tdir/striped_dir/a
22986         mkdir $DIR/$tdir/striped_dir/b
22987
22988         stat $DIR/$tdir/striped_dir/a ||
22989                 error "create dir under striped dir failed"
22990         stat $DIR/$tdir/striped_dir/b ||
22991                 error "create dir under striped dir failed"
22992
22993         [ $(stat -c%h $DIR/$tdir/striped_dir) == '4' ] ||
22994                 error "nlink error after mkdir"
22995
22996         rmdir $DIR/$tdir/striped_dir/a
22997         [ $(stat -c%h $DIR/$tdir/striped_dir) == '3' ] ||
22998                 error "nlink error after rmdir"
22999
23000         rmdir $DIR/$tdir/striped_dir/b
23001         [ $(stat -c%h $DIR/$tdir/striped_dir) == '2' ] ||
23002                 error "nlink error after rmdir"
23003
23004         chattr +i $DIR/$tdir/striped_dir
23005         createmany -o $DIR/$tdir/striped_dir/f 10 &&
23006                 error "immutable flags not working under striped dir!"
23007         chattr -i $DIR/$tdir/striped_dir
23008
23009         rmdir $DIR/$tdir/striped_dir ||
23010                 error "rmdir striped dir error"
23011
23012         cleanup_test_300
23013
23014         true
23015 }
23016
23017 test_300a() {
23018         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
23019                 skip "skipped for lustre < 2.7.0"
23020         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23021         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23022
23023         test_striped_dir 0 || error "failed on striped dir on MDT0"
23024         test_striped_dir 1 || error "failed on striped dir on MDT0"
23025 }
23026 run_test 300a "basic striped dir sanity test"
23027
23028 test_300b() {
23029         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
23030                 skip "skipped for lustre < 2.7.0"
23031         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23032         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23033
23034         local i
23035         local mtime1
23036         local mtime2
23037         local mtime3
23038
23039         test_mkdir $DIR/$tdir || error "mkdir fail"
23040         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
23041                 error "set striped dir error"
23042         for i in {0..9}; do
23043                 mtime1=$(stat -c %Y $DIR/$tdir/striped_dir)
23044                 sleep 1
23045                 touch $DIR/$tdir/striped_dir/file_$i || error "touch error $i"
23046                 mtime2=$(stat -c %Y $DIR/$tdir/striped_dir)
23047                 [ $mtime1 -eq $mtime2 ] && error "mtime unchanged after create"
23048                 sleep 1
23049                 rm -f $DIR/$tdir/striped_dir/file_$i || error "unlink error $i"
23050                 mtime3=$(stat -c %Y $DIR/$tdir/striped_dir)
23051                 [ $mtime2 -eq $mtime3 ] && error "mtime unchanged after unlink"
23052         done
23053         true
23054 }
23055 run_test 300b "check ctime/mtime for striped dir"
23056
23057 test_300c() {
23058         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
23059                 skip "skipped for lustre < 2.7.0"
23060         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23061         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23062
23063         local file_count
23064
23065         mkdir_on_mdt0 $DIR/$tdir
23066         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir ||
23067                 error "set striped dir error"
23068
23069         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/striped_dir ||
23070                 error "chown striped dir failed"
23071
23072         $RUNAS createmany -o $DIR/$tdir/striped_dir/f 5000 ||
23073                 error "create 5k files failed"
23074
23075         file_count=$(ls $DIR/$tdir/striped_dir | wc -l)
23076
23077         [ "$file_count" = 5000 ] || error "file count $file_count != 5000"
23078
23079         rm -rf $DIR/$tdir
23080 }
23081 run_test 300c "chown && check ls under striped directory"
23082
23083 test_300d() {
23084         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
23085                 skip "skipped for lustre < 2.7.0"
23086         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23087         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23088
23089         local stripe_count
23090         local file
23091
23092         mkdir -p $DIR/$tdir
23093         $LFS setstripe -c 2 $DIR/$tdir
23094
23095         #local striped directory
23096         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
23097                 error "set striped dir error"
23098         #look at the directories for debug purposes
23099         ls -l $DIR/$tdir
23100         $LFS getdirstripe $DIR/$tdir
23101         ls -l $DIR/$tdir/striped_dir
23102         $LFS getdirstripe $DIR/$tdir/striped_dir
23103         createmany -o $DIR/$tdir/striped_dir/f 10 ||
23104                 error "create 10 files failed"
23105
23106         #remote striped directory
23107         $LFS setdirstripe -i 1 -c 2 $DIR/$tdir/remote_striped_dir ||
23108                 error "set striped dir error"
23109         #look at the directories for debug purposes
23110         ls -l $DIR/$tdir
23111         $LFS getdirstripe $DIR/$tdir
23112         ls -l $DIR/$tdir/remote_striped_dir
23113         $LFS getdirstripe $DIR/$tdir/remote_striped_dir
23114         createmany -o $DIR/$tdir/remote_striped_dir/f 10 ||
23115                 error "create 10 files failed"
23116
23117         for file in $(find $DIR/$tdir); do
23118                 stripe_count=$($LFS getstripe -c $file)
23119                 [ $stripe_count -eq 2 ] ||
23120                         error "wrong stripe $stripe_count for $file"
23121         done
23122
23123         rm -rf $DIR/$tdir
23124 }
23125 run_test 300d "check default stripe under striped directory"
23126
23127 test_300e() {
23128         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23129                 skip "Need MDS version at least 2.7.55"
23130         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23131         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23132
23133         local stripe_count
23134         local file
23135
23136         mkdir -p $DIR/$tdir
23137
23138         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
23139                 error "set striped dir error"
23140
23141         touch $DIR/$tdir/striped_dir/a
23142         touch $DIR/$tdir/striped_dir/b
23143         touch $DIR/$tdir/striped_dir/c
23144
23145         mkdir $DIR/$tdir/striped_dir/dir_a
23146         mkdir $DIR/$tdir/striped_dir/dir_b
23147         mkdir $DIR/$tdir/striped_dir/dir_c
23148
23149         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_a ||
23150                 error "set striped adir under striped dir error"
23151
23152         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_b ||
23153                 error "set striped bdir under striped dir error"
23154
23155         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_c ||
23156                 error "set striped cdir under striped dir error"
23157
23158         mrename $DIR/$tdir/striped_dir/dir_a $DIR/$tdir/striped_dir/dir_b ||
23159                 error "rename dir under striped dir fails"
23160
23161         mrename $DIR/$tdir/striped_dir/stp_a $DIR/$tdir/striped_dir/stp_b ||
23162                 error "rename dir under different stripes fails"
23163
23164         mrename $DIR/$tdir/striped_dir/a $DIR/$tdir/striped_dir/c ||
23165                 error "rename file under striped dir should succeed"
23166
23167         mrename $DIR/$tdir/striped_dir/dir_b $DIR/$tdir/striped_dir/dir_c ||
23168                 error "rename dir under striped dir should succeed"
23169
23170         rm -rf $DIR/$tdir
23171 }
23172 run_test 300e "check rename under striped directory"
23173
23174 test_300f() {
23175         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23176         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23177         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23178                 skip "Need MDS version at least 2.7.55"
23179
23180         local stripe_count
23181         local file
23182
23183         rm -rf $DIR/$tdir
23184         mkdir -p $DIR/$tdir
23185
23186         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
23187                 error "set striped dir error"
23188
23189         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir1 ||
23190                 error "set striped dir error"
23191
23192         touch $DIR/$tdir/striped_dir/a
23193         mkdir $DIR/$tdir/striped_dir/dir_a
23194         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir/stp_a ||
23195                 error "create striped dir under striped dir fails"
23196
23197         touch $DIR/$tdir/striped_dir1/b
23198         mkdir $DIR/$tdir/striped_dir1/dir_b
23199         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir/stp_b ||
23200                 error "create striped dir under striped dir fails"
23201
23202         mrename $DIR/$tdir/striped_dir/dir_a $DIR/$tdir/striped_dir1/dir_b ||
23203                 error "rename dir under different striped dir should fail"
23204
23205         mrename $DIR/$tdir/striped_dir/stp_a $DIR/$tdir/striped_dir1/stp_b ||
23206                 error "rename striped dir under diff striped dir should fail"
23207
23208         mrename $DIR/$tdir/striped_dir/a $DIR/$tdir/striped_dir1/a ||
23209                 error "rename file under diff striped dirs fails"
23210
23211         rm -rf $DIR/$tdir
23212 }
23213 run_test 300f "check rename cross striped directory"
23214
23215 test_300_check_default_striped_dir()
23216 {
23217         local dirname=$1
23218         local default_count=$2
23219         local default_index=$3
23220         local stripe_count
23221         local stripe_index
23222         local dir_stripe_index
23223         local dir
23224
23225         echo "checking $dirname $default_count $default_index"
23226         $LFS setdirstripe -D -c $default_count -i $default_index \
23227                                 -H all_char $DIR/$tdir/$dirname ||
23228                 error "set default stripe on striped dir error"
23229         stripe_count=$($LFS getdirstripe -D -c $DIR/$tdir/$dirname)
23230         [ $stripe_count -eq $default_count ] ||
23231                 error "expect $default_count get $stripe_count for $dirname"
23232
23233         stripe_index=$($LFS getdirstripe -D -i $DIR/$tdir/$dirname)
23234         [ $stripe_index -eq $default_index ] ||
23235                 error "expect $default_index get $stripe_index for $dirname"
23236
23237         mkdir $DIR/$tdir/$dirname/{test1,test2,test3,test4} ||
23238                                                 error "create dirs failed"
23239
23240         createmany -o $DIR/$tdir/$dirname/f- 10 || error "create files failed"
23241         unlinkmany $DIR/$tdir/$dirname/f- 10    || error "unlink files failed"
23242         for dir in $(find $DIR/$tdir/$dirname/*); do
23243                 stripe_count=$($LFS getdirstripe -c $dir)
23244                 (( $stripe_count == $default_count )) ||
23245                 (( $stripe_count == $MDSCOUNT && $default_count == -1 )) ||
23246                 (( $stripe_count == 0 )) || (( $default_count == 1 )) ||
23247                 error "stripe count $default_count != $stripe_count for $dir"
23248
23249                 stripe_index=$($LFS getdirstripe -i $dir)
23250                 [ $default_index -eq -1 ] ||
23251                         [ $stripe_index -eq $default_index ] ||
23252                         error "$stripe_index != $default_index for $dir"
23253
23254                 #check default stripe
23255                 stripe_count=$($LFS getdirstripe -D -c $dir)
23256                 [ $stripe_count -eq $default_count ] ||
23257                 error "default count $default_count != $stripe_count for $dir"
23258
23259                 stripe_index=$($LFS getdirstripe -D -i $dir)
23260                 [ $stripe_index -eq $default_index ] ||
23261                 error "default index $default_index != $stripe_index for $dir"
23262         done
23263         rmdir $DIR/$tdir/$dirname/* || error "rmdir failed"
23264 }
23265
23266 test_300g() {
23267         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23268         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23269                 skip "Need MDS version at least 2.7.55"
23270
23271         local dir
23272         local stripe_count
23273         local stripe_index
23274
23275         mkdir_on_mdt0 $DIR/$tdir
23276         mkdir $DIR/$tdir/normal_dir
23277
23278         #Checking when client cache stripe index
23279         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
23280         $LFS setdirstripe -D -i1 $DIR/$tdir/striped_dir ||
23281                 error "create striped_dir failed"
23282
23283         $LFS setdirstripe -i0 $DIR/$tdir/striped_dir/dir0 ||
23284                 error "create dir0 fails"
23285         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/dir0)
23286         [ $stripe_index -eq 0 ] ||
23287                 error "dir0 expect index 0 got $stripe_index"
23288
23289         mkdir $DIR/$tdir/striped_dir/dir1 ||
23290                 error "create dir1 fails"
23291         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/dir1)
23292         [ $stripe_index -eq 1 ] ||
23293                 error "dir1 expect index 1 got $stripe_index"
23294
23295         #check default stripe count/stripe index
23296         test_300_check_default_striped_dir normal_dir $MDSCOUNT 1
23297         test_300_check_default_striped_dir normal_dir 1 0
23298         test_300_check_default_striped_dir normal_dir -1 1
23299         test_300_check_default_striped_dir normal_dir 2 -1
23300
23301         #delete default stripe information
23302         echo "delete default stripeEA"
23303         $LFS setdirstripe -d $DIR/$tdir/normal_dir ||
23304                 error "set default stripe on striped dir error"
23305
23306         mkdir -p $DIR/$tdir/normal_dir/{test1,test2,test3,test4}
23307         for dir in $(find $DIR/$tdir/normal_dir/*); do
23308                 stripe_count=$($LFS getdirstripe -c $dir)
23309                 [ $stripe_count -eq 0 ] ||
23310                         error "expect 1 get $stripe_count for $dir"
23311         done
23312 }
23313 run_test 300g "check default striped directory for normal directory"
23314
23315 test_300h() {
23316         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23317         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23318                 skip "Need MDS version at least 2.7.55"
23319
23320         local dir
23321         local stripe_count
23322
23323         mkdir $DIR/$tdir
23324         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
23325                 error "set striped dir error"
23326
23327         test_300_check_default_striped_dir striped_dir $MDSCOUNT 1
23328         test_300_check_default_striped_dir striped_dir 1 0
23329         test_300_check_default_striped_dir striped_dir -1 1
23330         test_300_check_default_striped_dir striped_dir 2 -1
23331
23332         #delete default stripe information
23333         $LFS setdirstripe -d $DIR/$tdir/striped_dir ||
23334                 error "set default stripe on striped dir error"
23335
23336         mkdir -p $DIR/$tdir/striped_dir/{test1,test2,test3,test4}
23337         for dir in $(find $DIR/$tdir/striped_dir/*); do
23338                 stripe_count=$($LFS getdirstripe -c $dir)
23339                 [ $stripe_count -eq 0 ] ||
23340                         error "expect 1 get $stripe_count for $dir"
23341         done
23342 }
23343 run_test 300h "check default striped directory for striped directory"
23344
23345 test_300i() {
23346         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23347         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23348         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23349                 skip "Need MDS version at least 2.7.55"
23350
23351         local stripe_count
23352         local file
23353
23354         mkdir $DIR/$tdir
23355
23356         $LFS setdirstripe -i 0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
23357                 error "set striped dir error"
23358
23359         createmany -o $DIR/$tdir/striped_dir/f- 10 ||
23360                 error "create files under striped dir failed"
23361
23362         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/hashdir ||
23363                 error "set striped hashdir error"
23364
23365         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/hashdir/d0 ||
23366                 error "create dir0 under hash dir failed"
23367         $LFS setdirstripe -i0 -c$MDSCOUNT -H fnv_1a_64 $DIR/$tdir/hashdir/d1 ||
23368                 error "create dir1 under hash dir failed"
23369         $LFS setdirstripe -i0 -c$MDSCOUNT -H crush $DIR/$tdir/hashdir/d2 ||
23370                 error "create dir2 under hash dir failed"
23371
23372         # unfortunately, we need to umount to clear dir layout cache for now
23373         # once we fully implement dir layout, we can drop this
23374         umount_client $MOUNT || error "umount failed"
23375         mount_client $MOUNT || error "mount failed"
23376
23377         $LFS find -H fnv_1a_64,crush $DIR/$tdir/hashdir
23378         local dircnt=$($LFS find -H fnv_1a_64,crush $DIR/$tdir/hashdir | wc -l)
23379         [ $dircnt -eq 2 ] || error "lfs find striped dir got:$dircnt,except:1"
23380
23381         #set the stripe to be unknown hash type
23382         #define OBD_FAIL_UNKNOWN_LMV_STRIPE     0x1901
23383         $LCTL set_param fail_loc=0x1901
23384         for ((i = 0; i < 10; i++)); do
23385                 $CHECKSTAT -t file $DIR/$tdir/striped_dir/f-$i ||
23386                         error "stat f-$i failed"
23387                 rm $DIR/$tdir/striped_dir/f-$i || error "unlink f-$i failed"
23388         done
23389
23390         touch $DIR/$tdir/striped_dir/f0 &&
23391                 error "create under striped dir with unknown hash should fail"
23392
23393         $LCTL set_param fail_loc=0
23394
23395         umount_client $MOUNT || error "umount failed"
23396         mount_client $MOUNT || error "mount failed"
23397
23398         return 0
23399 }
23400 run_test 300i "client handle unknown hash type striped directory"
23401
23402 test_300j() {
23403         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23404         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23405         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23406                 skip "Need MDS version at least 2.7.55"
23407
23408         local stripe_count
23409         local file
23410
23411         mkdir $DIR/$tdir
23412
23413         #define OBD_FAIL_SPLIT_UPDATE_REC       0x1702
23414         $LCTL set_param fail_loc=0x1702
23415         $LFS setdirstripe -i 0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
23416                 error "set striped dir error"
23417
23418         createmany -o $DIR/$tdir/striped_dir/f- 10 ||
23419                 error "create files under striped dir failed"
23420
23421         $LCTL set_param fail_loc=0
23422
23423         rm -rf $DIR/$tdir || error "unlink striped dir fails"
23424
23425         return 0
23426 }
23427 run_test 300j "test large update record"
23428
23429 test_300k() {
23430         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23431         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23432         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23433                 skip "Need MDS version at least 2.7.55"
23434
23435         # this test needs a huge transaction
23436         local kb
23437         kb=$(do_facet $SINGLEMDS "$LCTL get_param -n \
23438              osd*.$FSNAME-MDT0000.kbytestotal")
23439         [ $kb -lt $((1024*1024)) ] && skip "MDT0 too small: $kb"
23440
23441         local stripe_count
23442         local file
23443
23444         mkdir $DIR/$tdir
23445
23446         #define OBD_FAIL_LARGE_STRIPE   0x1703
23447         $LCTL set_param fail_loc=0x1703
23448         $LFS setdirstripe -i 0 -c192 $DIR/$tdir/striped_dir ||
23449                 error "set striped dir error"
23450         $LCTL set_param fail_loc=0
23451
23452         $LFS getdirstripe $DIR/$tdir/striped_dir ||
23453                 error "getstripeddir fails"
23454         rm -rf $DIR/$tdir/striped_dir ||
23455                 error "unlink striped dir fails"
23456
23457         return 0
23458 }
23459 run_test 300k "test large striped directory"
23460
23461 test_300l() {
23462         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23463         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23464         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23465                 skip "Need MDS version at least 2.7.55"
23466
23467         local stripe_index
23468
23469         test_mkdir -p $DIR/$tdir/striped_dir
23470         chown $RUNAS_ID $DIR/$tdir/striped_dir ||
23471                         error "chown $RUNAS_ID failed"
23472         $LFS setdirstripe -i 1 -D $DIR/$tdir/striped_dir ||
23473                 error "set default striped dir failed"
23474
23475         #define OBD_FAIL_MDS_STALE_DIR_LAYOUT    0x158
23476         $LCTL set_param fail_loc=0x80000158
23477         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir || error "create dir fails"
23478
23479         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/test_dir)
23480         [ $stripe_index -eq 1 ] ||
23481                 error "expect 1 get $stripe_index for $dir"
23482 }
23483 run_test 300l "non-root user to create dir under striped dir with stale layout"
23484
23485 test_300m() {
23486         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23487         [ $MDSCOUNT -ge 2 ] && skip_env "Only for single MDT"
23488         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23489                 skip "Need MDS version at least 2.7.55"
23490
23491         mkdir -p $DIR/$tdir/striped_dir
23492         $LFS setdirstripe -D -c 1 $DIR/$tdir/striped_dir ||
23493                 error "set default stripes dir error"
23494
23495         mkdir $DIR/$tdir/striped_dir/a || error "mkdir a fails"
23496
23497         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir/a)
23498         [ $stripe_count -eq 0 ] ||
23499                         error "expect 0 get $stripe_count for a"
23500
23501         $LFS setdirstripe -D -c 2 $DIR/$tdir/striped_dir ||
23502                 error "set default stripes dir error"
23503
23504         mkdir $DIR/$tdir/striped_dir/b || error "mkdir b fails"
23505
23506         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir/b)
23507         [ $stripe_count -eq 0 ] ||
23508                         error "expect 0 get $stripe_count for b"
23509
23510         $LFS setdirstripe -D -c1 -i2 $DIR/$tdir/striped_dir ||
23511                 error "set default stripes dir error"
23512
23513         mkdir $DIR/$tdir/striped_dir/c &&
23514                 error "default stripe_index is invalid, mkdir c should fails"
23515
23516         rm -rf $DIR/$tdir || error "rmdir fails"
23517 }
23518 run_test 300m "setstriped directory on single MDT FS"
23519
23520 cleanup_300n() {
23521         local list=$(comma_list $(mdts_nodes))
23522
23523         trap 0
23524         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
23525 }
23526
23527 test_300n() {
23528         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23529         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23530         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23531                 skip "Need MDS version at least 2.7.55"
23532         remote_mds_nodsh && skip "remote MDS with nodsh"
23533
23534         local stripe_index
23535         local list=$(comma_list $(mdts_nodes))
23536
23537         trap cleanup_300n RETURN EXIT
23538         mkdir -p $DIR/$tdir
23539         chmod 777 $DIR/$tdir
23540         $RUNAS $LFS setdirstripe -i0 -c$MDSCOUNT \
23541                                 $DIR/$tdir/striped_dir > /dev/null 2>&1 &&
23542                 error "create striped dir succeeds with gid=0"
23543
23544         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=-1
23545         $RUNAS $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir ||
23546                 error "create striped dir fails with gid=-1"
23547
23548         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
23549         $RUNAS $LFS setdirstripe -i 1 -c$MDSCOUNT -D \
23550                                 $DIR/$tdir/striped_dir > /dev/null 2>&1 &&
23551                 error "set default striped dir succeeds with gid=0"
23552
23553
23554         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=-1
23555         $RUNAS $LFS setdirstripe -i 1 -c$MDSCOUNT -D $DIR/$tdir/striped_dir ||
23556                 error "set default striped dir fails with gid=-1"
23557
23558
23559         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
23560         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir ||
23561                                         error "create test_dir fails"
23562         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir1 ||
23563                                         error "create test_dir1 fails"
23564         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir2 ||
23565                                         error "create test_dir2 fails"
23566         cleanup_300n
23567 }
23568 run_test 300n "non-root user to create dir under striped dir with default EA"
23569
23570 test_300o() {
23571         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23572         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23573         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23574                 skip "Need MDS version at least 2.7.55"
23575
23576         local numfree1
23577         local numfree2
23578
23579         mkdir -p $DIR/$tdir
23580
23581         numfree1=$(lctl get_param -n mdc.*MDT0000*.filesfree)
23582         numfree2=$(lctl get_param -n mdc.*MDT0001*.filesfree)
23583         if [ $numfree1 -lt 66000 ] || [ $numfree2 -lt 66000 ]; then
23584                 skip "not enough free inodes $numfree1 $numfree2"
23585         fi
23586
23587         numfree1=$(lctl get_param -n mdc.*MDT0000-mdc-*.kbytesfree)
23588         numfree2=$(lctl get_param -n mdc.*MDT0001-mdc-*.kbytesfree)
23589         if [ $numfree1 -lt 300000 ] || [ $numfree2 -lt 300000 ]; then
23590                 skip "not enough free space $numfree1 $numfree2"
23591         fi
23592
23593         $LFS setdirstripe -c2 $DIR/$tdir/striped_dir ||
23594                 error "setdirstripe fails"
23595
23596         createmany -d $DIR/$tdir/striped_dir/d 131000 ||
23597                 error "create dirs fails"
23598
23599         $LCTL set_param ldlm.namespaces.*mdc-*.lru_size=0
23600         ls $DIR/$tdir/striped_dir > /dev/null ||
23601                 error "ls striped dir fails"
23602         unlinkmany -d $DIR/$tdir/striped_dir/d 131000 ||
23603                 error "unlink big striped dir fails"
23604 }
23605 run_test 300o "unlink big sub stripe(> 65000 subdirs)"
23606
23607 test_300p() {
23608         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23609         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23610         remote_mds_nodsh && skip "remote MDS with nodsh"
23611
23612         mkdir_on_mdt0 $DIR/$tdir
23613
23614         #define OBD_FAIL_OUT_ENOSPC     0x1704
23615         do_facet mds2 lctl set_param fail_loc=0x80001704
23616         $LFS setdirstripe -i 0 -c2 $DIR/$tdir/bad_striped_dir > /dev/null 2>&1 \
23617                  && error "create striped directory should fail"
23618
23619         [ -e $DIR/$tdir/bad_striped_dir ] && error "striped dir exists"
23620
23621         $LFS setdirstripe -c2 $DIR/$tdir/bad_striped_dir
23622         true
23623 }
23624 run_test 300p "create striped directory without space"
23625
23626 test_300q() {
23627         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23628         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23629
23630         local fd=$(free_fd)
23631         local cmd="exec $fd<$tdir"
23632         cd $DIR
23633         $LFS mkdir -c $MDSCOUNT $tdir || error "create $tdir fails"
23634         eval $cmd
23635         cmd="exec $fd<&-"
23636         trap "eval $cmd" EXIT
23637         cd $tdir || error "cd $tdir fails"
23638         rmdir  ../$tdir || error "rmdir $tdir fails"
23639         mkdir local_dir && error "create dir succeeds"
23640         $LFS setdirstripe -i1 remote_dir && error "create remote dir succeeds"
23641         eval $cmd
23642         return 0
23643 }
23644 run_test 300q "create remote directory under orphan directory"
23645
23646 test_300r() {
23647         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23648                 skip "Need MDS version at least 2.7.55" && return
23649         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
23650
23651         mkdir $DIR/$tdir
23652
23653         $LFS setdirstripe -i 0 -c -1 $DIR/$tdir/striped_dir ||
23654                 error "set striped dir error"
23655
23656         $LFS getdirstripe $DIR/$tdir/striped_dir ||
23657                 error "getstripeddir fails"
23658
23659         local stripe_count
23660         stripe_count=$($LFS getdirstripe $DIR/$tdir/striped_dir |
23661                       awk '/lmv_stripe_count:/ { print $2 }')
23662
23663         [ $MDSCOUNT -ne $stripe_count ] &&
23664                 error "wrong stripe count $stripe_count expected $MDSCOUNT"
23665
23666         rm -rf $DIR/$tdir/striped_dir ||
23667                 error "unlink striped dir fails"
23668 }
23669 run_test 300r "test -1 striped directory"
23670
23671 test_300s_helper() {
23672         local count=$1
23673
23674         local stripe_dir=$DIR/$tdir/striped_dir.$count
23675
23676         $LFS mkdir -c $count $stripe_dir ||
23677                 error "lfs mkdir -c error"
23678
23679         $LFS getdirstripe $stripe_dir ||
23680                 error "lfs getdirstripe fails"
23681
23682         local stripe_count
23683         stripe_count=$($LFS getdirstripe $stripe_dir |
23684                       awk '/lmv_stripe_count:/ { print $2 }')
23685
23686         [ $count -ne $stripe_count ] &&
23687                 error_noexit "bad stripe count $stripe_count expected $count"
23688
23689         local dupe_stripes
23690         dupe_stripes=$($LFS getdirstripe $stripe_dir |
23691                 awk '/0x/ {count[$1] += 1}; END {
23692                         for (idx in count) {
23693                                 if (count[idx]>1) {
23694                                         print "index " idx " count " count[idx]
23695                                 }
23696                         }
23697                 }')
23698
23699         if [[ -n "$dupe_stripes" ]] ; then
23700                 lfs getdirstripe $stripe_dir
23701                 error_noexit "Dupe MDT above: $dupe_stripes "
23702         fi
23703
23704         rm -rf $stripe_dir ||
23705                 error_noexit "unlink $stripe_dir fails"
23706 }
23707
23708 test_300s() {
23709         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23710                 skip "Need MDS version at least 2.7.55" && return
23711         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
23712
23713         mkdir $DIR/$tdir
23714         for count in $(seq 2 $MDSCOUNT); do
23715                 test_300s_helper $count
23716         done
23717 }
23718 run_test 300s "test lfs mkdir -c without -i"
23719
23720 prepare_remote_file() {
23721         mkdir $DIR/$tdir/src_dir ||
23722                 error "create remote source failed"
23723
23724         cp /etc/hosts $DIR/$tdir/src_dir/a ||
23725                  error "cp to remote source failed"
23726         touch $DIR/$tdir/src_dir/a
23727
23728         $LFS mkdir -i 1 $DIR/$tdir/tgt_dir ||
23729                 error "create remote target dir failed"
23730
23731         touch $DIR/$tdir/tgt_dir/b
23732
23733         mrename $DIR/$tdir/src_dir/a $DIR/$tdir/tgt_dir/b ||
23734                 error "rename dir cross MDT failed!"
23735
23736         $CHECKSTAT -t file $DIR/$tdir/src_dir/a &&
23737                 error "src_child still exists after rename"
23738
23739         $CHECKSTAT -t file $DIR/$tdir/tgt_dir/b ||
23740                 error "missing file(a) after rename"
23741
23742         diff /etc/hosts $DIR/$tdir/tgt_dir/b ||
23743                 error "diff after rename"
23744 }
23745
23746 test_310a() {
23747         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 4 MDTs"
23748         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23749
23750         local remote_file=$DIR/$tdir/tgt_dir/b
23751
23752         mkdir -p $DIR/$tdir
23753
23754         prepare_remote_file || error "prepare remote file failed"
23755
23756         #open-unlink file
23757         $OPENUNLINK $remote_file $remote_file ||
23758                 error "openunlink $remote_file failed"
23759         $CHECKSTAT -a $remote_file || error "$remote_file exists"
23760 }
23761 run_test 310a "open unlink remote file"
23762
23763 test_310b() {
23764         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 4 MDTs"
23765         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23766
23767         local remote_file=$DIR/$tdir/tgt_dir/b
23768
23769         mkdir -p $DIR/$tdir
23770
23771         prepare_remote_file || error "prepare remote file failed"
23772
23773         ln $remote_file $DIR/$tfile || error "link failed for remote file"
23774         $MULTIOP $DIR/$tfile Ouc || error "mulitop failed"
23775         $CHECKSTAT -t file $remote_file || error "check file failed"
23776 }
23777 run_test 310b "unlink remote file with multiple links while open"
23778
23779 test_310c() {
23780         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23781         [[ $MDSCOUNT -lt 4 ]] && skip_env "needs >= 4 MDTs"
23782
23783         local remote_file=$DIR/$tdir/tgt_dir/b
23784
23785         mkdir -p $DIR/$tdir
23786
23787         prepare_remote_file || error "prepare remote file failed"
23788
23789         ln $remote_file $DIR/$tfile || error "link failed for remote file"
23790         multiop_bg_pause $remote_file O_uc ||
23791                         error "mulitop failed for remote file"
23792         MULTIPID=$!
23793         $MULTIOP $DIR/$tfile Ouc
23794         kill -USR1 $MULTIPID
23795         wait $MULTIPID
23796 }
23797 run_test 310c "open-unlink remote file with multiple links"
23798
23799 #LU-4825
23800 test_311() {
23801         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23802         [ $OSTCOUNT -lt 2 ] && skip "needs >= 2 OSTs"
23803         [ $MDS1_VERSION -lt $(version_code 2.8.54) ] &&
23804                 skip "lustre < 2.8.54 does not contain LU-4825 fix"
23805         remote_mds_nodsh && skip "remote MDS with nodsh"
23806
23807         local old_iused=$($LFS df -i | awk '/OST0000/ { print $3; exit; }')
23808         local mdts=$(comma_list $(mdts_nodes))
23809
23810         mkdir -p $DIR/$tdir
23811         $LFS setstripe -i 0 -c 1 $DIR/$tdir
23812         createmany -o $DIR/$tdir/$tfile. 1000
23813
23814         # statfs data is not real time, let's just calculate it
23815         old_iused=$((old_iused + 1000))
23816
23817         local count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
23818                         osp.*OST0000*MDT0000.create_count")
23819         local max_count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
23820                                 osp.*OST0000*MDT0000.max_create_count")
23821         do_nodes $mdts "$LCTL set_param -n osp.*OST0000*.max_create_count=0"
23822
23823         $LFS setstripe -i 0 $DIR/$tdir/$tfile || error "setstripe failed"
23824         local index=$($LFS getstripe -i $DIR/$tdir/$tfile)
23825         [ $index -ne 0 ] || error "$tfile stripe index is 0"
23826
23827         unlinkmany $DIR/$tdir/$tfile. 1000
23828
23829         do_nodes $mdts "$LCTL set_param -n \
23830                         osp.*OST0000*.max_create_count=$max_count"
23831         [ $MDS1_VERSION -lt $(version_code 2.12.51) ] &&
23832                 do_nodes $mdts "$LCTL set_param -n \
23833                                 osp.*OST0000*.create_count=$count"
23834         do_nodes $mdts "$LCTL get_param osp.*OST0000*.create_count" |
23835                         grep "=0" && error "create_count is zero"
23836
23837         local new_iused
23838         for i in $(seq 120); do
23839                 new_iused=$($LFS df -i | awk '/OST0000/ { print $3; exit; }')
23840                 # system may be too busy to destroy all objs in time, use
23841                 # a somewhat small value to not fail autotest
23842                 [ $((old_iused - new_iused)) -gt 400 ] && break
23843                 sleep 1
23844         done
23845
23846         echo "waited $i sec, old Iused $old_iused, new Iused $new_iused"
23847         [ $((old_iused - new_iused)) -gt 400 ] ||
23848                 error "objs not destroyed after unlink"
23849 }
23850 run_test 311 "disable OSP precreate, and unlink should destroy objs"
23851
23852 zfs_oid_to_objid()
23853 {
23854         local ost=$1
23855         local objid=$2
23856
23857         local vdevdir=$(dirname $(facet_vdevice $ost))
23858         local cmd="$ZDB -e -p $vdevdir -ddddd $(facet_device $ost)"
23859         local zfs_zapid=$(do_facet $ost $cmd |
23860                           grep -w "/O/0/d$((objid%32))" -C 5 |
23861                           awk '/Object/{getline; print $1}')
23862         local zfs_objid=$(do_facet $ost $cmd $zfs_zapid |
23863                           awk "/$objid = /"'{printf $3}')
23864
23865         echo $zfs_objid
23866 }
23867
23868 zfs_object_blksz() {
23869         local ost=$1
23870         local objid=$2
23871
23872         local vdevdir=$(dirname $(facet_vdevice $ost))
23873         local cmd="$ZDB -e -p $vdevdir -dddd $(facet_device $ost)"
23874         local blksz=$(do_facet $ost $cmd $objid |
23875                       awk '/dblk/{getline; printf $4}')
23876
23877         case "${blksz: -1}" in
23878                 k|K) blksz=$((${blksz:0:$((${#blksz} - 1))}*1024)) ;;
23879                 m|M) blksz=$((${blksz:0:$((${#blksz} - 1))}*1024*1024)) ;;
23880                 *) ;;
23881         esac
23882
23883         echo $blksz
23884 }
23885
23886 test_312() { # LU-4856
23887         remote_ost_nodsh && skip "remote OST with nodsh"
23888         [ "$ost1_FSTYPE" = "zfs" ] ||
23889                 skip_env "the test only applies to zfs"
23890
23891         local max_blksz=$(do_facet ost1 \
23892                           $ZFS get -p recordsize $(facet_device ost1) |
23893                           awk '!/VALUE/{print $3}')
23894
23895         # to make life a little bit easier
23896         $LFS mkdir -c 1 -i 0 $DIR/$tdir
23897         $LFS setstripe -c 1 -i 0 $DIR/$tdir
23898
23899         local tf=$DIR/$tdir/$tfile
23900         touch $tf
23901         local oid=$($LFS getstripe $tf | awk '/obdidx/{getline; print $2}')
23902
23903         # Get ZFS object id
23904         local zfs_objid=$(zfs_oid_to_objid ost1 $oid)
23905         # block size change by sequential overwrite
23906         local bs
23907
23908         for ((bs=$PAGE_SIZE; bs <= max_blksz; bs *= 4)) ; do
23909                 dd if=/dev/zero of=$tf bs=$bs count=1 oflag=sync conv=notrunc
23910
23911                 local blksz=$(zfs_object_blksz ost1 $zfs_objid)
23912                 [ $blksz -eq $bs ] || error "blksz error: $blksz, expected: $bs"
23913         done
23914         rm -f $tf
23915
23916         # block size change by sequential append write
23917         dd if=/dev/zero of=$tf bs=$PAGE_SIZE count=1 oflag=sync conv=notrunc
23918         oid=$($LFS getstripe $tf | awk '/obdidx/{getline; print $2}')
23919         zfs_objid=$(zfs_oid_to_objid ost1 $oid)
23920         local count
23921
23922         for ((count = 1; count < $((max_blksz / PAGE_SIZE)); count *= 2)); do
23923                 dd if=/dev/zero of=$tf bs=$PAGE_SIZE count=$count seek=$count \
23924                         oflag=sync conv=notrunc
23925
23926                 blksz=$(zfs_object_blksz ost1 $zfs_objid)
23927                 [ $blksz -eq $((2 * count * PAGE_SIZE)) ] ||
23928                         error "blksz error, actual $blksz, " \
23929                                 "expected: 2 * $count * $PAGE_SIZE"
23930         done
23931         rm -f $tf
23932
23933         # random write
23934         touch $tf
23935         oid=$($LFS getstripe $tf | awk '/obdidx/{getline; print $2}')
23936         zfs_objid=$(zfs_oid_to_objid ost1 $oid)
23937
23938         dd if=/dev/zero of=$tf bs=1K count=1 oflag=sync conv=notrunc
23939         blksz=$(zfs_object_blksz ost1 $zfs_objid)
23940         [ $blksz -eq $PAGE_SIZE ] ||
23941                 error "blksz error: $blksz, expected: $PAGE_SIZE"
23942
23943         dd if=/dev/zero of=$tf bs=64K count=1 oflag=sync conv=notrunc seek=128
23944         blksz=$(zfs_object_blksz ost1 $zfs_objid)
23945         [ $blksz -eq 65536 ] || error "blksz error: $blksz, expected: 64k"
23946
23947         dd if=/dev/zero of=$tf bs=1M count=1 oflag=sync conv=notrunc
23948         blksz=$(zfs_object_blksz ost1 $zfs_objid)
23949         [ $blksz -eq 65536 ] || error "rewrite error: $blksz, expected: 64k"
23950 }
23951 run_test 312 "make sure ZFS adjusts its block size by write pattern"
23952
23953 test_313() {
23954         remote_ost_nodsh && skip "remote OST with nodsh"
23955
23956         local file=$DIR/$tfile
23957
23958         rm -f $file
23959         $LFS setstripe -c 1 -i 0 $file || error "setstripe failed"
23960
23961         # define OBD_FAIL_TGT_RCVD_EIO           0x720
23962         do_facet ost1 "$LCTL set_param fail_loc=0x720"
23963         dd if=/dev/zero of=$file bs=$PAGE_SIZE oflag=direct count=1 &&
23964                 error "write should failed"
23965         do_facet ost1 "$LCTL set_param fail_loc=0"
23966         rm -f $file
23967 }
23968 run_test 313 "io should fail after last_rcvd update fail"
23969
23970 test_314() {
23971         [ $OSTCOUNT -lt 2 ] && skip "needs >= 2 OSTs"
23972
23973         $LFS setstripe -c 2 -i 0 $DIR/$tfile || error "setstripe failed"
23974         do_facet ost1 "$LCTL set_param fail_loc=0x720"
23975         rm -f $DIR/$tfile
23976         wait_delete_completed
23977         do_facet ost1 "$LCTL set_param fail_loc=0"
23978 }
23979 run_test 314 "OSP shouldn't fail after last_rcvd update failure"
23980
23981 test_315() { # LU-618
23982         [ -f /proc/$$/io ] || skip_env "no IO accounting in kernel"
23983
23984         local file=$DIR/$tfile
23985         rm -f $file
23986
23987         $MULTIOP $file oO_CREAT:O_DIRECT:O_RDWR:w4063232c ||
23988                 error "multiop file write failed"
23989         $MULTIOP $file oO_RDONLY:r4063232_c &
23990         PID=$!
23991
23992         sleep 2
23993
23994         local rbytes=$(awk '/read_bytes/ { print $2 }' /proc/$PID/io)
23995         kill -USR1 $PID
23996
23997         [ $rbytes -gt 4000000 ] || error "read is not accounted ($rbytes)"
23998         rm -f $file
23999 }
24000 run_test 315 "read should be accounted"
24001
24002 test_316() {
24003         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
24004         large_xattr_enabled || skip_env "ea_inode feature disabled"
24005
24006         rm -rf $DIR/$tdir/d
24007         mkdir -p $DIR/$tdir/d
24008         chown nobody $DIR/$tdir/d
24009         touch $DIR/$tdir/d/file
24010
24011         $LFS mv -m1 $DIR/$tdir/d || error "lfs mv failed"
24012 }
24013 run_test 316 "lfs mv"
24014
24015 test_317() {
24016         [ $MDS1_VERSION -lt $(version_code 2.11.53) ] &&
24017                 skip "Need MDS version at least 2.11.53"
24018         if [ "$ost1_FSTYPE" == "zfs" ]; then
24019                 skip "LU-10370: no implementation for ZFS"
24020         fi
24021
24022         local trunc_sz
24023         local grant_blk_size
24024
24025         grant_blk_size=$($LCTL get_param osc.$FSNAME*.import |
24026                         awk '/grant_block_size:/ { print $2; exit; }')
24027         #
24028         # Create File of size 5M. Truncate it to below size's and verify
24029         # blocks count.
24030         #
24031         dd if=/dev/zero of=$DIR/$tfile bs=5M count=1 conv=fsync ||
24032                 error "Create file $DIR/$tfile failed"
24033         stack_trap "rm -f $DIR/$tfile" EXIT
24034
24035         for trunc_sz in 2097152 4097 4000 509 0; do
24036                 $TRUNCATE $DIR/$tfile $trunc_sz ||
24037                         error "truncate $tfile to $trunc_sz failed"
24038                 local sz=$(stat --format=%s $DIR/$tfile)
24039                 local blk=$(stat --format=%b $DIR/$tfile)
24040                 local trunc_blk=$((((trunc_sz + (grant_blk_size - 1) ) /
24041                                      grant_blk_size) * 8))
24042
24043                 if [[ $blk -ne $trunc_blk ]]; then
24044                         $(which stat) $DIR/$tfile
24045                         error "Expected Block $trunc_blk got $blk for $tfile"
24046                 fi
24047
24048                 $CHECKSTAT -s $trunc_sz $DIR/$tfile ||
24049                         error "Expected Size $trunc_sz got $sz for $tfile"
24050         done
24051
24052         #
24053         # sparse file test
24054         # Create file with a hole and write actual 65536 bytes which aligned
24055         # with 4K and 64K PAGE_SIZE. Block count must be 128.
24056         #
24057         local bs=65536
24058         dd if=/dev/zero of=$DIR/$tfile bs=$bs count=1 seek=5 conv=fsync ||
24059                 error "Create file : $DIR/$tfile"
24060
24061         #
24062         # Truncate to size $trunc_sz bytes. Strip tail blocks and leave only 8
24063         # blocks. The block count must drop to 8.
24064         #
24065         trunc_sz=$(($(stat --format=%s $DIR/$tfile) - \
24066                 ((bs - grant_blk_size) + 1)))
24067         $TRUNCATE $DIR/$tfile $trunc_sz ||
24068                 error "truncate $tfile to $trunc_sz failed"
24069
24070         local trunc_bsz=$((grant_blk_size / $(stat --format=%B $DIR/$tfile)))
24071         sz=$(stat --format=%s $DIR/$tfile)
24072         blk=$(stat --format=%b $DIR/$tfile)
24073
24074         if [[ $blk -ne $trunc_bsz ]]; then
24075                 $(which stat) $DIR/$tfile
24076                 error "Expected Block $trunc_bsz got $blk for $tfile"
24077         fi
24078
24079         $CHECKSTAT -s $trunc_sz $DIR/$tfile ||
24080                 error "Expected Size $trunc_sz got $sz for $tfile"
24081 }
24082 run_test 317 "Verify blocks get correctly update after truncate"
24083
24084 test_318() {
24085         local llite_name="llite.$($LFS getname $MOUNT | awk '{print $1}')"
24086         local old_max_active=$($LCTL get_param -n \
24087                             ${llite_name}.max_read_ahead_async_active \
24088                             2>/dev/null)
24089
24090         $LCTL set_param llite.*.max_read_ahead_async_active=256
24091         local max_active=$($LCTL get_param -n \
24092                            ${llite_name}.max_read_ahead_async_active \
24093                            2>/dev/null)
24094         [ $max_active -ne 256 ] && error "expected 256 but got $max_active"
24095
24096         $LCTL set_param llite.*.max_read_ahead_async_active=0 ||
24097                 error "set max_read_ahead_async_active should succeed"
24098
24099         $LCTL set_param llite.*.max_read_ahead_async_active=512
24100         max_active=$($LCTL get_param -n \
24101                      ${llite_name}.max_read_ahead_async_active 2>/dev/null)
24102         [ $max_active -eq 512 ] || error "expected 512 but got $max_active"
24103
24104         # restore @max_active
24105         [ $old_max_active -ne 0 ] && $LCTL set_param \
24106                 llite.*.max_read_ahead_async_active=$old_max_active
24107
24108         local old_threshold=$($LCTL get_param -n \
24109                 ${llite_name}.read_ahead_async_file_threshold_mb 2>/dev/null)
24110         local max_per_file_mb=$($LCTL get_param -n \
24111                 ${llite_name}.max_read_ahead_per_file_mb 2>/dev/null)
24112
24113         local invalid=$(($max_per_file_mb + 1))
24114         $LCTL set_param \
24115                 llite.*.read_ahead_async_file_threshold_mb=$invalid\
24116                         && error "set $invalid should fail"
24117
24118         local valid=$(($invalid - 1))
24119         $LCTL set_param \
24120                 llite.*.read_ahead_async_file_threshold_mb=$valid ||
24121                         error "set $valid should succeed"
24122         local threshold=$($LCTL get_param -n \
24123                 ${llite_name}.read_ahead_async_file_threshold_mb 2>/dev/null)
24124         [ $threshold -eq $valid ] || error \
24125                 "expect threshold $valid got $threshold"
24126         $LCTL set_param \
24127                 llite.*.read_ahead_async_file_threshold_mb=$old_threshold
24128 }
24129 run_test 318 "Verify async readahead tunables"
24130
24131 test_319() {
24132         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return 0
24133
24134         local before=$(date +%s)
24135         local evict
24136         local mdir=$DIR/$tdir
24137         local file=$mdir/xxx
24138
24139         $LFS mkdir -i0 $mdir || error "mkdir $mdir fails"
24140         touch $file
24141
24142 #define OBD_FAIL_LDLM_LOCAL_CANCEL_PAUSE 0x32c
24143         $LCTL set_param fail_val=5 fail_loc=0x8000032c
24144         $LFS mv -m1 $file &
24145
24146         sleep 1
24147         dd if=$file of=/dev/null
24148         wait
24149         evict=$($LCTL get_param mdc.$FSNAME-MDT*.state |
24150           awk -F"[ [,]" '/EVICTED ]$/ { if (mx<$5) {mx=$5;} } END { print mx }')
24151
24152         [ -z "$evict" ] || [[ $evict -le $before ]] || error "eviction happened"
24153 }
24154 run_test 319 "lost lease lock on migrate error"
24155
24156 test_398a() { # LU-4198
24157         local ost1_imp=$(get_osc_import_name client ost1)
24158         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
24159                          cut -d'.' -f2)
24160
24161         $LFS setstripe -c 1 -i 0 $DIR/$tfile
24162         $LCTL set_param ldlm.namespaces.*.lru_size=clear
24163
24164         # request a new lock on client
24165         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
24166
24167         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=direct conv=notrunc
24168         local lock_count=$($LCTL get_param -n \
24169                            ldlm.namespaces.$imp_name.lru_size)
24170         [[ $lock_count -eq 0 ]] || error "lock should be cancelled by direct IO"
24171
24172         $LCTL set_param ldlm.namespaces.*-OST0000-osc-ffff*.lru_size=clear
24173
24174         # no lock cached, should use lockless IO and not enqueue new lock
24175         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=direct conv=notrunc
24176         lock_count=$($LCTL get_param -n \
24177                      ldlm.namespaces.$imp_name.lru_size)
24178         [[ $lock_count -eq 0 ]] || error "no lock should be held by direct IO"
24179 }
24180 run_test 398a "direct IO should cancel lock otherwise lockless"
24181
24182 test_398b() { # LU-4198
24183         which fio || skip_env "no fio installed"
24184         $LFS setstripe -c -1 $DIR/$tfile
24185
24186         local size=12
24187         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$size
24188
24189         local njobs=4
24190         echo "mix direct rw ${size}M to OST0 by fio with $njobs jobs..."
24191         fio --name=rand-rw --rw=randrw --bs=$PAGE_SIZE --direct=1 \
24192                 --numjobs=$njobs --fallocate=none \
24193                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
24194                 --filename=$DIR/$tfile &
24195         bg_pid=$!
24196
24197         echo "mix buffer rw ${size}M to OST0 by fio with $njobs jobs..."
24198         fio --name=rand-rw --rw=randrw --bs=$PAGE_SIZE \
24199                 --numjobs=$njobs --fallocate=none \
24200                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
24201                 --filename=$DIR/$tfile || true
24202         wait $bg_pid
24203
24204         rm -f $DIR/$tfile
24205 }
24206 run_test 398b "DIO and buffer IO race"
24207
24208 test_398c() { # LU-4198
24209         local ost1_imp=$(get_osc_import_name client ost1)
24210         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
24211                          cut -d'.' -f2)
24212
24213         which fio || skip_env "no fio installed"
24214
24215         saved_debug=$($LCTL get_param -n debug)
24216         $LCTL set_param debug=0
24217
24218         local size=$(lctl get_param -n osc.$FSNAME-OST0000*.kbytesavail | head -1)
24219         ((size /= 1024)) # by megabytes
24220         ((size /= 2)) # write half of the OST at most
24221         [ $size -gt 40 ] && size=40 #reduce test time anyway
24222
24223         $LFS setstripe -c 1 $DIR/$tfile
24224
24225         # it seems like ldiskfs reserves more space than necessary if the
24226         # writing blocks are not mapped, so it extends the file firstly
24227         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$size && sync
24228         cancel_lru_locks osc
24229
24230         # clear and verify rpc_stats later
24231         $LCTL set_param osc.${FSNAME}-OST0000-osc-ffff*.rpc_stats=clear
24232
24233         local njobs=4
24234         echo "writing ${size}M to OST0 by fio with $njobs jobs..."
24235         fio --name=rand-write --rw=randwrite --bs=$PAGE_SIZE --direct=1 \
24236                 --numjobs=$njobs --fallocate=none --ioengine=libaio \
24237                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
24238                 --filename=$DIR/$tfile
24239         [ $? -eq 0 ] || error "fio write error"
24240
24241         [ $($LCTL get_param -n ldlm.namespaces.$imp_name.lock_count) -eq 0 ] ||
24242                 error "Locks were requested while doing AIO"
24243
24244         # get the percentage of 1-page I/O
24245         pct=$($LCTL get_param osc.${imp_name}.rpc_stats |
24246                 grep -A 1 'pages per rpc' | grep -v 'pages per rpc' |
24247                 awk '{print $7}')
24248         [ $pct -le 50 ] || error "$pct% of I/O are 1-page"
24249
24250         echo "mix rw ${size}M to OST0 by fio with $njobs jobs..."
24251         fio --name=rand-rw --rw=randrw --bs=$PAGE_SIZE --direct=1 \
24252                 --numjobs=$njobs --fallocate=none --ioengine=libaio \
24253                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
24254                 --filename=$DIR/$tfile
24255         [ $? -eq 0 ] || error "fio mixed read write error"
24256
24257         echo "AIO with large block size ${size}M"
24258         fio --name=rand-rw --rw=randrw --bs=${size}M --direct=1 \
24259                 --numjobs=1 --fallocate=none --ioengine=libaio \
24260                 --iodepth=16 --allow_file_create=0 --size=${size}M \
24261                 --filename=$DIR/$tfile
24262         [ $? -eq 0 ] || error "fio large block size failed"
24263
24264         rm -f $DIR/$tfile
24265         $LCTL set_param debug="$saved_debug"
24266 }
24267 run_test 398c "run fio to test AIO"
24268
24269 test_398d() { #  LU-13846
24270         which aiocp || skip_env "no aiocp installed"
24271         local aio_file=$DIR/$tfile.aio
24272
24273         $LFS setstripe -c -1 -S 1M $DIR/$tfile $aio_file
24274
24275         dd if=/dev/urandom of=$DIR/$tfile bs=1M count=64
24276         aiocp -a $PAGE_SIZE -b 64M -s 64M -f O_DIRECT $DIR/$tfile $aio_file
24277         stack_trap "rm -f $DIR/$tfile $aio_file"
24278
24279         diff $DIR/$tfile $aio_file || error "file diff after aiocp"
24280
24281         # make sure we don't crash and fail properly
24282         aiocp -a 512 -b 64M -s 64M -f O_DIRECT $DIR/$tfile $aio_file &&
24283                 error "aio not aligned with PAGE SIZE should fail"
24284
24285         rm -f $DIR/$tfile $aio_file
24286 }
24287 run_test 398d "run aiocp to verify block size > stripe size"
24288
24289 test_398e() {
24290         dd if=/dev/zero of=$DIR/$tfile bs=1234 count=1
24291         touch $DIR/$tfile.new
24292         dd if=$DIR/$tfile of=$DIR/$tfile.new bs=1M count=1 oflag=direct
24293 }
24294 run_test 398e "O_Direct open cleared by fcntl doesn't cause hang"
24295
24296 test_398f() { #  LU-14687
24297         which aiocp || skip_env "no aiocp installed"
24298         local aio_file=$DIR/$tfile.aio
24299
24300         $LFS setstripe -c -1 -S 1M $DIR/$tfile $aio_file
24301
24302         dd if=/dev/zero of=$DIR/$tfile bs=1M count=64
24303         stack_trap "rm -f $DIR/$tfile $aio_file"
24304
24305         #define OBD_FAIL_LLITE_PAGE_ALLOC 0x1418
24306         $LCTL set_param fail_loc=0x1418
24307         # make sure we don't crash and fail properly
24308         aiocp -b 64M -s 64M -f O_DIRECT $DIR/$tfile $aio_file &&
24309                 error "aio with page allocation failure succeeded"
24310         $LCTL set_param fail_loc=0
24311         diff $DIR/$tfile $aio_file
24312         [[ $? != 0 ]] || error "no diff after failed aiocp"
24313 }
24314 run_test 398f "verify aio handles ll_direct_rw_pages errors correctly"
24315
24316 # NB: To get the parallel DIO behavior in LU-13798, there must be > 1
24317 # stripe and i/o size must be > stripe size
24318 # Old style synchronous DIO waits after submitting each chunk, resulting in a
24319 # single RPC in flight.  This test shows async DIO submission is working by
24320 # showing multiple RPCs in flight.
24321 test_398g() { #  LU-13798
24322         $LFS setstripe -o 0,0 -S 1M $DIR/$tfile
24323
24324         # We need to do some i/o first to acquire enough grant to put our RPCs
24325         # in flight; otherwise a new connection may not have enough grant
24326         # available
24327         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=1 oflag=direct ||
24328                 error "parallel dio failed"
24329         stack_trap "rm -f $DIR/$tfile"
24330
24331         # Reduce RPC size to 1M to avoid combination in to larger RPCs
24332         local pages_per_rpc=$($LCTL get_param osc.*-OST0000-*.max_pages_per_rpc)
24333         $LCTL set_param osc.*-OST0000-*.max_pages_per_rpc=1M
24334         stack_trap "$LCTL set_param -n $pages_per_rpc"
24335
24336         # Recreate file so it's empty
24337         rm -f $DIR/$tfile
24338         $LFS setstripe -o 0,0 -S 1M $DIR/$tfile
24339         #Pause rpc completion to guarantee we see multiple rpcs in flight
24340         #define OBD_FAIL_OST_BRW_PAUSE_BULK
24341         do_facet ost1 $LCTL set_param fail_loc=0x214 fail_val=2
24342         stack_trap "do_facet ost1 $LCTL set_param fail_loc=0"
24343
24344         # Clear rpc stats
24345         $LCTL set_param osc.*.rpc_stats=c
24346
24347         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=1 oflag=direct ||
24348                 error "parallel dio failed"
24349         stack_trap "rm -f $DIR/$tfile"
24350
24351         $LCTL get_param osc.*-OST0000-*.rpc_stats
24352         pct=$($LCTL get_param osc.*-OST0000-*.rpc_stats |
24353                 grep -A 8 'rpcs in flight' | grep -v 'rpcs in flight' |
24354                 grep "8:" | awk '{print $8}')
24355         # We look at the "8 rpcs in flight" field, and verify A) it is present
24356         # and B) it includes all RPCs.  This proves we had 8 RPCs in flight,
24357         # as expected for an 8M DIO to a file with 1M stripes.
24358         [ $pct -eq 100 ] || error "we should see 8 RPCs in flight"
24359
24360         # Verify turning off parallel dio works as expected
24361         # Clear rpc stats
24362         $LCTL set_param osc.*.rpc_stats=c
24363         $LCTL set_param llite.*.parallel_dio=0
24364         stack_trap '$LCTL set_param llite.*.parallel_dio=1'
24365
24366         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=1 oflag=direct ||
24367                 error "dio with parallel dio disabled failed"
24368
24369         # Ideally, we would see only one RPC in flight here, but there is an
24370         # unavoidable race between i/o completion and RPC in flight counting,
24371         # so while only 1 i/o is in flight at a time, the RPC in flight counter
24372         # will sometimes exceed 1 (3 or 4 is not rare on VM testing).
24373         # So instead we just verify it's always < 8.
24374         $LCTL get_param osc.*-OST0000-*.rpc_stats
24375         ret=$($LCTL get_param osc.*-OST0000-*.rpc_stats |
24376                 grep -A 8 'rpcs in flight' | grep -v 'rpcs in flight' |
24377                 grep '^$' -B1 | grep . | awk '{print $1}')
24378         [ $ret != "8:" ] ||
24379                 error "we should see fewer than 8 RPCs in flight (saw $ret)"
24380 }
24381 run_test 398g "verify parallel dio async RPC submission"
24382
24383 test_398h() { #  LU-13798
24384         local dio_file=$DIR/$tfile.dio
24385
24386         $LFS setstripe -C 2 -S 1M $DIR/$tfile $dio_file
24387
24388         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct
24389         stack_trap "rm -f $DIR/$tfile $dio_file"
24390
24391         dd if=$DIR/$tfile of=$dio_file bs=8M count=8 iflag=direct oflag=direct ||
24392                 error "parallel dio failed"
24393         diff $DIR/$tfile $dio_file
24394         [[ $? == 0 ]] || error "file diff after aiocp"
24395 }
24396 run_test 398h "verify correctness of read & write with i/o size >> stripe size"
24397
24398 test_398i() { #  LU-13798
24399         local dio_file=$DIR/$tfile.dio
24400
24401         $LFS setstripe -C 2 -S 1M $DIR/$tfile $dio_file
24402
24403         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct
24404         stack_trap "rm -f $DIR/$tfile $dio_file"
24405
24406         #define OBD_FAIL_LLITE_PAGE_ALLOC 0x1418
24407         $LCTL set_param fail_loc=0x1418
24408         # make sure we don't crash and fail properly
24409         dd if=$DIR/$tfile of=$dio_file bs=8M count=8 iflag=direct oflag=direct &&
24410                 error "parallel dio page allocation failure succeeded"
24411         diff $DIR/$tfile $dio_file
24412         [[ $? != 0 ]] || error "no diff after failed aiocp"
24413 }
24414 run_test 398i "verify parallel dio handles ll_direct_rw_pages errors correctly"
24415
24416 test_398j() { #  LU-13798
24417         # Stripe size > RPC size but less than i/o size tests split across
24418         # stripes and RPCs for individual i/o op
24419         $LFS setstripe -o 0,0 -S 4M $DIR/$tfile $DIR/$tfile.2
24420
24421         # Reduce RPC size to 1M to guarantee split to multiple RPCs per stripe
24422         local pages_per_rpc=$($LCTL get_param osc.*-OST0000-*.max_pages_per_rpc)
24423         $LCTL set_param osc.*-OST0000-*.max_pages_per_rpc=1M
24424         stack_trap "$LCTL set_param -n $pages_per_rpc"
24425
24426         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct ||
24427                 error "parallel dio write failed"
24428         stack_trap "rm -f $DIR/$tfile $DIR/$tfile.2"
24429
24430         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 iflag=direct ||
24431                 error "parallel dio read failed"
24432         diff $DIR/$tfile $DIR/$tfile.2
24433         [[ $? == 0 ]] || error "file diff after parallel dio read"
24434 }
24435 run_test 398j "test parallel dio where stripe size > rpc_size"
24436
24437 test_398k() { #  LU-13798
24438         wait_delete_completed
24439         wait_mds_ost_sync
24440
24441         # 4 stripe file; we will cause out of space on OST0
24442         $LFS setstripe -o 0,1,0,1 -S 1M $DIR/$tfile
24443
24444         # Fill OST0 (if it's not too large)
24445         ORIGFREE=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
24446                    head -n1)
24447         if [[ $ORIGFREE -gt $MAXFREE ]]; then
24448                 skip "$ORIGFREE > $MAXFREE skipping out-of-space test on OST0"
24449         fi
24450         $LFS setstripe -i 0 -c 1 $DIR/$tfile.1
24451         dd if=/dev/zero of=$DIR/$tfile.1 bs=1024 count=$MAXFREE &&
24452                 error "dd should fill OST0"
24453         stack_trap "rm -f $DIR/$tfile.1"
24454
24455         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct
24456         err=$?
24457
24458         ls -la $DIR/$tfile
24459         $CHECKSTAT -t file -s 0 $DIR/$tfile ||
24460                 error "file is not 0 bytes in size"
24461
24462         # dd above should not succeed, but don't error until here so we can
24463         # get debug info above
24464         [[ $err != 0 ]] ||
24465                 error "parallel dio write with enospc succeeded"
24466         stack_trap "rm -f $DIR/$tfile"
24467 }
24468 run_test 398k "test enospc on first stripe"
24469
24470 test_398l() { #  LU-13798
24471         wait_delete_completed
24472         wait_mds_ost_sync
24473
24474         # 4 stripe file; we will cause out of space on OST0
24475         # Note the 1M stripe size and the > 1M i/o size mean this ENOSPC
24476         # happens on the second i/o chunk we issue
24477         $LFS setstripe -o 1,0,1,0 -S 1M $DIR/$tfile $DIR/$tfile.2
24478
24479         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=2 oflag=direct
24480         stack_trap "rm -f $DIR/$tfile"
24481
24482         # Fill OST0 (if it's not too large)
24483         ORIGFREE=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
24484                    head -n1)
24485         if [[ $ORIGFREE -gt $MAXFREE ]]; then
24486                 skip "$ORIGFREE > $MAXFREE skipping out-of-space test on OST0"
24487         fi
24488         $LFS setstripe -i 0 -c 1 $DIR/$tfile.1
24489         dd if=/dev/zero of=$DIR/$tfile.1 bs=1024 count=$MAXFREE &&
24490                 error "dd should fill OST0"
24491         stack_trap "rm -f $DIR/$tfile.1"
24492
24493         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 oflag=direct
24494         err=$?
24495         stack_trap "rm -f $DIR/$tfile.2"
24496
24497         # Check that short write completed as expected
24498         ls -la $DIR/$tfile.2
24499         $CHECKSTAT -t file -s 1048576 $DIR/$tfile.2 ||
24500                 error "file is not 1M in size"
24501
24502         # dd above should not succeed, but don't error until here so we can
24503         # get debug info above
24504         [[ $err != 0 ]] ||
24505                 error "parallel dio write with enospc succeeded"
24506
24507         # Truncate source file to same length as output file and diff them
24508         $TRUNCATE $DIR/$tfile 1048576
24509         diff $DIR/$tfile $DIR/$tfile.2
24510         [[ $? == 0 ]] || error "data incorrect after short write"
24511 }
24512 run_test 398l "test enospc on intermediate stripe/RPC"
24513
24514 test_398m() { #  LU-13798
24515         $LFS setstripe -o 0,1,0,1 -S 1M $DIR/$tfile
24516
24517         # Set up failure on OST0, the first stripe:
24518         #define OBD_FAIL_OST_BRW_WRITE_BULK     0x20e
24519         #NB: Fail val is ost # + 1, because we cannot use cfs_fail_val = 0
24520         # So this fail_val specifies OST0
24521         do_facet ost1 $LCTL set_param fail_loc=0x20e fail_val=1
24522         stack_trap "do_facet ost1 $LCTL set_param fail_loc=0"
24523
24524         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct &&
24525                 error "parallel dio write with failure on first stripe succeeded"
24526         stack_trap "rm -f $DIR/$tfile"
24527         do_facet ost1 $LCTL set_param fail_loc=0 fail_val=0
24528
24529         # Place data in file for read
24530         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct ||
24531                 error "parallel dio write failed"
24532
24533         # Fail read on OST0, first stripe
24534         #define OBD_FAIL_OST_BRW_READ_BULK       0x20f
24535         do_facet ost1 $LCTL set_param fail_loc=0x20f fail_val=1
24536         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 iflag=direct &&
24537                 error "parallel dio read with error on first stripe succeeded"
24538         rm -f $DIR/$tfile.2
24539         do_facet ost1 $LCTL set_param fail_loc=0 fail_val=0
24540
24541         # Switch to testing on OST1, second stripe
24542         # Clear file contents, maintain striping
24543         echo > $DIR/$tfile
24544         # Set up failure on OST1, second stripe:
24545         do_facet ost1 $LCTL set_param fail_loc=0x20e fail_val=2
24546         stack_trap "do_facet ost1 $LCTL set_param fail_loc=0"
24547
24548         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct &&
24549                 error "parallel dio write with failure on first stripe succeeded"
24550         stack_trap "rm -f $DIR/$tfile"
24551         do_facet ost1 $LCTL set_param fail_loc=0 fail_val=0
24552
24553         # Place data in file for read
24554         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct ||
24555                 error "parallel dio write failed"
24556
24557         # Fail read on OST1, second stripe
24558         #define OBD_FAIL_OST_BRW_READ_BULK       0x20f
24559         do_facet ost2 $LCTL set_param fail_loc=0x20f fail_val=2
24560         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 iflag=direct &&
24561                 error "parallel dio read with error on first stripe succeeded"
24562         rm -f $DIR/$tfile.2
24563         do_facet ost2 $LCTL set_param fail_loc=0 fail_val=0
24564 }
24565 run_test 398m "test RPC failures with parallel dio"
24566
24567 # Parallel submission of DIO should not cause problems for append, but it's
24568 # important to verify.
24569 test_398n() { #  LU-13798
24570         $LFS setstripe -C 2 -S 1M $DIR/$tfile
24571
24572         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 ||
24573                 error "dd to create source file failed"
24574         stack_trap "rm -f $DIR/$tfile"
24575
24576         dd if=$DIR/$tfile of=$DIR/$tfile.1 bs=8M count=8 oflag=direct oflag=append ||
24577                 error "parallel dio write with failure on second stripe succeeded"
24578         stack_trap "rm -f $DIR/$tfile $DIR/$tfile.1"
24579         diff $DIR/$tfile $DIR/$tfile.1
24580         [[ $? == 0 ]] || error "data incorrect after append"
24581
24582 }
24583 run_test 398n "test append with parallel DIO"
24584
24585 test_fake_rw() {
24586         local read_write=$1
24587         if [ "$read_write" = "write" ]; then
24588                 local dd_cmd="dd if=/dev/zero of=$DIR/$tfile"
24589         elif [ "$read_write" = "read" ]; then
24590                 local dd_cmd="dd of=/dev/null if=$DIR/$tfile"
24591         else
24592                 error "argument error"
24593         fi
24594
24595         # turn off debug for performance testing
24596         local saved_debug=$($LCTL get_param -n debug)
24597         $LCTL set_param debug=0
24598
24599         $LFS setstripe -c 1 -i 0 $DIR/$tfile
24600
24601         # get ost1 size - $FSNAME-OST0000
24602         local ost1_avail_size=$($LFS df $DIR | awk /${ost1_svc}/'{ print $4 }')
24603         local blocks=$((ost1_avail_size/2/1024)) # half avail space by megabytes
24604         [ $blocks -gt 1000 ] && blocks=1000 # 1G in maximum
24605
24606         if [ "$read_write" = "read" ]; then
24607                 $TRUNCATE $DIR/$tfile $(expr 1048576 \* $blocks)
24608         fi
24609
24610         local start_time=$(date +%s.%N)
24611         $dd_cmd bs=1M count=$blocks oflag=sync ||
24612                 error "real dd $read_write error"
24613         local duration=$(bc <<< "$(date +%s.%N) - $start_time")
24614
24615         if [ "$read_write" = "write" ]; then
24616                 rm -f $DIR/$tfile
24617         fi
24618
24619         # define OBD_FAIL_OST_FAKE_RW           0x238
24620         do_facet ost1 $LCTL set_param fail_loc=0x238
24621
24622         local start_time=$(date +%s.%N)
24623         $dd_cmd bs=1M count=$blocks oflag=sync ||
24624                 error "fake dd $read_write error"
24625         local duration_fake=$(bc <<< "$(date +%s.%N) - $start_time")
24626
24627         if [ "$read_write" = "write" ]; then
24628                 # verify file size
24629                 cancel_lru_locks osc
24630                 $CHECKSTAT -t file -s $((blocks * 1024 * 1024)) $DIR/$tfile ||
24631                         error "$tfile size not $blocks MB"
24632         fi
24633         do_facet ost1 $LCTL set_param fail_loc=0
24634
24635         echo "fake $read_write $duration_fake vs. normal $read_write" \
24636                 "$duration in seconds"
24637         [ $(bc <<< "$duration_fake < $duration") -eq 1 ] ||
24638                 error_not_in_vm "fake write is slower"
24639
24640         $LCTL set_param -n debug="$saved_debug"
24641         rm -f $DIR/$tfile
24642 }
24643 test_399a() { # LU-7655 for OST fake write
24644         remote_ost_nodsh && skip "remote OST with nodsh"
24645
24646         test_fake_rw write
24647 }
24648 run_test 399a "fake write should not be slower than normal write"
24649
24650 test_399b() { # LU-8726 for OST fake read
24651         remote_ost_nodsh && skip "remote OST with nodsh"
24652         if [ "$ost1_FSTYPE" != "ldiskfs" ]; then
24653                 skip_env "ldiskfs only test"
24654         fi
24655
24656         test_fake_rw read
24657 }
24658 run_test 399b "fake read should not be slower than normal read"
24659
24660 test_400a() { # LU-1606, was conf-sanity test_74
24661         if ! which $CC > /dev/null 2>&1; then
24662                 skip_env "$CC is not installed"
24663         fi
24664
24665         local extra_flags=''
24666         local out=$TMP/$tfile
24667         local prefix=/usr/include/lustre
24668         local prog
24669
24670         # Oleg removes c files in his test rig so test if any c files exist
24671         [ -z "$(ls -A $LUSTRE_TESTS_API_DIR)" ] && \
24672                 skip_env "Needed c test files are missing"
24673
24674         if ! [[ -d $prefix ]]; then
24675                 # Assume we're running in tree and fixup the include path.
24676                 extra_flags+=" -I$LUSTRE/../lnet/include/uapi -I$LUSTRE/include/uapi -I$LUSTRE/include"
24677                 extra_flags+=" -L$LUSTRE/utils/.lib"
24678         fi
24679
24680         for prog in $LUSTRE_TESTS_API_DIR/*.c; do
24681                 $CC -Wall -Werror -std=c99 $extra_flags -o $out $prog -llustreapi ||
24682                         error "client api broken"
24683         done
24684         rm -f $out
24685 }
24686 run_test 400a "Lustre client api program can compile and link"
24687
24688 test_400b() { # LU-1606, LU-5011
24689         local header
24690         local out=$TMP/$tfile
24691         local prefix=/usr/include/linux/lustre
24692
24693         # We use a hard coded prefix so that this test will not fail
24694         # when run in tree. There are headers in lustre/include/lustre/
24695         # that are not packaged (like lustre_idl.h) and have more
24696         # complicated include dependencies (like config.h and lnet/types.h).
24697         # Since this test about correct packaging we just skip them when
24698         # they don't exist (see below) rather than try to fixup cppflags.
24699
24700         if ! which $CC > /dev/null 2>&1; then
24701                 skip_env "$CC is not installed"
24702         fi
24703
24704         for header in $prefix/*.h; do
24705                 if ! [[ -f "$header" ]]; then
24706                         continue
24707                 fi
24708
24709                 if [[ "$(basename $header)" == lustre_ioctl.h ]]; then
24710                         continue # lustre_ioctl.h is internal header
24711                 fi
24712
24713                 $CC -Wall -Werror -std=c99 -include $header -c -x c /dev/null -o $out ||
24714                         error "cannot compile '$header'"
24715         done
24716         rm -f $out
24717 }
24718 run_test 400b "packaged headers can be compiled"
24719
24720 test_401a() { #LU-7437
24721         local printf_arg=$(find -printf 2>&1 | grep "unrecognized:")
24722         [ -n "$printf_arg" ] && skip_env "find does not support -printf"
24723
24724         #count the number of parameters by "list_param -R"
24725         local params=$($LCTL list_param -R '*' 2>/dev/null | wc -l)
24726         #count the number of parameters by listing proc files
24727         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
24728         echo "proc_dirs='$proc_dirs'"
24729         [ -n "$proc_dirs" ] || error "no proc_dirs on $HOSTNAME"
24730         local procs=$(find -L $proc_dirs -mindepth 1 -printf '%P\n' 2>/dev/null|
24731                       sort -u | wc -l)
24732
24733         [ $params -eq $procs ] ||
24734                 error "found $params parameters vs. $procs proc files"
24735
24736         # test the list_param -D option only returns directories
24737         params=$($LCTL list_param -R -D '*' 2>/dev/null | wc -l)
24738         #count the number of parameters by listing proc directories
24739         procs=$(find -L $proc_dirs -mindepth 1 -type d -printf '%P\n' 2>/dev/null |
24740                 sort -u | wc -l)
24741
24742         [ $params -eq $procs ] ||
24743                 error "found $params parameters vs. $procs proc files"
24744 }
24745 run_test 401a "Verify if 'lctl list_param -R' can list parameters recursively"
24746
24747 test_401b() {
24748         # jobid_var may not allow arbitrary values, so use jobid_name
24749         # if available
24750         if $LCTL list_param jobid_name > /dev/null 2>&1; then
24751                 local testname=jobid_name tmp='testing%p'
24752         else
24753                 local testname=jobid_var tmp=testing
24754         fi
24755
24756         local save=$($LCTL get_param -n $testname)
24757
24758         $LCTL set_param foo=bar $testname=$tmp bar=baz &&
24759                 error "no error returned when setting bad parameters"
24760
24761         local jobid_new=$($LCTL get_param -n foe $testname baz)
24762         [[ "$jobid_new" == "$tmp" ]] || error "jobid tmp $jobid_new != $tmp"
24763
24764         $LCTL set_param -n fog=bam $testname=$save bat=fog
24765         local jobid_old=$($LCTL get_param -n foe $testname bag)
24766         [[ "$jobid_old" == "$save" ]] || error "jobid new $jobid_old != $save"
24767 }
24768 run_test 401b "Verify 'lctl {get,set}_param' continue after error"
24769
24770 test_401c() {
24771         # jobid_var may not allow arbitrary values, so use jobid_name
24772         # if available
24773         if $LCTL list_param jobid_name > /dev/null 2>&1; then
24774                 local testname=jobid_name
24775         else
24776                 local testname=jobid_var
24777         fi
24778
24779         local jobid_var_old=$($LCTL get_param -n $testname)
24780         local jobid_var_new
24781
24782         $LCTL set_param $testname= &&
24783                 error "no error returned for 'set_param a='"
24784
24785         jobid_var_new=$($LCTL get_param -n $testname)
24786         [[ "$jobid_var_old" == "$jobid_var_new" ]] ||
24787                 error "$testname was changed by setting without value"
24788
24789         $LCTL set_param $testname &&
24790                 error "no error returned for 'set_param a'"
24791
24792         jobid_var_new=$($LCTL get_param -n $testname)
24793         [[ "$jobid_var_old" == "$jobid_var_new" ]] ||
24794                 error "$testname was changed by setting without value"
24795 }
24796 run_test 401c "Verify 'lctl set_param' without value fails in either format."
24797
24798 test_401d() {
24799         # jobid_var may not allow arbitrary values, so use jobid_name
24800         # if available
24801         if $LCTL list_param jobid_name > /dev/null 2>&1; then
24802                 local testname=jobid_name new_value='foo=bar%p'
24803         else
24804                 local testname=jobid_var new_valuie=foo=bar
24805         fi
24806
24807         local jobid_var_old=$($LCTL get_param -n $testname)
24808         local jobid_var_new
24809
24810         $LCTL set_param $testname=$new_value ||
24811                 error "'set_param a=b' did not accept a value containing '='"
24812
24813         jobid_var_new=$($LCTL get_param -n $testname)
24814         [[ "$jobid_var_new" == "$new_value" ]] ||
24815                 error "'set_param a=b' failed on a value containing '='"
24816
24817         # Reset the $testname to test the other format
24818         $LCTL set_param $testname=$jobid_var_old
24819         jobid_var_new=$($LCTL get_param -n $testname)
24820         [[ "$jobid_var_new" == "$jobid_var_old" ]] ||
24821                 error "failed to reset $testname"
24822
24823         $LCTL set_param $testname $new_value ||
24824                 error "'set_param a b' did not accept a value containing '='"
24825
24826         jobid_var_new=$($LCTL get_param -n $testname)
24827         [[ "$jobid_var_new" == "$new_value" ]] ||
24828                 error "'set_param a b' failed on a value containing '='"
24829
24830         $LCTL set_param $testname $jobid_var_old
24831         jobid_var_new=$($LCTL get_param -n $testname)
24832         [[ "$jobid_var_new" == "$jobid_var_old" ]] ||
24833                 error "failed to reset $testname"
24834 }
24835 run_test 401d "Verify 'lctl set_param' accepts values containing '='"
24836
24837 test_401e() { # LU-14779
24838         $LCTL list_param -R "ldlm.namespaces.MGC*" ||
24839                 error "lctl list_param MGC* failed"
24840         $LCTL get_param "ldlm.namespaces.MGC*" || error "lctl get_param failed"
24841         $LCTL get_param "ldlm.namespaces.MGC*.lru_size" ||
24842                 error "lctl get_param lru_size failed"
24843 }
24844 run_test 401e "verify 'lctl get_param' works with NID in parameter"
24845
24846 test_402() {
24847         [[ $MDS1_VERSION -ge $(version_code 2.7.66) ]] ||
24848         [[ $MDS1_VERSION -ge $(version_code 2.7.18.4) &&
24849                 $MDS1_VERSION -lt $(version_code 2.7.50) ]] ||
24850         [[ $MDS1_VERSION -ge $(version_code 2.7.2) &&
24851                 $MDS1_VERSION -lt $(version_code 2.7.11) ]] ||
24852                 skip "Need MDS version 2.7.2+ or 2.7.18.4+ or 2.7.66+"
24853         remote_mds_nodsh && skip "remote MDS with nodsh"
24854
24855         $LFS setdirstripe -i 0 $DIR/$tdir || error "setdirstripe -i 0 failed"
24856 #define OBD_FAIL_MDS_FLD_LOOKUP 0x15c
24857         do_facet mds1 "lctl set_param fail_loc=0x8000015c"
24858         touch $DIR/$tdir/$tfile && error "touch should fail with ENOENT" ||
24859                 echo "Touch failed - OK"
24860 }
24861 run_test 402 "Return ENOENT to lod_generate_and_set_lovea"
24862
24863 test_403() {
24864         local file1=$DIR/$tfile.1
24865         local file2=$DIR/$tfile.2
24866         local tfile=$TMP/$tfile
24867
24868         rm -f $file1 $file2 $tfile
24869
24870         touch $file1
24871         ln $file1 $file2
24872
24873         # 30 sec OBD_TIMEOUT in ll_getattr()
24874         # right before populating st_nlink
24875         $LCTL set_param fail_loc=0x80001409
24876         stat -c %h $file1 > $tfile &
24877
24878         # create an alias, drop all locks and reclaim the dentry
24879         < $file2
24880         cancel_lru_locks mdc
24881         cancel_lru_locks osc
24882         sysctl -w vm.drop_caches=2
24883
24884         wait
24885
24886         [ $(cat $tfile) -gt 0 ] || error "wrong nlink count: $(cat $tfile)"
24887
24888         rm -f $tfile $file1 $file2
24889 }
24890 run_test 403 "i_nlink should not drop to zero due to aliasing"
24891
24892 test_404() { # LU-6601
24893         [[ $MDS1_VERSION -ge $(version_code 2.8.53) ]] ||
24894                 skip "Need server version newer than 2.8.52"
24895         remote_mds_nodsh && skip "remote MDS with nodsh"
24896
24897         local mosps=$(do_facet $SINGLEMDS $LCTL dl |
24898                 awk '/osp .*-osc-MDT/ { print $4}')
24899
24900         local osp
24901         for osp in $mosps; do
24902                 echo "Deactivate: " $osp
24903                 do_facet $SINGLEMDS $LCTL --device %$osp deactivate
24904                 local stat=$(do_facet $SINGLEMDS $LCTL dl |
24905                         awk -vp=$osp '$4 == p { print $2 }')
24906                 [ $stat = IN ] || {
24907                         do_facet $SINGLEMDS $LCTL dl | grep -w $osp
24908                         error "deactivate error"
24909                 }
24910                 echo "Activate: " $osp
24911                 do_facet $SINGLEMDS $LCTL --device %$osp activate
24912                 local stat=$(do_facet $SINGLEMDS $LCTL dl |
24913                         awk -vp=$osp '$4 == p { print $2 }')
24914                 [ $stat = UP ] || {
24915                         do_facet $SINGLEMDS $LCTL dl | grep -w $osp
24916                         error "activate error"
24917                 }
24918         done
24919 }
24920 run_test 404 "validate manual {de}activated works properly for OSPs"
24921
24922 test_405() {
24923         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
24924         [ $MDS1_VERSION -lt $(version_code 2.6.92) ] ||
24925                 [ $CLIENT_VERSION -lt $(version_code 2.6.99) ] &&
24926                         skip "Layout swap lock is not supported"
24927
24928         check_swap_layouts_support
24929         check_swap_layout_no_dom $DIR
24930
24931         test_mkdir $DIR/$tdir
24932         swap_lock_test -d $DIR/$tdir ||
24933                 error "One layout swap locked test failed"
24934 }
24935 run_test 405 "Various layout swap lock tests"
24936
24937 test_406() {
24938         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
24939         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
24940         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
24941         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24942         [ $MDS1_VERSION -lt $(version_code 2.8.50) ] &&
24943                 skip "Need MDS version at least 2.8.50"
24944
24945         local def_stripe_size=$($LFS getstripe -S $MOUNT)
24946         local test_pool=$TESTNAME
24947
24948         pool_add $test_pool || error "pool_add failed"
24949         pool_add_targets $test_pool 0 $(($OSTCOUNT - 1)) 1 ||
24950                 error "pool_add_targets failed"
24951
24952         save_layout_restore_at_exit $MOUNT
24953
24954         # parent set default stripe count only, child will stripe from both
24955         # parent and fs default
24956         $LFS setstripe -c 1 -i 1 -S $((def_stripe_size * 2)) -p $test_pool $MOUNT ||
24957                 error "setstripe $MOUNT failed"
24958         $LFS mkdir -c $MDSCOUNT $DIR/$tdir || error "mkdir $tdir failed"
24959         $LFS setstripe -c $OSTCOUNT $DIR/$tdir || error "setstripe $tdir failed"
24960         for i in $(seq 10); do
24961                 local f=$DIR/$tdir/$tfile.$i
24962                 touch $f || error "touch failed"
24963                 local count=$($LFS getstripe -c $f)
24964                 [ $count -eq $OSTCOUNT ] ||
24965                         error "$f stripe count $count != $OSTCOUNT"
24966                 local offset=$($LFS getstripe -i $f)
24967                 [ $offset -eq 1 ] || error "$f stripe offset $offset != 1"
24968                 local size=$($LFS getstripe -S $f)
24969                 [ $size -eq $((def_stripe_size * 2)) ] ||
24970                         error "$f stripe size $size != $((def_stripe_size * 2))"
24971                 local pool=$($LFS getstripe -p $f)
24972                 [ $pool == $test_pool ] || error "$f pool $pool != $test_pool"
24973         done
24974
24975         # change fs default striping, delete parent default striping, now child
24976         # will stripe from new fs default striping only
24977         $LFS setstripe -c 1 -S $def_stripe_size -i 0 $MOUNT ||
24978                 error "change $MOUNT default stripe failed"
24979         $LFS setstripe -c 0 $DIR/$tdir ||
24980                 error "delete $tdir default stripe failed"
24981         for i in $(seq 11 20); do
24982                 local f=$DIR/$tdir/$tfile.$i
24983                 touch $f || error "touch $f failed"
24984                 local count=$($LFS getstripe -c $f)
24985                 [ $count -eq 1 ] || error "$f stripe count $count != 1"
24986                 local offset=$($LFS getstripe -i $f)
24987                 [ $offset -eq 0 ] || error "$f stripe offset $offset != 0"
24988                 local size=$($LFS getstripe -S $f)
24989                 [ $size -eq $def_stripe_size ] ||
24990                         error "$f stripe size $size != $def_stripe_size"
24991                 local pool=$($LFS getstripe -p $f)
24992                 [ $pool == $test_pool ] || error "$f pool $pool isn't set"
24993         done
24994
24995         unlinkmany $DIR/$tdir/$tfile. 1 20
24996
24997         local f=$DIR/$tdir/$tfile
24998         pool_remove_all_targets $test_pool $f
24999         pool_remove $test_pool $f
25000 }
25001 run_test 406 "DNE support fs default striping"
25002
25003 test_407() {
25004         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25005         [[ $MDS1_VERSION -lt $(version_code 2.8.55) ]] &&
25006                 skip "Need MDS version at least 2.8.55"
25007         remote_mds_nodsh && skip "remote MDS with nodsh"
25008
25009         $LFS mkdir -i 0 -c 1 $DIR/$tdir.0 ||
25010                 error "$LFS mkdir -i 0 -c 1 $tdir.0 failed"
25011         $LFS mkdir -i 1 -c 1 $DIR/$tdir.1 ||
25012                 error "$LFS mkdir -i 1 -c 1 $tdir.1 failed"
25013         touch $DIR/$tdir.0/$tfile.0 || error "touch $tdir.0/$tfile.0 failed"
25014
25015         #define OBD_FAIL_DT_TXN_STOP    0x2019
25016         for idx in $(seq $MDSCOUNT); do
25017                 do_facet mds$idx "lctl set_param fail_loc=0x2019"
25018         done
25019         $LFS mkdir -c 2 $DIR/$tdir && error "$LFS mkdir -c 2 $tdir should fail"
25020         mv $DIR/$tdir.0/$tfile.0 $DIR/$tdir.1/$tfile.1 &&
25021                 error "mv $tdir.0/$tfile.0 $tdir.1/$tfile.1 should fail"
25022         true
25023 }
25024 run_test 407 "transaction fail should cause operation fail"
25025
25026 test_408() {
25027         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1 oflag=direct
25028
25029         #define OBD_FAIL_OSC_BRW_PREP_REQ2        0x40a
25030         lctl set_param fail_loc=0x8000040a
25031         # let ll_prepare_partial_page() fail
25032         dd if=/dev/zero of=$DIR/$tfile bs=2048 count=1 conv=notrunc || true
25033
25034         rm -f $DIR/$tfile
25035
25036         # create at least 100 unused inodes so that
25037         # shrink_icache_memory(0) should not return 0
25038         touch $DIR/$tfile-{0..100}
25039         rm -f $DIR/$tfile-{0..100}
25040         sync
25041
25042         echo 2 > /proc/sys/vm/drop_caches
25043 }
25044 run_test 408 "drop_caches should not hang due to page leaks"
25045
25046 test_409()
25047 {
25048         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
25049
25050         mkdir -p $DIR/$tdir || error "(0) Fail to mkdir"
25051         $LFS mkdir -i 1 -c 2 $DIR/$tdir/foo || error "(1) Fail to mkdir"
25052         touch $DIR/$tdir/guard || error "(2) Fail to create"
25053
25054         local PREFIX=$(str_repeat 'A' 128)
25055         echo "Create 1K hard links start at $(date)"
25056         createmany -l $DIR/$tdir/guard $DIR/$tdir/foo/${PREFIX}_ 1000 ||
25057                 error "(3) Fail to hard link"
25058
25059         echo "Links count should be right although linkEA overflow"
25060         stat $DIR/$tdir/guard || error "(4) Fail to stat"
25061         local linkcount=$(stat --format=%h $DIR/$tdir/guard)
25062         [ $linkcount -eq 1001 ] ||
25063                 error "(5) Unexpected hard links count: $linkcount"
25064
25065         echo "List all links start at $(date)"
25066         ls -l $DIR/$tdir/foo > /dev/null ||
25067                 error "(6) Fail to list $DIR/$tdir/foo"
25068
25069         echo "Unlink hard links start at $(date)"
25070         unlinkmany $DIR/$tdir/foo/${PREFIX}_ 1000 ||
25071                 error "(7) Fail to unlink"
25072         echo "Unlink hard links finished at $(date)"
25073 }
25074 run_test 409 "Large amount of cross-MDTs hard links on the same file"
25075
25076 test_410()
25077 {
25078         [[ $CLIENT_VERSION -lt $(version_code 2.9.59) ]] &&
25079                 skip "Need client version at least 2.9.59"
25080         [ -f $LUSTRE/tests/kernel/kinode.ko ] ||
25081                 skip "Need MODULES build"
25082
25083         # Create a file, and stat it from the kernel
25084         local testfile=$DIR/$tfile
25085         touch $testfile
25086
25087         local run_id=$RANDOM
25088         local my_ino=$(stat --format "%i" $testfile)
25089
25090         # Try to insert the module. This will always fail as the
25091         # module is designed to not be inserted.
25092         insmod $LUSTRE/tests/kernel/kinode.ko run_id=$run_id fname=$testfile \
25093             &> /dev/null
25094
25095         # Anything but success is a test failure
25096         dmesg | grep -q \
25097             "lustre_kinode_$run_id: inode numbers are identical: $my_ino" ||
25098             error "no inode match"
25099 }
25100 run_test 410 "Test inode number returned from kernel thread"
25101
25102 cleanup_test411_cgroup() {
25103         trap 0
25104         rmdir "$1"
25105 }
25106
25107 test_411() {
25108         local cg_basedir=/sys/fs/cgroup/memory
25109         # LU-9966
25110         test -f "$cg_basedir/memory.kmem.limit_in_bytes" ||
25111                 skip "no setup for cgroup"
25112
25113         dd if=/dev/zero of=$DIR/$tfile bs=1M count=100 conv=fsync ||
25114                 error "test file creation failed"
25115         cancel_lru_locks osc
25116
25117         # Create a very small memory cgroup to force a slab allocation error
25118         local cgdir=$cg_basedir/osc_slab_alloc
25119         mkdir $cgdir || error "cgroup mkdir '$cgdir' failed"
25120         trap "cleanup_test411_cgroup $cgdir" EXIT
25121         echo 2M > $cgdir/memory.kmem.limit_in_bytes
25122         echo 1M > $cgdir/memory.limit_in_bytes
25123
25124         # Should not LBUG, just be killed by oom-killer
25125         # dd will return 0 even allocation failure in some environment.
25126         # So don't check return value
25127         bash -c "echo \$$ > $cgdir/tasks && dd if=$DIR/$tfile of=/dev/null"
25128         cleanup_test411_cgroup $cgdir
25129
25130         return 0
25131 }
25132 run_test 411 "Slab allocation error with cgroup does not LBUG"
25133
25134 test_412() {
25135         (( $MDSCOUNT > 1 )) || skip_env "needs >= 2 MDTs"
25136         (( $MDS1_VERSION >= $(version_code 2.10.55) )) ||
25137                 skip "Need server version at least 2.10.55"
25138
25139         $LFS mkdir -i $((MDSCOUNT - 1)),$((MDSCOUNT - 2)) $DIR/$tdir ||
25140                 error "mkdir failed"
25141         $LFS getdirstripe $DIR/$tdir
25142         local stripe_index=$($LFS getdirstripe -i $DIR/$tdir)
25143         [ $stripe_index -eq $((MDSCOUNT - 1)) ] ||
25144                 error "expect $((MDSCOUT - 1)) get $stripe_index"
25145         local stripe_count=$($LFS getdirstripe -T $DIR/$tdir)
25146         [ $stripe_count -eq 2 ] ||
25147                 error "expect 2 get $stripe_count"
25148
25149         (( $MDS1_VERSION >= $(version_code 2.14.55) )) || return 0
25150
25151         local index
25152         local index2
25153
25154         # subdirs should be on the same MDT as parent
25155         for i in $(seq 0 $((MDSCOUNT - 1))); do
25156                 $LFS mkdir -i $i $DIR/$tdir/mdt$i || error "mkdir mdt$i failed"
25157                 mkdir $DIR/$tdir/mdt$i/sub || error "mkdir sub failed"
25158                 index=$($LFS getstripe -m $DIR/$tdir/mdt$i/sub)
25159                 (( index == i )) || error "mdt$i/sub on MDT$index"
25160         done
25161
25162         # stripe offset -1, ditto
25163         for i in {1..10}; do
25164                 $LFS mkdir -i -1 $DIR/$tdir/qos$i || error "mkdir qos$i failed"
25165                 index=$($LFS getstripe -m $DIR/$tdir/qos$i)
25166                 mkdir $DIR/$tdir/qos$i/sub || error "mkdir sub failed"
25167                 index2=$($LFS getstripe -m $DIR/$tdir/qos$i/sub)
25168                 (( index == index2 )) ||
25169                         error "qos$i on MDT$index, sub on MDT$index2"
25170         done
25171
25172         local testdir=$DIR/$tdir/inherit
25173
25174         $LFS mkdir -i 1 --max-inherit=3 $testdir || error "mkdir inherit failed"
25175         # inherit 2 levels
25176         for i in 1 2; do
25177                 testdir=$testdir/s$i
25178                 mkdir $testdir || error "mkdir $testdir failed"
25179                 index=$($LFS getstripe -m $testdir)
25180                 (( index == 1 )) ||
25181                         error "$testdir on MDT$index"
25182         done
25183
25184         # not inherit any more
25185         testdir=$testdir/s3
25186         mkdir $testdir || error "mkdir $testdir failed"
25187         getfattr -d -m dmv $testdir | grep dmv &&
25188                 error "default LMV set on $testdir" || true
25189 }
25190 run_test 412 "mkdir on specific MDTs"
25191
25192 generate_uneven_mdts() {
25193         local threshold=$1
25194         local lmv_qos_maxage
25195         local lod_qos_maxage
25196         local ffree
25197         local bavail
25198         local max
25199         local min
25200         local max_index
25201         local min_index
25202         local tmp
25203         local i
25204
25205         lmv_qos_maxage=$($LCTL get_param -n lmv.*.qos_maxage)
25206         $LCTL set_param lmv.*.qos_maxage=1
25207         stack_trap "$LCTL set_param \
25208                 lmv.*.qos_maxage=$lmv_qos_maxage > /dev/null" RETURN
25209         lod_qos_maxage=$(do_facet mds1 $LCTL get_param -n \
25210                 lod.$FSNAME-MDT0000-mdtlov.qos_maxage | awk '{ print $1 }')
25211         do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param \
25212                 lod.*.mdt_qos_maxage=1
25213         stack_trap "do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param \
25214                 lod.*.mdt_qos_maxage=$lod_qos_maxage > /dev/null" RETURN
25215
25216         echo
25217         echo "Check for uneven MDTs: "
25218
25219         ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.filesfree))
25220         bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.kbytesavail))
25221         bsize=$(lctl get_param -n mdc.*MDT0000*.blocksize)
25222
25223         max=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
25224         min=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
25225         max_index=0
25226         min_index=0
25227         for ((i = 1; i < ${#ffree[@]}; i++)); do
25228                 tmp=$(((${ffree[i]} >> 8) * (${bavail[i]} * bsize >> 16)))
25229                 if [ $tmp -gt $max ]; then
25230                         max=$tmp
25231                         max_index=$i
25232                 fi
25233                 if [ $tmp -lt $min ]; then
25234                         min=$tmp
25235                         min_index=$i
25236                 fi
25237         done
25238
25239         (( ${ffree[min_index]} > 0 )) ||
25240                 skip "no free files in MDT$min_index"
25241         (( ${ffree[min_index]} < 10000000 )) ||
25242                 skip "too many free files in MDT$min_index"
25243
25244         # Check if we need to generate uneven MDTs
25245         local diff=$(((max - min) * 100 / min))
25246         local testdir=$DIR/$tdir-fillmdt
25247         local start
25248
25249         mkdir -p $testdir
25250
25251         i=0
25252         while (( diff < threshold )); do
25253                 # generate uneven MDTs, create till $threshold% diff
25254                 echo -n "weight diff=$diff% must be > $threshold% ..."
25255                 echo "Fill MDT$min_index with 1000 files: loop $i"
25256                 testdir=$DIR/$tdir-fillmdt/$i
25257                 [ -d $testdir ] || $LFS mkdir -i $min_index $testdir ||
25258                         error "mkdir $testdir failed"
25259                 $LFS setstripe -E 1M -L mdt $testdir ||
25260                         error "setstripe $testdir failed"
25261                 start=$SECONDS
25262                 for F in f.{0..999}; do
25263                         dd if=/dev/zero of=$testdir/$F bs=64K count=1 > \
25264                                 /dev/null 2>&1 || error "dd $F failed"
25265                 done
25266
25267                 # wait for QOS to update
25268                 (( SECONDS < start + 1 )) && sleep $((start + 1 - SECONDS))
25269
25270                 ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-*.filesfree))
25271                 bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-*.kbytesavail))
25272                 max=$(((${ffree[max_index]} >> 8) * \
25273                         (${bavail[max_index]} * bsize >> 16)))
25274                 min=$(((${ffree[min_index]} >> 8) * \
25275                         (${bavail[min_index]} * bsize >> 16)))
25276                 diff=$(((max - min) * 100 / min))
25277                 i=$((i + 1))
25278         done
25279
25280         echo "MDT filesfree available: ${ffree[@]}"
25281         echo "MDT blocks available: ${bavail[@]}"
25282         echo "weight diff=$diff%"
25283 }
25284
25285 test_qos_mkdir() {
25286         local mkdir_cmd=$1
25287         local stripe_count=$2
25288         local mdts=$(comma_list $(mdts_nodes))
25289
25290         local testdir
25291         local lmv_qos_prio_free
25292         local lmv_qos_threshold_rr
25293         local lmv_qos_maxage
25294         local lod_qos_prio_free
25295         local lod_qos_threshold_rr
25296         local lod_qos_maxage
25297         local count
25298         local i
25299
25300         lmv_qos_prio_free=$($LCTL get_param -n lmv.*.qos_prio_free | head -n1)
25301         lmv_qos_prio_free=${lmv_qos_prio_free%%%}
25302         lmv_qos_threshold_rr=$($LCTL get_param -n lmv.*.qos_threshold_rr |
25303                 head -n1)
25304         lmv_qos_threshold_rr=${lmv_qos_threshold_rr%%%}
25305         lmv_qos_maxage=$($LCTL get_param -n lmv.*.qos_maxage)
25306         stack_trap "$LCTL set_param \
25307                 lmv.*.qos_prio_free=$lmv_qos_prio_free > /dev/null"
25308         stack_trap "$LCTL set_param \
25309                 lmv.*.qos_threshold_rr=$lmv_qos_threshold_rr > /dev/null"
25310         stack_trap "$LCTL set_param \
25311                 lmv.*.qos_maxage=$lmv_qos_maxage > /dev/null"
25312
25313         lod_qos_prio_free=$(do_facet mds1 $LCTL get_param -n \
25314                 lod.$FSNAME-MDT0000-mdtlov.mdt_qos_prio_free | head -n1)
25315         lod_qos_prio_free=${lod_qos_prio_free%%%}
25316         lod_qos_threshold_rr=$(do_facet mds1 $LCTL get_param -n \
25317                 lod.$FSNAME-MDT0000-mdtlov.mdt_qos_threshold_rr | head -n1)
25318         lod_qos_threshold_rr=${lod_qos_threshold_rr%%%}
25319         lod_qos_maxage=$(do_facet mds1 $LCTL get_param -n \
25320                 lod.$FSNAME-MDT0000-mdtlov.qos_maxage | awk '{ print $1 }')
25321         stack_trap "do_nodes $mdts $LCTL set_param \
25322                 lod.*.mdt_qos_prio_free=$lod_qos_prio_free > /dev/null"
25323         stack_trap "do_nodes $mdts $LCTL set_param \
25324                 lod.*.mdt_qos_threshold_rr=$lod_qos_threshold_rr > /dev/null"
25325         stack_trap "do_nodes $mdts $LCTL set_param \
25326                 lod.*.mdt_qos_maxage=$lod_qos_maxage > /dev/null"
25327
25328         $LCTL set_param lmv.*.qos_threshold_rr=100 > /dev/null
25329         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_threshold_rr=100 > /dev/null
25330
25331         testdir=$DIR/$tdir-s$stripe_count/rr
25332
25333         local stripe_index=$($LFS getstripe -m $testdir)
25334         local test_mkdir_rr=true
25335
25336         getfattr -d -m dmv -e hex $testdir | grep dmv
25337         if (( $? == 0 && $MDS1_VERSION >= $(version_code 2.14.51) )); then
25338                 echo "defstripe: '$($LFS getdirstripe -D $testdir)'"
25339                 (( $($LFS getdirstripe -D --max-inherit-rr $testdir) == 0 )) &&
25340                         test_mkdir_rr=false
25341         fi
25342
25343         echo
25344         $test_mkdir_rr &&
25345                 echo "Mkdir (stripe_count $stripe_count) roundrobin:" ||
25346                 echo "Mkdir (stripe_count $stripe_count) on stripe $stripe_index"
25347
25348         stack_trap "unlinkmany -d $testdir/subdir $((100 * MDSCOUNT))"
25349         for (( i = 0; i < 100 * MDSCOUNT; i++ )); do
25350                 eval $mkdir_cmd $testdir/subdir$i ||
25351                         error "$mkdir_cmd subdir$i failed"
25352         done
25353
25354         for (( i = 0; i < $MDSCOUNT; i++ )); do
25355                 count=$($LFS getdirstripe -i $testdir/* | grep -c "^$i$")
25356                 echo "$count directories created on MDT$i"
25357                 if $test_mkdir_rr; then
25358                         (( $count == 100 )) ||
25359                                 error "subdirs are not evenly distributed"
25360                 elif (( $i == $stripe_index )); then
25361                         (( $count == 100 * MDSCOUNT )) ||
25362                                 error "$count subdirs created on MDT$i"
25363                 else
25364                         (( $count == 0 )) ||
25365                                 error "$count subdirs created on MDT$i"
25366                 fi
25367
25368                 if $test_mkdir_rr && [ $stripe_count -gt 1 ]; then
25369                         count=$($LFS getdirstripe $testdir/* |
25370                                 grep -c -P "^\s+$i\t")
25371                         echo "$count stripes created on MDT$i"
25372                         # deviation should < 5% of average
25373                         (( $count >= 95 * stripe_count &&
25374                            $count <= 105 * stripe_count)) ||
25375                                 error "stripes are not evenly distributed"
25376                 fi
25377         done
25378
25379         echo
25380         echo "Check for uneven MDTs: "
25381
25382         local ffree
25383         local bavail
25384         local max
25385         local min
25386         local max_index
25387         local min_index
25388         local tmp
25389
25390         ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.filesfree))
25391         bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.kbytesavail))
25392         bsize=$(lctl get_param -n mdc.*MDT0000*.blocksize)
25393
25394         max=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
25395         min=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
25396         max_index=0
25397         min_index=0
25398         for ((i = 1; i < ${#ffree[@]}; i++)); do
25399                 tmp=$(((${ffree[i]} >> 8) * (${bavail[i]} * bsize >> 16)))
25400                 if [ $tmp -gt $max ]; then
25401                         max=$tmp
25402                         max_index=$i
25403                 fi
25404                 if [ $tmp -lt $min ]; then
25405                         min=$tmp
25406                         min_index=$i
25407                 fi
25408         done
25409
25410         (( ${ffree[min_index]} > 0 )) ||
25411                 skip "no free files in MDT$min_index"
25412         (( ${ffree[min_index]} < 10000000 )) ||
25413                 skip "too many free files in MDT$min_index"
25414
25415         echo "MDT filesfree available: ${ffree[@]}"
25416         echo "MDT blocks available: ${bavail[@]}"
25417         echo "weight diff=$(((max - min) * 100 / min))%"
25418         echo
25419         echo "Mkdir (stripe_count $stripe_count) with balanced space usage:"
25420
25421         $LCTL set_param lmv.*.qos_threshold_rr=0 > /dev/null
25422         $LCTL set_param lmv.*.qos_prio_free=100 > /dev/null
25423         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_threshold_rr=0 > /dev/null
25424         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_prio_free=100 > /dev/null
25425         # decrease statfs age, so that it can be updated in time
25426         $LCTL set_param lmv.*.qos_maxage=1 > /dev/null
25427         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_maxage=1 > /dev/null
25428
25429         sleep 1
25430
25431         testdir=$DIR/$tdir-s$stripe_count/qos
25432         local num=200
25433
25434         stack_trap "unlinkmany -d $testdir/subdir $((num * MDSCOUNT))"
25435         for (( i = 0; i < num * MDSCOUNT; i++ )); do
25436                 eval $mkdir_cmd $testdir/subdir$i ||
25437                         error "$mkdir_cmd subdir$i failed"
25438         done
25439
25440         max=0
25441         for (( i = 0; i < $MDSCOUNT; i++ )); do
25442                 count=$($LFS getdirstripe -i $testdir/* | grep -c "^$i$")
25443                 (( count > max )) && max=$count
25444                 echo "$count directories created on MDT$i"
25445         done
25446
25447         min=$($LFS getdirstripe -i $testdir/* | grep -c "^$min_index$")
25448
25449         # D-value should > 10% of averge
25450         (( max - min > num / 10 )) ||
25451                 error "subdirs shouldn't be evenly distributed: $max - $min < $((num / 10))"
25452
25453         # ditto for stripes
25454         if (( stripe_count > 1 )); then
25455                 max=0
25456                 for (( i = 0; i < $MDSCOUNT; i++ )); do
25457                         count=$($LFS getdirstripe $testdir/* |
25458                                 grep -c -P "^\s+$i\t")
25459                         (( count > max )) && max=$count
25460                         echo "$count stripes created on MDT$i"
25461                 done
25462
25463                 min=$($LFS getdirstripe $testdir/* |
25464                         grep -c -P "^\s+$min_index\t")
25465                 (( max - min > num * stripe_count / 10 )) ||
25466                         error "stripes shouldn't be evenly distributed: $max - $min < $((num / 10)) * $stripe_count"
25467         fi
25468 }
25469
25470 most_full_mdt() {
25471         local ffree
25472         local bavail
25473         local bsize
25474         local min
25475         local min_index
25476         local tmp
25477
25478         ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.filesfree))
25479         bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.kbytesavail))
25480         bsize=$(lctl get_param -n mdc.*MDT0000*.blocksize)
25481
25482         min=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
25483         min_index=0
25484         for ((i = 1; i < ${#ffree[@]}; i++)); do
25485                 tmp=$(((${ffree[i]} >> 8) * (${bavail[i]} * bsize >> 16)))
25486                 (( tmp < min )) && min=$tmp && min_index=$i
25487         done
25488
25489         echo -n $min_index
25490 }
25491
25492 test_413a() {
25493         [ $MDSCOUNT -lt 2 ] &&
25494                 skip "We need at least 2 MDTs for this test"
25495
25496         [ $MDS1_VERSION -lt $(version_code 2.12.52) ] &&
25497                 skip "Need server version at least 2.12.52"
25498
25499         local stripe_count
25500
25501         generate_uneven_mdts 100
25502         for stripe_count in $(seq 1 $((MDSCOUNT - 1))); do
25503                 mkdir $DIR/$tdir-s$stripe_count || error "mkdir failed"
25504                 mkdir $DIR/$tdir-s$stripe_count/rr || error "mkdir failed"
25505                 $LFS mkdir -i $(most_full_mdt) $DIR/$tdir-s$stripe_count/qos ||
25506                         error "mkdir failed"
25507                 test_qos_mkdir "$LFS mkdir -i -1 -c $stripe_count" $stripe_count
25508         done
25509 }
25510 run_test 413a "QoS mkdir with 'lfs mkdir -i -1'"
25511
25512 test_413b() {
25513         [ $MDSCOUNT -lt 2 ] &&
25514                 skip "We need at least 2 MDTs for this test"
25515
25516         [ $MDS1_VERSION -lt $(version_code 2.12.52) ] &&
25517                 skip "Need server version at least 2.12.52"
25518
25519         local testdir
25520         local stripe_count
25521
25522         generate_uneven_mdts 100
25523         for stripe_count in $(seq 1 $((MDSCOUNT - 1))); do
25524                 testdir=$DIR/$tdir-s$stripe_count
25525                 mkdir $testdir || error "mkdir $testdir failed"
25526                 mkdir $testdir/rr || error "mkdir rr failed"
25527                 $LFS mkdir -i $(most_full_mdt) $testdir/qos ||
25528                         error "mkdir qos failed"
25529                 $LFS setdirstripe -D -c $stripe_count --max-inherit-rr 2 \
25530                         $testdir/rr || error "setdirstripe rr failed"
25531                 $LFS setdirstripe -D -c $stripe_count $testdir/qos ||
25532                         error "setdirstripe failed"
25533                 test_qos_mkdir "mkdir" $stripe_count
25534         done
25535 }
25536 run_test 413b "QoS mkdir under dir whose default LMV starting MDT offset is -1"
25537
25538 test_413c() {
25539         (( $MDSCOUNT >= 2 )) ||
25540                 skip "We need at least 2 MDTs for this test"
25541
25542         (( $MDS1_VERSION >= $(version_code 2.14.51) )) ||
25543                 skip "Need server version at least 2.14.51"
25544
25545         local testdir
25546         local inherit
25547         local inherit_rr
25548
25549         testdir=$DIR/${tdir}-s1
25550         mkdir $testdir || error "mkdir $testdir failed"
25551         mkdir $testdir/rr || error "mkdir rr failed"
25552         $LFS mkdir -i $(most_full_mdt) $testdir/qos || error "mkdir qos failed"
25553         # default max_inherit is -1, default max_inherit_rr is 0
25554         $LFS setdirstripe -D -c 1 $testdir/rr ||
25555                 error "setdirstripe rr failed"
25556         $LFS setdirstripe -D -c 1 -i -1 -X 2 --max-inherit-rr 1 $testdir/qos ||
25557                 error "setdirstripe qos failed"
25558         test_qos_mkdir "mkdir" 1
25559
25560         mkdir $testdir/rr/level1 || error "mkdir rr/level1 failed"
25561         inherit=$($LFS getdirstripe -D -X $testdir/rr/level1)
25562         (( $inherit == -1 )) || error "rr/level1 inherit $inherit != -1"
25563         inherit_rr=$($LFS getdirstripe -D --max-inherit-rr $testdir/rr/level1)
25564         (( $inherit_rr == 0 )) || error "rr/level1 inherit-rr $inherit_rr != 0"
25565
25566         mkdir $testdir/qos/level1 || error "mkdir qos/level1 failed"
25567         inherit=$($LFS getdirstripe -D -X $testdir/qos/level1)
25568         (( $inherit == 1 )) || error "qos/level1 inherit $inherit != 1"
25569         inherit_rr=$($LFS getdirstripe -D --max-inherit-rr $testdir/qos/level1)
25570         (( $inherit_rr == 0 )) || error "qos/level1 inherit-rr $inherit_rr != 0"
25571         mkdir $testdir/qos/level1/level2 || error "mkdir level2 failed"
25572         getfattr -d -m dmv -e hex $testdir/qos/level1/level2 | grep dmv &&
25573                 error "level2 shouldn't have default LMV" || true
25574 }
25575 run_test 413c "mkdir with default LMV max inherit rr"
25576
25577 test_413d() {
25578         (( MDSCOUNT >= 2 )) ||
25579                 skip "We need at least 2 MDTs for this test"
25580
25581         (( MDS1_VERSION >= $(version_code 2.14.51) )) ||
25582                 skip "Need server version at least 2.14.51"
25583
25584         local lmv_qos_threshold_rr
25585
25586         lmv_qos_threshold_rr=$($LCTL get_param -n lmv.*.qos_threshold_rr |
25587                 head -n1)
25588         stack_trap "$LCTL set_param \
25589                 lmv.*.qos_threshold_rr=$lmv_qos_threshold_rr > /dev/null" EXIT
25590
25591         $LCTL set_param lmv.*.qos_threshold_rr=100 > /dev/null
25592         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
25593         getfattr -d -m dmv -e hex $DIR/$tdir | grep dmv &&
25594                 error "$tdir shouldn't have default LMV"
25595         createmany -d $DIR/$tdir/sub $((100 * MDSCOUNT)) ||
25596                 error "mkdir sub failed"
25597
25598         local count=$($LFS getstripe -m $DIR/$tdir/* | grep -c ^0)
25599
25600         (( count == 100 )) || error "$count subdirs on MDT0"
25601 }
25602 run_test 413d "inherit ROOT default LMV"
25603
25604 test_413z() {
25605         local pids=""
25606         local subdir
25607         local pid
25608
25609         for subdir in $(\ls -1 -d $DIR/d413*-fillmdt/*); do
25610                 unlinkmany $subdir/f. 1000 &
25611                 pids="$pids $!"
25612         done
25613
25614         for pid in $pids; do
25615                 wait $pid
25616         done
25617 }
25618 run_test 413z "413 test cleanup"
25619
25620 test_414() {
25621 #define OBD_FAIL_PTLRPC_BULK_ATTACH      0x521
25622         $LCTL set_param fail_loc=0x80000521
25623         dd if=/dev/zero of=$DIR/$tfile bs=2M count=1 oflag=sync
25624         rm -f $DIR/$tfile
25625 }
25626 run_test 414 "simulate ENOMEM in ptlrpc_register_bulk()"
25627
25628 test_415() {
25629         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25630         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
25631                 skip "Need server version at least 2.11.52"
25632
25633         # LU-11102
25634         local total
25635         local setattr_pid
25636         local start_time
25637         local end_time
25638         local duration
25639
25640         total=500
25641         # this test may be slow on ZFS
25642         [ "$mds1_FSTYPE" == "zfs" ] && total=100
25643
25644         # though this test is designed for striped directory, let's test normal
25645         # directory too since lock is always saved as CoS lock.
25646         test_mkdir $DIR/$tdir || error "mkdir $tdir"
25647         createmany -o $DIR/$tdir/$tfile. $total || error "createmany"
25648
25649         (
25650                 while true; do
25651                         touch $DIR/$tdir
25652                 done
25653         ) &
25654         setattr_pid=$!
25655
25656         start_time=$(date +%s)
25657         for i in $(seq $total); do
25658                 mrename $DIR/$tdir/$tfile.$i $DIR/$tdir/$tfile-new.$i \
25659                         > /dev/null
25660         done
25661         end_time=$(date +%s)
25662         duration=$((end_time - start_time))
25663
25664         kill -9 $setattr_pid
25665
25666         echo "rename $total files took $duration sec"
25667         [ $duration -lt 100 ] || error "rename took $duration sec"
25668 }
25669 run_test 415 "lock revoke is not missing"
25670
25671 test_416() {
25672         [ $MDS1_VERSION -lt $(version_code 2.11.55) ] &&
25673                 skip "Need server version at least 2.11.55"
25674
25675         # define OBD_FAIL_OSD_TXN_START    0x19a
25676         do_facet mds1 lctl set_param fail_loc=0x19a
25677
25678         lfs mkdir -c $MDSCOUNT $DIR/$tdir
25679
25680         true
25681 }
25682 run_test 416 "transaction start failure won't cause system hung"
25683
25684 cleanup_417() {
25685         trap 0
25686         do_nodes $(comma_list $(mdts_nodes)) \
25687                 "$LCTL set_param -n mdt.*MDT*.enable_dir_migration=1"
25688         do_nodes $(comma_list $(mdts_nodes)) \
25689                 "$LCTL set_param -n mdt.*MDT*.enable_remote_dir=1"
25690         do_nodes $(comma_list $(mdts_nodes)) \
25691                 "$LCTL set_param -n mdt.*MDT*.enable_striped_dir=1"
25692 }
25693
25694 test_417() {
25695         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
25696         [[ $MDS1_VERSION -lt $(version_code 2.11.56) ]] &&
25697                 skip "Need MDS version at least 2.11.56"
25698
25699         trap cleanup_417 RETURN EXIT
25700
25701         $LFS mkdir -i 1 $DIR/$tdir.1 || error "create remote dir $tdir.1 failed"
25702         do_nodes $(comma_list $(mdts_nodes)) \
25703                 "$LCTL set_param -n mdt.*MDT*.enable_dir_migration=0"
25704         $LFS migrate -m 0 $DIR/$tdir.1 &&
25705                 error "migrate dir $tdir.1 should fail"
25706
25707         do_nodes $(comma_list $(mdts_nodes)) \
25708                 "$LCTL set_param -n mdt.*MDT*.enable_remote_dir=0"
25709         $LFS mkdir -i 1 $DIR/$tdir.2 &&
25710                 error "create remote dir $tdir.2 should fail"
25711
25712         do_nodes $(comma_list $(mdts_nodes)) \
25713                 "$LCTL set_param -n mdt.*MDT*.enable_striped_dir=0"
25714         $LFS mkdir -c 2 $DIR/$tdir.3 &&
25715                 error "create striped dir $tdir.3 should fail"
25716         true
25717 }
25718 run_test 417 "disable remote dir, striped dir and dir migration"
25719
25720 # Checks that the outputs of df [-i] and lfs df [-i] match
25721 #
25722 # usage: check_lfs_df <blocks | inodes> <mountpoint>
25723 check_lfs_df() {
25724         local dir=$2
25725         local inodes
25726         local df_out
25727         local lfs_df_out
25728         local count
25729         local passed=false
25730
25731         # blocks or inodes
25732         [ "$1" == "blocks" ] && inodes= || inodes="-i"
25733
25734         for count in {1..100}; do
25735                 do_nodes "$CLIENTS" \
25736                         $LCTL set_param ldlm.namespaces.*.lru_size=clear
25737                 sync; sleep 0.2
25738
25739                 # read the lines of interest
25740                 df_out=($(df -P $inodes $dir | tail -n +2)) ||
25741                         error "df $inodes $dir | tail -n +2 failed"
25742                 lfs_df_out=($($LFS df $inodes $dir | grep summary:)) ||
25743                         error "lfs df $inodes $dir | grep summary: failed"
25744
25745                 # skip first substrings of each output as they are different
25746                 # "<NID>:/<fsname>" for df, "filesystem_summary:" for lfs df
25747                 # compare the two outputs
25748                 passed=true
25749                 #  skip "available" on MDT until LU-13997 is fixed.
25750                 #for i in {1..5}; do
25751                 for i in 1 2 4 5; do
25752                         [ "${df_out[i]}" != "${lfs_df_out[i]}" ] && passed=false
25753                 done
25754                 $passed && break
25755         done
25756
25757         if ! $passed; then
25758                 df -P $inodes $dir
25759                 echo
25760                 lfs df $inodes $dir
25761                 error "df and lfs df $1 output mismatch: "      \
25762                       "df ${inodes}: ${df_out[*]}, "            \
25763                       "lfs df ${inodes}: ${lfs_df_out[*]}"
25764         fi
25765 }
25766
25767 test_418() {
25768         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25769
25770         local dir=$DIR/$tdir
25771         local numfiles=$((RANDOM % 4096 + 2))
25772         local numblocks=$((RANDOM % 256 + 1))
25773
25774         wait_delete_completed
25775         test_mkdir $dir
25776
25777         # check block output
25778         check_lfs_df blocks $dir
25779         # check inode output
25780         check_lfs_df inodes $dir
25781
25782         # create a single file and retest
25783         echo "Creating a single file and testing"
25784         createmany -o $dir/$tfile- 1 &>/dev/null ||
25785                 error "creating 1 file in $dir failed"
25786         check_lfs_df blocks $dir
25787         check_lfs_df inodes $dir
25788
25789         # create a random number of files
25790         echo "Creating $((numfiles - 1)) files and testing"
25791         createmany -o $dir/$tfile- 1 $((numfiles - 1)) &>/dev/null ||
25792                 error "creating $((numfiles - 1)) files in $dir failed"
25793
25794         # write a random number of blocks to the first test file
25795         echo "Writing $numblocks 4K blocks and testing"
25796         dd if=/dev/urandom of=$dir/${tfile}-0 bs=4K conv=fsync \
25797                 count=$numblocks &>/dev/null ||
25798                 error "dd to $dir/${tfile}-0 failed"
25799
25800         # retest
25801         check_lfs_df blocks $dir
25802         check_lfs_df inodes $dir
25803
25804         unlinkmany $dir/$tfile- $numfiles &>/dev/null ||
25805                 error "unlinking $numfiles files in $dir failed"
25806 }
25807 run_test 418 "df and lfs df outputs match"
25808
25809 test_419()
25810 {
25811         local dir=$DIR/$tdir
25812
25813         mkdir -p $dir
25814         touch $dir/file
25815
25816         cancel_lru_locks mdc
25817
25818         #OBD_FAIL_LLITE_OPEN_BY_NAME    0x1410
25819         $LCTL set_param fail_loc=0x1410
25820         cat $dir/file
25821         $LCTL set_param fail_loc=0
25822         rm -rf $dir
25823 }
25824 run_test 419 "Verify open file by name doesn't crash kernel"
25825
25826 test_420()
25827 {
25828         [[ $MDS1_VERSION -ge $(version_code 2.12.53) ]] ||
25829                 skip "Need MDS version at least 2.12.53"
25830
25831         local SAVE_UMASK=$(umask)
25832         local dir=$DIR/$tdir
25833         local uname=$(getent passwd $RUNAS_ID | cut -d: -f1)
25834
25835         mkdir -p $dir
25836         umask 0000
25837         mkdir -m03777 $dir/testdir
25838         ls -dn $dir/testdir
25839         # Need to remove trailing '.' when SELinux is enabled
25840         local dirperms=$(ls -dn $dir/testdir |
25841                          awk '{ sub(/\.$/, "", $1); print $1}')
25842         [ $dirperms == "drwxrwsrwt" ] ||
25843                 error "incorrect perms on $dir/testdir"
25844
25845         su - $uname -c "PATH=$LUSTRE/tests:\$PATH; \
25846                 openfile -f O_RDONLY:O_CREAT -m 02755 $dir/testdir/testfile"
25847         ls -n $dir/testdir/testfile
25848         local fileperms=$(ls -n $dir/testdir/testfile |
25849                           awk '{ sub(/\.$/, "", $1); print $1}')
25850         [ $fileperms == "-rwxr-xr-x" ] ||
25851                 error "incorrect perms on $dir/testdir/testfile"
25852
25853         umask $SAVE_UMASK
25854 }
25855 run_test 420 "clear SGID bit on non-directories for non-members"
25856
25857 test_421a() {
25858         local cnt
25859         local fid1
25860         local fid2
25861
25862         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
25863                 skip "Need MDS version at least 2.12.54"
25864
25865         test_mkdir $DIR/$tdir
25866         createmany -o $DIR/$tdir/f 3
25867         cnt=$(ls -1 $DIR/$tdir | wc -l)
25868         [ $cnt != 3 ] && error "unexpected #files: $cnt"
25869
25870         fid1=$(lfs path2fid $DIR/$tdir/f1)
25871         fid2=$(lfs path2fid $DIR/$tdir/f2)
25872         $LFS rmfid $DIR $fid1 $fid2 || error "rmfid failed"
25873
25874         stat $DIR/$tdir/f1 && error "f1 still visible on the client"
25875         stat $DIR/$tdir/f2 && error "f2 still visible on the client"
25876
25877         cnt=$(ls -1 $DIR/$tdir | wc -l)
25878         [ $cnt == 1 ] || error "unexpected #files after: $cnt"
25879
25880         rm -f $DIR/$tdir/f3 || error "can't remove f3"
25881         createmany -o $DIR/$tdir/f 3
25882         cnt=$(ls -1 $DIR/$tdir | wc -l)
25883         [ $cnt != 3 ] && error "unexpected #files: $cnt"
25884
25885         fid1=$(lfs path2fid $DIR/$tdir/f1)
25886         fid2=$(lfs path2fid $DIR/$tdir/f2)
25887         echo "remove using fsname $FSNAME"
25888         $LFS rmfid $FSNAME $fid1 $fid2 || error "rmfid with fsname failed"
25889
25890         cnt=$(ls -1 $DIR/$tdir | wc -l)
25891         [ $cnt == 1 ] || error "unexpected #files after: $cnt"
25892 }
25893 run_test 421a "simple rm by fid"
25894
25895 test_421b() {
25896         local cnt
25897         local FID1
25898         local FID2
25899
25900         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
25901                 skip "Need MDS version at least 2.12.54"
25902
25903         test_mkdir $DIR/$tdir
25904         createmany -o $DIR/$tdir/f 3
25905         multiop_bg_pause $DIR/$tdir/f1 o_c || error "multiop failed to start"
25906         MULTIPID=$!
25907
25908         FID1=$(lfs path2fid $DIR/$tdir/f1)
25909         FID2=$(lfs path2fid $DIR/$tdir/f2)
25910         $LFS rmfid $DIR $FID1 $FID2 && error "rmfid didn't fail"
25911
25912         kill -USR1 $MULTIPID
25913         wait
25914
25915         cnt=$(ls $DIR/$tdir | wc -l)
25916         [ $cnt == 2 ] || error "unexpected #files after: $cnt"
25917 }
25918 run_test 421b "rm by fid on open file"
25919
25920 test_421c() {
25921         local cnt
25922         local FIDS
25923
25924         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
25925                 skip "Need MDS version at least 2.12.54"
25926
25927         test_mkdir $DIR/$tdir
25928         createmany -o $DIR/$tdir/f 3
25929         touch $DIR/$tdir/$tfile
25930         createmany -l$DIR/$tdir/$tfile $DIR/$tdir/h 180
25931         cnt=$(ls -1 $DIR/$tdir | wc -l)
25932         [ $cnt != 184 ] && error "unexpected #files: $cnt"
25933
25934         FID1=$(lfs path2fid $DIR/$tdir/$tfile)
25935         $LFS rmfid $DIR $FID1 || error "rmfid failed"
25936
25937         cnt=$(ls $DIR/$tdir | wc -l)
25938         [ $cnt == 3 ] || error "unexpected #files after: $cnt"
25939 }
25940 run_test 421c "rm by fid against hardlinked files"
25941
25942 test_421d() {
25943         local cnt
25944         local FIDS
25945
25946         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
25947                 skip "Need MDS version at least 2.12.54"
25948
25949         test_mkdir $DIR/$tdir
25950         createmany -o $DIR/$tdir/f 4097
25951         cnt=$(ls -1 $DIR/$tdir | wc -l)
25952         [ $cnt != 4097 ] && error "unexpected #files: $cnt"
25953
25954         FIDS=$(lfs path2fid $DIR/$tdir/f* | sed "s/[/][^:]*://g")
25955         $LFS rmfid $DIR $FIDS || error "rmfid failed"
25956
25957         cnt=$(ls $DIR/$tdir | wc -l)
25958         rm -rf $DIR/$tdir
25959         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
25960 }
25961 run_test 421d "rmfid en masse"
25962
25963 test_421e() {
25964         local cnt
25965         local FID
25966
25967         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
25968         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
25969                 skip "Need MDS version at least 2.12.54"
25970
25971         mkdir -p $DIR/$tdir
25972         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
25973         createmany -o $DIR/$tdir/striped_dir/f 512
25974         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
25975         [ $cnt != 512 ] && error "unexpected #files: $cnt"
25976
25977         FIDS=$(lfs path2fid $DIR/$tdir/striped_dir/f* |
25978                 sed "s/[/][^:]*://g")
25979         $LFS rmfid $DIR $FIDS || error "rmfid failed"
25980
25981         cnt=$(ls $DIR/$tdir/striped_dir | wc -l)
25982         rm -rf $DIR/$tdir
25983         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
25984 }
25985 run_test 421e "rmfid in DNE"
25986
25987 test_421f() {
25988         local cnt
25989         local FID
25990
25991         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
25992                 skip "Need MDS version at least 2.12.54"
25993
25994         test_mkdir $DIR/$tdir
25995         touch $DIR/$tdir/f
25996         cnt=$(ls -1 $DIR/$tdir | wc -l)
25997         [ $cnt != 1 ] && error "unexpected #files: $cnt"
25998
25999         FID=$(lfs path2fid $DIR/$tdir/f)
26000         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail (1)"
26001         # rmfid should fail
26002         cnt=$(ls -1 $DIR/$tdir | wc -l)
26003         [ $cnt != 1 ] && error "unexpected #files after (2): $cnt"
26004
26005         chmod a+rw $DIR/$tdir
26006         ls -la $DIR/$tdir
26007         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail (2)"
26008         # rmfid should fail
26009         cnt=$(ls -1 $DIR/$tdir | wc -l)
26010         [ $cnt != 1 ] && error "unexpected #files after (3): $cnt"
26011
26012         rm -f $DIR/$tdir/f
26013         $RUNAS touch $DIR/$tdir/f
26014         FID=$(lfs path2fid $DIR/$tdir/f)
26015         echo "rmfid as root"
26016         $LFS rmfid $DIR $FID || error "rmfid as root failed"
26017         cnt=$(ls -1 $DIR/$tdir | wc -l)
26018         [ $cnt == 0 ] || error "unexpected #files after (4): $cnt"
26019
26020         rm -f $DIR/$tdir/f
26021         $RUNAS touch $DIR/$tdir/f
26022         cnt=$(ls -1 $DIR/$tdir | wc -l)
26023         [ $cnt != 1 ] && error "unexpected #files (4): $cnt"
26024         FID=$(lfs path2fid $DIR/$tdir/f)
26025         # rmfid w/o user_fid2path mount option should fail
26026         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail(3)"
26027         cnt=$(ls -1 $DIR/$tdir | wc -l)
26028         [ $cnt == 1 ] || error "unexpected #files after (5): $cnt"
26029
26030         tmpdir=$(mktemp -d /tmp/lustre-XXXXXX)
26031         stack_trap "rmdir $tmpdir"
26032         mount_client $tmpdir "$MOUNT_OPTS,user_fid2path" ||
26033                 error "failed to mount client'"
26034         stack_trap "umount_client $tmpdir"
26035
26036         $RUNAS $LFS rmfid $tmpdir $FID || error "rmfid failed"
26037         # rmfid should succeed
26038         cnt=$(ls -1 $tmpdir/$tdir | wc -l)
26039         [ $cnt == 0 ] || error "unexpected #files after (6): $cnt"
26040
26041         # rmfid shouldn't allow to remove files due to dir's permission
26042         chmod a+rwx $tmpdir/$tdir
26043         touch $tmpdir/$tdir/f
26044         ls -la $tmpdir/$tdir
26045         FID=$(lfs path2fid $tmpdir/$tdir/f)
26046         $RUNAS $LFS rmfid $tmpdir $FID && error "rmfid didn't fail"
26047         return 0
26048 }
26049 run_test 421f "rmfid checks permissions"
26050
26051 test_421g() {
26052         local cnt
26053         local FIDS
26054
26055         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
26056         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
26057                 skip "Need MDS version at least 2.12.54"
26058
26059         mkdir -p $DIR/$tdir
26060         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
26061         createmany -o $DIR/$tdir/striped_dir/f 512
26062         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
26063         [ $cnt != 512 ] && error "unexpected #files: $cnt"
26064
26065         FIDS=$(lfs path2fid $DIR/$tdir/striped_dir/f* |
26066                 sed "s/[/][^:]*://g")
26067
26068         rm -f $DIR/$tdir/striped_dir/f1*
26069         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
26070         removed=$((512 - cnt))
26071
26072         # few files have been just removed, so we expect
26073         # rmfid to fail on their fids
26074         errors=$($LFS rmfid $DIR $FIDS 2>&1 | wc -l)
26075         [ $removed != $errors ] && error "$errors != $removed"
26076
26077         cnt=$(ls $DIR/$tdir/striped_dir | wc -l)
26078         rm -rf $DIR/$tdir
26079         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
26080 }
26081 run_test 421g "rmfid to return errors properly"
26082
26083 test_422() {
26084         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d1
26085         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d2
26086         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d3
26087         dd if=/dev/zero of=$DIR/$tdir/d1/file1 bs=1k count=1
26088         dd if=/dev/zero of=$DIR/$tdir/d2/file1 bs=1k count=1
26089
26090         local amc=$(at_max_get client)
26091         local amo=$(at_max_get mds1)
26092         local timeout=`lctl get_param -n timeout`
26093
26094         at_max_set 0 client
26095         at_max_set 0 mds1
26096
26097 #define OBD_FAIL_PTLRPC_PAUSE_REQ        0x50a
26098         do_facet mds1 $LCTL set_param fail_loc=0x8000050a \
26099                         fail_val=$(((2*timeout + 10)*1000))
26100         touch $DIR/$tdir/d3/file &
26101         sleep 2
26102 #define OBD_FAIL_TGT_REPLY_DATA_RACE     0x722
26103         do_facet mds1 $LCTL set_param fail_loc=0x80000722 \
26104                         fail_val=$((2*timeout + 5))
26105         mv $DIR/$tdir/d1/file1 $DIR/$tdir/d1/file2 &
26106         local pid=$!
26107         sleep 1
26108         kill -9 $pid
26109         sleep $((2 * timeout))
26110         echo kill $pid
26111         kill -9 $pid
26112         lctl mark touch
26113         touch $DIR/$tdir/d2/file3
26114         touch $DIR/$tdir/d2/file4
26115         touch $DIR/$tdir/d2/file5
26116
26117         wait
26118         at_max_set $amc client
26119         at_max_set $amo mds1
26120
26121         # LU-12838 - verify the ptlrpc thread watchdog is not always throttled
26122         do_facet mds1 "dmesg | grep 'Dumping the stack trace for debugging'" ||
26123                 error "Watchdog is always throttled"
26124 }
26125 run_test 422 "kill a process with RPC in progress"
26126
26127 stat_test() {
26128     df -h $MOUNT &
26129     df -h $MOUNT &
26130     df -h $MOUNT &
26131     df -h $MOUNT &
26132     df -h $MOUNT &
26133     df -h $MOUNT &
26134 }
26135
26136 test_423() {
26137     local _stats
26138     # ensure statfs cache is expired
26139     sleep 2;
26140
26141     _stats=$(stat_test | grep $MOUNT | sort -u | wc -l)
26142     [[ ${_stats} -ne 1 ]] && error "statfs wrong"
26143
26144     return 0
26145 }
26146 run_test 423 "statfs should return a right data"
26147
26148 test_424() {
26149 #define OBD_FAIL_PTLRPC_BULK_REPLY_ATTACH      0x522 | OBD_FAIL_ONCE
26150         $LCTL set_param fail_loc=0x80000522
26151         dd if=/dev/zero of=$DIR/$tfile bs=2M count=1 oflag=sync
26152         rm -f $DIR/$tfile
26153 }
26154 run_test 424 "simulate ENOMEM in ptl_send_rpc bulk reply ME attach"
26155
26156 test_425() {
26157         test_mkdir -c -1 $DIR/$tdir
26158         $LFS setstripe -c -1 $DIR/$tdir
26159
26160         lru_resize_disable "" 100
26161         stack_trap "lru_resize_enable" EXIT
26162
26163         sleep 5
26164
26165         for i in $(seq $((MDSCOUNT * 125))); do
26166                 local t=$DIR/$tdir/$tfile_$i
26167
26168                 dd if=/dev/zero of=$t bs=4K count=1 > /dev/null 2>&1 ||
26169                         error_noexit "Create file $t"
26170         done
26171         stack_trap "rm -rf $DIR/$tdir" EXIT
26172
26173         for oscparam in $($LCTL list_param ldlm.namespaces.*osc-[-0-9a-f]*); do
26174                 local lru_size=$($LCTL get_param -n $oscparam.lru_size)
26175                 local lock_count=$($LCTL get_param -n $oscparam.lock_count)
26176
26177                 [ $lock_count -le $lru_size ] ||
26178                         error "osc lock count $lock_count > lru size $lru_size"
26179         done
26180
26181         for mdcparam in $($LCTL list_param ldlm.namespaces.*mdc-*); do
26182                 local lru_size=$($LCTL get_param -n $mdcparam.lru_size)
26183                 local lock_count=$($LCTL get_param -n $mdcparam.lock_count)
26184
26185                 [ $lock_count -le $lru_size ] ||
26186                         error "mdc lock count $lock_count > lru size $lru_size"
26187         done
26188 }
26189 run_test 425 "lock count should not exceed lru size"
26190
26191 test_426() {
26192         splice-test -r $DIR/$tfile
26193         splice-test -rd $DIR/$tfile
26194         splice-test $DIR/$tfile
26195         splice-test -d $DIR/$tfile
26196 }
26197 run_test 426 "splice test on Lustre"
26198
26199 test_427() {
26200         [ $MDSCOUNT -ge 2 ] || skip "needs >= 2 MDTs"
26201         (( $MDS1_VERSION >= $(version_code 2.12.4) )) ||
26202                 skip "Need MDS version at least 2.12.4"
26203         local log
26204
26205         mkdir $DIR/$tdir
26206         mkdir $DIR/$tdir/1
26207         mkdir $DIR/$tdir/2
26208         test_mkdir -c $MDSCOUNT -i 1 $DIR/$tdir/1/dir
26209         test_mkdir -c $MDSCOUNT -i 1 $DIR/$tdir/2/dir2
26210
26211         $LFS getdirstripe $DIR/$tdir/1/dir
26212
26213         #first setfattr for creating updatelog
26214         setfattr -n user.attr0 -v "some text" $DIR/$tdir/1/dir
26215
26216 #define OBD_FAIL_OUT_OBJECT_MISS        0x1708
26217         do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param fail_loc=0x80001708
26218         setfattr -n user.attr1 -v "some text" $DIR/$tdir/1/dir &
26219         setfattr -n user.attr2 -v "another attr"  $DIR/$tdir/2/dir2 &
26220
26221         sleep 2
26222         fail mds2
26223         wait_recovery_complete mds2 $((2*TIMEOUT))
26224
26225         log=$(do_facet mds1 dmesg | tac | sed "/${TESTNAME//_/ }/,$ d")
26226         echo $log | grep "get update log failed" &&
26227                 error "update log corruption is detected" || true
26228 }
26229 run_test 427 "Failed DNE2 update request shouldn't corrupt updatelog"
26230
26231 test_428() {
26232         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26233         local cache_limit=$CACHE_MAX
26234
26235         stack_trap "$LCTL set_param -n llite.*.max_cached_mb=$cache_limit"
26236         $LCTL set_param -n llite.*.max_cached_mb=64
26237
26238         mkdir $DIR/$tdir
26239         $LFS setstripe -c 1 $DIR/$tdir
26240         eval touch $DIR/$tdir/$tfile.{1..$OSTCOUNT}
26241         stack_trap "rm -f $DIR/$tdir/$tfile.*"
26242         #test write
26243         for f in $(seq 4); do
26244                 dd if=/dev/zero of=$DIR/$tdir/$tfile.$f bs=128M count=1 &
26245         done
26246         wait
26247
26248         cancel_lru_locks osc
26249         # Test read
26250         for f in $(seq 4); do
26251                 dd if=$DIR/$tdir/$tfile.$f of=/dev/null bs=128M count=1 &
26252         done
26253         wait
26254 }
26255 run_test 428 "large block size IO should not hang"
26256
26257 test_429() { # LU-7915 / LU-10948
26258         local ll_opencache_threshold_count="llite.*.opencache_threshold_count"
26259         local testfile=$DIR/$tfile
26260         local mdc_rpcstats="mdc.$FSNAME-MDT0000-*.stats"
26261         local new_flag=1
26262         local first_rpc
26263         local second_rpc
26264         local third_rpc
26265
26266         $LCTL get_param $ll_opencache_threshold_count ||
26267                 skip "client does not have opencache parameter"
26268
26269         set_opencache $new_flag
26270         stack_trap "restore_opencache"
26271         [ $($LCTL get_param -n $ll_opencache_threshold_count) == $new_flag ] ||
26272                 error "enable opencache failed"
26273         touch $testfile
26274         # drop MDC DLM locks
26275         cancel_lru_locks mdc
26276         # clear MDC RPC stats counters
26277         $LCTL set_param $mdc_rpcstats=clear
26278
26279         # According to the current implementation, we need to run 3 times
26280         # open & close file to verify if opencache is enabled correctly.
26281         # 1st, RPCs are sent for lookup/open and open handle is released on
26282         #      close finally.
26283         # 2nd, RPC is sent for open, MDS_OPEN_LOCK is fetched automatically,
26284         #      so open handle won't be released thereafter.
26285         # 3rd, No RPC is sent out.
26286         $MULTIOP $testfile oc || error "multiop failed"
26287         first_rpc=$(calc_stats $mdc_rpcstats ldlm_ibits_enqueue)
26288         echo "1st: $first_rpc RPCs in flight"
26289
26290         $MULTIOP $testfile oc || error "multiop failed"
26291         second_rpc=$(calc_stats $mdc_rpcstats ldlm_ibits_enqueue)
26292         echo "2nd: $second_rpc RPCs in flight"
26293
26294         $MULTIOP $testfile oc || error "multiop failed"
26295         third_rpc=$(calc_stats $mdc_rpcstats ldlm_ibits_enqueue)
26296         echo "3rd: $third_rpc RPCs in flight"
26297
26298         #verify no MDC RPC is sent
26299         [[ $second_rpc == $third_rpc ]] || error "MDC RPC is still sent"
26300 }
26301 run_test 429 "verify if opencache flag on client side does work"
26302
26303 lseek_test_430() {
26304         local offset
26305         local file=$1
26306
26307         # data at [200K, 400K)
26308         dd if=/dev/urandom of=$file bs=256K count=1 seek=1 ||
26309                 error "256K->512K dd fails"
26310         # data at [2M, 3M)
26311         dd if=/dev/urandom of=$file bs=1M count=1 seek=2 ||
26312                 error "2M->3M dd fails"
26313         # data at [4M, 5M)
26314         dd if=/dev/urandom of=$file bs=1M count=1 seek=4 ||
26315                 error "4M->5M dd fails"
26316         echo "Data at 256K...512K, 2M...3M and 4M...5M"
26317         # start at first component hole #1
26318         printf "Seeking hole from 1000 ... "
26319         offset=$(lseek_test -l 1000 $file)
26320         echo $offset
26321         [[ $offset == 1000 ]] || error "offset $offset != 1000"
26322         printf "Seeking data from 1000 ... "
26323         offset=$(lseek_test -d 1000 $file)
26324         echo $offset
26325         [[ $offset == 262144 ]] || error "offset $offset != 262144"
26326
26327         # start at first component data block
26328         printf "Seeking hole from 300000 ... "
26329         offset=$(lseek_test -l 300000 $file)
26330         echo $offset
26331         [[ $offset == 524288 ]] || error "offset $offset != 524288"
26332         printf "Seeking data from 300000 ... "
26333         offset=$(lseek_test -d 300000 $file)
26334         echo $offset
26335         [[ $offset == 300000 ]] || error "offset $offset != 300000"
26336
26337         # start at the first component but beyond end of object size
26338         printf "Seeking hole from 1000000 ... "
26339         offset=$(lseek_test -l 1000000 $file)
26340         echo $offset
26341         [[ $offset == 1000000 ]] || error "offset $offset != 1000000"
26342         printf "Seeking data from 1000000 ... "
26343         offset=$(lseek_test -d 1000000 $file)
26344         echo $offset
26345         [[ $offset == 2097152 ]] || error "offset $offset != 2097152"
26346
26347         # start at second component stripe 2 (empty file)
26348         printf "Seeking hole from 1500000 ... "
26349         offset=$(lseek_test -l 1500000 $file)
26350         echo $offset
26351         [[ $offset == 1500000 ]] || error "offset $offset != 1500000"
26352         printf "Seeking data from 1500000 ... "
26353         offset=$(lseek_test -d 1500000 $file)
26354         echo $offset
26355         [[ $offset == 2097152 ]] || error "offset $offset != 2097152"
26356
26357         # start at second component stripe 1 (all data)
26358         printf "Seeking hole from 3000000 ... "
26359         offset=$(lseek_test -l 3000000 $file)
26360         echo $offset
26361         [[ $offset == 3145728 ]] || error "offset $offset != 3145728"
26362         printf "Seeking data from 3000000 ... "
26363         offset=$(lseek_test -d 3000000 $file)
26364         echo $offset
26365         [[ $offset == 3000000 ]] || error "offset $offset != 3000000"
26366
26367         dd if=/dev/urandom of=$file bs=640K count=1 seek=1 ||
26368                 error "2nd dd fails"
26369         echo "Add data block at 640K...1280K"
26370
26371         # start at before new data block, in hole
26372         printf "Seeking hole from 600000 ... "
26373         offset=$(lseek_test -l 600000 $file)
26374         echo $offset
26375         [[ $offset == 600000 ]] || error "offset $offset != 600000"
26376         printf "Seeking data from 600000 ... "
26377         offset=$(lseek_test -d 600000 $file)
26378         echo $offset
26379         [[ $offset == 655360 ]] || error "offset $offset != 655360"
26380
26381         # start at the first component new data block
26382         printf "Seeking hole from 1000000 ... "
26383         offset=$(lseek_test -l 1000000 $file)
26384         echo $offset
26385         [[ $offset == 1310720 ]] || error "offset $offset != 1310720"
26386         printf "Seeking data from 1000000 ... "
26387         offset=$(lseek_test -d 1000000 $file)
26388         echo $offset
26389         [[ $offset == 1000000 ]] || error "offset $offset != 1000000"
26390
26391         # start at second component stripe 2, new data
26392         printf "Seeking hole from 1200000 ... "
26393         offset=$(lseek_test -l 1200000 $file)
26394         echo $offset
26395         [[ $offset == 1310720 ]] || error "offset $offset != 1310720"
26396         printf "Seeking data from 1200000 ... "
26397         offset=$(lseek_test -d 1200000 $file)
26398         echo $offset
26399         [[ $offset == 1200000 ]] || error "offset $offset != 1200000"
26400
26401         # start beyond file end
26402         printf "Using offset > filesize ... "
26403         lseek_test -l 4000000 $file && error "lseek should fail"
26404         printf "Using offset > filesize ... "
26405         lseek_test -d 4000000 $file && error "lseek should fail"
26406
26407         printf "Done\n\n"
26408 }
26409
26410 test_430a() {
26411         $LCTL get_param mdc.*.import | grep -q 'connect_flags:.*seek' ||
26412                 skip "MDT does not support SEEK_HOLE"
26413
26414         $LCTL get_param osc.*.import | grep -q 'connect_flags:.*seek' ||
26415                 skip "OST does not support SEEK_HOLE"
26416
26417         local file=$DIR/$tdir/$tfile
26418
26419         mkdir -p $DIR/$tdir
26420
26421         $LFS setstripe -E 1M -L mdt -E eof -c2 $file
26422         # OST stripe #1 will have continuous data at [1M, 3M)
26423         # OST stripe #2 is empty
26424         echo "Component #1: 1M DoM, component #2: EOF, 2 stripes 1M"
26425         lseek_test_430 $file
26426         rm $file
26427         $LFS setstripe -E 1M -c2 -S 64K -E 10M -c2 -S 1M $file
26428         echo "Component #1: 1M, 2 stripes 64K, component #2: EOF, 2 stripes 1M"
26429         lseek_test_430 $file
26430         rm $file
26431         $LFS setstripe -c2 -S 512K $file
26432         echo "Two stripes, stripe size 512K"
26433         lseek_test_430 $file
26434         rm $file
26435         # FLR with stale mirror
26436         $LFS setstripe -N -E 512K -c1 -S 64K -E eof -c2 -S 512K \
26437                        -N -c2 -S 1M $file
26438         echo "Mirrored file:"
26439         echo "Component #1: 512K, stripe 64K, component #2: EOF, 2 stripes 512K"
26440         echo "Plain 2 stripes 1M"
26441         lseek_test_430 $file
26442         rm $file
26443 }
26444 run_test 430a "lseek: SEEK_DATA/SEEK_HOLE basic functionality"
26445
26446 test_430b() {
26447         $LCTL get_param osc.*.import | grep -q 'connect_flags:.*seek' ||
26448                 skip "OST does not support SEEK_HOLE"
26449
26450         local offset
26451         local file=$DIR/$tdir/$tfile
26452
26453         mkdir -p $DIR/$tdir
26454         # Empty layout lseek should fail
26455         $MCREATE $file
26456         # seek from 0
26457         printf "Seeking hole from 0 ... "
26458         lseek_test -l 0 $file && error "lseek should fail"
26459         printf "Seeking data from 0 ... "
26460         lseek_test -d 0 $file && error "lseek should fail"
26461         rm $file
26462
26463         # 1M-hole file
26464         $LFS setstripe -E 1M -c2 -E eof $file
26465         $TRUNCATE $file 1048576
26466         printf "Seeking hole from 1000000 ... "
26467         offset=$(lseek_test -l 1000000 $file)
26468         echo $offset
26469         [[ $offset == 1000000 ]] || error "offset $offset != 1000000"
26470         printf "Seeking data from 1000000 ... "
26471         lseek_test -d 1000000 $file && error "lseek should fail"
26472         rm $file
26473
26474         # full component followed by non-inited one
26475         $LFS setstripe -E 1M -c2 -E eof $file
26476         dd if=/dev/urandom of=$file bs=1M count=1
26477         printf "Seeking hole from 1000000 ... "
26478         offset=$(lseek_test -l 1000000 $file)
26479         echo $offset
26480         [[ $offset == 1048576 ]] || error "offset $offset != 1048576"
26481         printf "Seeking hole from 1048576 ... "
26482         lseek_test -l 1048576 $file && error "lseek should fail"
26483         # init second component and truncate back
26484         echo "123" >> $file
26485         $TRUNCATE $file 1048576
26486         printf "Seeking hole from 1000000 ... "
26487         offset=$(lseek_test -l 1000000 $file)
26488         echo $offset
26489         [[ $offset == 1048576 ]] || error "offset $offset != 1048576"
26490         printf "Seeking hole from 1048576 ... "
26491         lseek_test -l 1048576 $file && error "lseek should fail"
26492         # boundary checks for big values
26493         dd if=/dev/urandom of=$file.10g bs=1 count=1 seek=10G
26494         offset=$(lseek_test -d 0 $file.10g)
26495         [[ $offset == 10737418240 ]] || error "offset $offset != 10737418240"
26496         dd if=/dev/urandom of=$file.100g bs=1 count=1 seek=100G
26497         offset=$(lseek_test -d 0 $file.100g)
26498         [[ $offset == 107374182400 ]] || error "offset $offset != 107374182400"
26499         return 0
26500 }
26501 run_test 430b "lseek: SEEK_DATA/SEEK_HOLE special cases"
26502
26503 test_430c() {
26504         $LCTL get_param osc.*.import | grep -q 'connect_flags:.*seek' ||
26505                 skip "OST does not support SEEK_HOLE"
26506
26507         local file=$DIR/$tdir/$tfile
26508         local start
26509
26510         mkdir -p $DIR/$tdir
26511         dd if=/dev/urandom of=$file bs=1k count=1 seek=5M
26512
26513         # cp version 8.33+ prefers lseek over fiemap
26514         if [[ $(cp --version | head -n1 | sed "s/[^0-9]//g") -ge 833 ]]; then
26515                 start=$SECONDS
26516                 time cp $file /dev/null
26517                 (( SECONDS - start < 5 )) ||
26518                         error "cp: too long runtime $((SECONDS - start))"
26519
26520         fi
26521         # tar version 1.29+ supports SEEK_HOLE/DATA
26522         if [[ $(tar --version | head -n1 | sed "s/[^0-9]//g") -ge 129 ]]; then
26523                 start=$SECONDS
26524                 time tar cS $file - | cat > /dev/null
26525                 (( SECONDS - start < 5 )) ||
26526                         error "tar: too long runtime $((SECONDS - start))"
26527         fi
26528 }
26529 run_test 430c "lseek: external tools check"
26530
26531 test_431() { # LU-14187
26532         local file=$DIR/$tdir/$tfile
26533
26534         mkdir -p $DIR/$tdir
26535         $LFS setstripe -c 1 -i 0 $file || error "lfs setstripe failed"
26536         dd if=/dev/urandom of=$file bs=4k count=1
26537         dd if=/dev/urandom of=$file bs=4k count=1 seek=10 conv=notrunc
26538         dd if=/dev/urandom of=$file bs=4k count=1 seek=12 conv=notrunc
26539         #define OBD_FAIL_OST_RESTART_IO 0x251
26540         do_facet ost1 "$LCTL set_param fail_loc=0x251"
26541         $LFS setstripe -c 1 -i 0 $file.0 || error "lfs setstripe failed"
26542         cp $file $file.0
26543         cancel_lru_locks
26544         sync_all_data
26545         echo 3 > /proc/sys/vm/drop_caches
26546         diff  $file $file.0 || error "data diff"
26547 }
26548 run_test 431 "Restart transaction for IO"
26549
26550 cleanup_test_432() {
26551         do_facet mgs $LCTL nodemap_activate 0
26552         wait_nm_sync active
26553 }
26554
26555 test_432() {
26556         local tmpdir=$TMP/dir432
26557
26558         (( $MDS1_VERSION >= $(version_code 2.14.52) )) ||
26559                 skip "Need MDS version at least 2.14.52"
26560
26561         stack_trap cleanup_test_432 EXIT
26562         mkdir $DIR/$tdir
26563         mkdir $tmpdir
26564
26565         do_facet mgs $LCTL nodemap_activate 1
26566         wait_nm_sync active
26567         do_facet mgs $LCTL nodemap_modify --name default \
26568                 --property admin --value 1
26569         do_facet mgs $LCTL nodemap_modify --name default \
26570                 --property trusted --value 1
26571         cancel_lru_locks mdc
26572         wait_nm_sync default admin_nodemap
26573         wait_nm_sync default trusted_nodemap
26574
26575         if [ $(mv $tmpdir $DIR/$tdir/ 2>&1 |
26576                grep -ci "Operation not permitted") -ne 0 ]; then
26577                 error "mv $tmpdir $DIR/$tdir/ hits 'Operation not permitted'"
26578         fi
26579 }
26580 run_test 432 "mv dir from outside Lustre"
26581
26582 prep_801() {
26583         [[ $MDS1_VERSION -lt $(version_code 2.9.55) ]] ||
26584         [[ $OST1_VERSION -lt $(version_code 2.9.55) ]] &&
26585                 skip "Need server version at least 2.9.55"
26586
26587         start_full_debug_logging
26588 }
26589
26590 post_801() {
26591         stop_full_debug_logging
26592 }
26593
26594 barrier_stat() {
26595         if [ $MGS_VERSION -le $(version_code 2.10.0) ]; then
26596                 local st=$(do_facet mgs $LCTL barrier_stat $FSNAME |
26597                            awk '/The barrier for/ { print $7 }')
26598                 echo $st
26599         else
26600                 local st=$(do_facet mgs $LCTL barrier_stat -s $FSNAME)
26601                 echo \'$st\'
26602         fi
26603 }
26604
26605 barrier_expired() {
26606         local expired
26607
26608         if [ $MGS_VERSION -le $(version_code 2.10.0) ]; then
26609                 expired=$(do_facet mgs $LCTL barrier_stat $FSNAME |
26610                           awk '/will be expired/ { print $7 }')
26611         else
26612                 expired=$(do_facet mgs $LCTL barrier_stat -t $FSNAME)
26613         fi
26614
26615         echo $expired
26616 }
26617
26618 test_801a() {
26619         prep_801
26620
26621         echo "Start barrier_freeze at: $(date)"
26622         #define OBD_FAIL_BARRIER_DELAY          0x2202
26623         do_facet mgs $LCTL set_param fail_val=5 fail_loc=0x2202
26624         # Do not reduce barrier time - See LU-11873
26625         do_facet mgs $LCTL barrier_freeze $FSNAME 20 &
26626
26627         sleep 2
26628         local b_status=$(barrier_stat)
26629         echo "Got barrier status at: $(date)"
26630         [ "$b_status" = "'freezing_p1'" ] ||
26631                 error "(1) unexpected barrier status $b_status"
26632
26633         do_facet mgs $LCTL set_param fail_val=0 fail_loc=0
26634         wait
26635         b_status=$(barrier_stat)
26636         [ "$b_status" = "'frozen'" ] ||
26637                 error "(2) unexpected barrier status $b_status"
26638
26639         local expired=$(barrier_expired)
26640         echo "sleep $((expired + 3)) seconds, then the barrier will be expired"
26641         sleep $((expired + 3))
26642
26643         b_status=$(barrier_stat)
26644         [ "$b_status" = "'expired'" ] ||
26645                 error "(3) unexpected barrier status $b_status"
26646
26647         # Do not reduce barrier time - See LU-11873
26648         do_facet mgs $LCTL barrier_freeze $FSNAME 20 ||
26649                 error "(4) fail to freeze barrier"
26650
26651         b_status=$(barrier_stat)
26652         [ "$b_status" = "'frozen'" ] ||
26653                 error "(5) unexpected barrier status $b_status"
26654
26655         echo "Start barrier_thaw at: $(date)"
26656         #define OBD_FAIL_BARRIER_DELAY          0x2202
26657         do_facet mgs $LCTL set_param fail_val=5 fail_loc=0x2202
26658         do_facet mgs $LCTL barrier_thaw $FSNAME &
26659
26660         sleep 2
26661         b_status=$(barrier_stat)
26662         echo "Got barrier status at: $(date)"
26663         [ "$b_status" = "'thawing'" ] ||
26664                 error "(6) unexpected barrier status $b_status"
26665
26666         do_facet mgs $LCTL set_param fail_val=0 fail_loc=0
26667         wait
26668         b_status=$(barrier_stat)
26669         [ "$b_status" = "'thawed'" ] ||
26670                 error "(7) unexpected barrier status $b_status"
26671
26672         #define OBD_FAIL_BARRIER_FAILURE        0x2203
26673         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2203
26674         do_facet mgs $LCTL barrier_freeze $FSNAME
26675
26676         b_status=$(barrier_stat)
26677         [ "$b_status" = "'failed'" ] ||
26678                 error "(8) unexpected barrier status $b_status"
26679
26680         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
26681         do_facet mgs $LCTL barrier_thaw $FSNAME
26682
26683         post_801
26684 }
26685 run_test 801a "write barrier user interfaces and stat machine"
26686
26687 test_801b() {
26688         prep_801
26689
26690         mkdir $DIR/$tdir || error "(1) fail to mkdir"
26691         createmany -d $DIR/$tdir/d 6 || error "(2) fail to mkdir"
26692         touch $DIR/$tdir/d2/f10 || error "(3) fail to touch"
26693         touch $DIR/$tdir/d3/f11 || error "(4) fail to touch"
26694         touch $DIR/$tdir/d4/f12 || error "(5) fail to touch"
26695
26696         cancel_lru_locks mdc
26697
26698         # 180 seconds should be long enough
26699         do_facet mgs $LCTL barrier_freeze $FSNAME 180
26700
26701         local b_status=$(barrier_stat)
26702         [ "$b_status" = "'frozen'" ] ||
26703                 error "(6) unexpected barrier status $b_status"
26704
26705         mkdir $DIR/$tdir/d0/d10 &
26706         mkdir_pid=$!
26707
26708         touch $DIR/$tdir/d1/f13 &
26709         touch_pid=$!
26710
26711         ln $DIR/$tdir/d2/f10 $DIR/$tdir/d2/f14 &
26712         ln_pid=$!
26713
26714         mv $DIR/$tdir/d3/f11 $DIR/$tdir/d3/f15 &
26715         mv_pid=$!
26716
26717         rm -f $DIR/$tdir/d4/f12 &
26718         rm_pid=$!
26719
26720         stat $DIR/$tdir/d5 || error "(7) stat should succeed"
26721
26722         # To guarantee taht the 'stat' is not blocked
26723         b_status=$(barrier_stat)
26724         [ "$b_status" = "'frozen'" ] ||
26725                 error "(8) unexpected barrier status $b_status"
26726
26727         # let above commands to run at background
26728         sleep 5
26729
26730         ps -p $mkdir_pid || error "(9) mkdir should be blocked"
26731         ps -p $touch_pid || error "(10) touch should be blocked"
26732         ps -p $ln_pid || error "(11) link should be blocked"
26733         ps -p $mv_pid || error "(12) rename should be blocked"
26734         ps -p $rm_pid || error "(13) unlink should be blocked"
26735
26736         b_status=$(barrier_stat)
26737         [ "$b_status" = "'frozen'" ] ||
26738                 error "(14) unexpected barrier status $b_status"
26739
26740         do_facet mgs $LCTL barrier_thaw $FSNAME
26741         b_status=$(barrier_stat)
26742         [ "$b_status" = "'thawed'" ] ||
26743                 error "(15) unexpected barrier status $b_status"
26744
26745         wait $mkdir_pid || error "(16) mkdir should succeed"
26746         wait $touch_pid || error "(17) touch should succeed"
26747         wait $ln_pid || error "(18) link should succeed"
26748         wait $mv_pid || error "(19) rename should succeed"
26749         wait $rm_pid || error "(20) unlink should succeed"
26750
26751         post_801
26752 }
26753 run_test 801b "modification will be blocked by write barrier"
26754
26755 test_801c() {
26756         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
26757
26758         prep_801
26759
26760         stop mds2 || error "(1) Fail to stop mds2"
26761
26762         do_facet mgs $LCTL barrier_freeze $FSNAME 30
26763
26764         local b_status=$(barrier_stat)
26765         [ "$b_status" = "'expired'" ] || [ "$b_status" = "'failed'" ] || {
26766                 do_facet mgs $LCTL barrier_thaw $FSNAME
26767                 error "(2) unexpected barrier status $b_status"
26768         }
26769
26770         do_facet mgs $LCTL barrier_rescan $FSNAME ||
26771                 error "(3) Fail to rescan barrier bitmap"
26772
26773         # Do not reduce barrier time - See LU-11873
26774         do_facet mgs $LCTL barrier_freeze $FSNAME 20
26775
26776         b_status=$(barrier_stat)
26777         [ "$b_status" = "'frozen'" ] ||
26778                 error "(4) unexpected barrier status $b_status"
26779
26780         do_facet mgs $LCTL barrier_thaw $FSNAME
26781         b_status=$(barrier_stat)
26782         [ "$b_status" = "'thawed'" ] ||
26783                 error "(5) unexpected barrier status $b_status"
26784
26785         local devname=$(mdsdevname 2)
26786
26787         start mds2 $devname $MDS_MOUNT_OPTS || error "(6) Fail to start mds2"
26788
26789         do_facet mgs $LCTL barrier_rescan $FSNAME ||
26790                 error "(7) Fail to rescan barrier bitmap"
26791
26792         post_801
26793 }
26794 run_test 801c "rescan barrier bitmap"
26795
26796 saved_MGS_MOUNT_OPTS=$MGS_MOUNT_OPTS
26797 saved_MDS_MOUNT_OPTS=$MDS_MOUNT_OPTS
26798 saved_OST_MOUNT_OPTS=$OST_MOUNT_OPTS
26799 saved_MOUNT_OPTS=$MOUNT_OPTS
26800
26801 cleanup_802a() {
26802         trap 0
26803
26804         stopall
26805         MGS_MOUNT_OPTS=$saved_MGS_MOUNT_OPTS
26806         MDS_MOUNT_OPTS=$saved_MDS_MOUNT_OPTS
26807         OST_MOUNT_OPTS=$saved_OST_MOUNT_OPTS
26808         MOUNT_OPTS=$saved_MOUNT_OPTS
26809         setupall
26810 }
26811
26812 test_802a() {
26813         [[ $mds1_FSTYPE = zfs ]] || skip "ZFS specific test"
26814         [[ $MDS1_VERSION -lt $(version_code 2.9.55) ]] ||
26815         [[ $OST1_VERSION -lt $(version_code 2.9.55) ]] &&
26816                 skip "Need server version at least 2.9.55"
26817
26818         [[ $ENABLE_QUOTA ]] && skip "Quota enabled for read-only test"
26819
26820         mkdir $DIR/$tdir || error "(1) fail to mkdir"
26821
26822         cp $LUSTRE/tests/test-framework.sh $DIR/$tdir/ ||
26823                 error "(2) Fail to copy"
26824
26825         trap cleanup_802a EXIT
26826
26827         # sync by force before remount as readonly
26828         sync; sync_all_data; sleep 3; sync_all_data
26829
26830         stopall
26831
26832         MGS_MOUNT_OPTS=$(csa_add "$MGS_MOUNT_OPTS" -o rdonly_dev)
26833         MDS_MOUNT_OPTS=$(csa_add "$MDS_MOUNT_OPTS" -o rdonly_dev)
26834         OST_MOUNT_OPTS=$(csa_add "$OST_MOUNT_OPTS" -o rdonly_dev)
26835
26836         echo "Mount the server as read only"
26837         setupall server_only || error "(3) Fail to start servers"
26838
26839         echo "Mount client without ro should fail"
26840         mount_client $MOUNT &&
26841                 error "(4) Mount client without 'ro' should fail"
26842
26843         echo "Mount client with ro should succeed"
26844         MOUNT_OPTS=$(csa_add "$MOUNT_OPTS" -o ro)
26845         mount_client $MOUNT ||
26846                 error "(5) Mount client with 'ro' should succeed"
26847
26848         echo "Modify should be refused"
26849         touch $DIR/$tdir/guard && error "(6) Touch should fail under ro mode"
26850
26851         echo "Read should be allowed"
26852         diff $LUSTRE/tests/test-framework.sh $DIR/$tdir/test-framework.sh ||
26853                 error "(7) Read should succeed under ro mode"
26854
26855         cleanup_802a
26856 }
26857 run_test 802a "simulate readonly device"
26858
26859 test_802b() {
26860         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26861         remote_mds_nodsh && skip "remote MDS with nodsh"
26862
26863         do_facet $SINGLEMDS $LCTL get_param mdt.*.readonly ||
26864                 skip "readonly option not available"
26865
26866         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "(1) fail to mkdir"
26867
26868         cp $LUSTRE/tests/test-framework.sh $DIR/$tdir/ ||
26869                 error "(2) Fail to copy"
26870
26871         # write back all cached data before setting MDT to readonly
26872         cancel_lru_locks
26873         sync_all_data
26874
26875         do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=1
26876         stack_trap "do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=0" EXIT
26877
26878         echo "Modify should be refused"
26879         touch $DIR/$tdir/guard && error "(6) Touch should fail under ro mode"
26880
26881         echo "Read should be allowed"
26882         diff $LUSTRE/tests/test-framework.sh $DIR/$tdir/test-framework.sh ||
26883                 error "(7) Read should succeed under ro mode"
26884
26885         # disable readonly
26886         do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=0
26887 }
26888 run_test 802b "be able to set MDTs to readonly"
26889
26890 test_803a() {
26891         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
26892         [ $MDS1_VERSION -lt $(version_code 2.10.54) ] &&
26893                 skip "MDS needs to be newer than 2.10.54"
26894
26895         mkdir_on_mdt0 $DIR/$tdir
26896         # Create some objects on all MDTs to trigger related logs objects
26897         for idx in $(seq $MDSCOUNT); do
26898                 $LFS mkdir -c $MDSCOUNT -i $((idx % $MDSCOUNT)) \
26899                         $DIR/$tdir/dir${idx} ||
26900                         error "Fail to create $DIR/$tdir/dir${idx}"
26901         done
26902
26903         sync; sleep 3
26904         wait_delete_completed # ensure old test cleanups are finished
26905         echo "before create:"
26906         $LFS df -i $MOUNT
26907         local before_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
26908
26909         for i in {1..10}; do
26910                 $LFS mkdir -c 1 -i 1 $DIR/$tdir/foo$i ||
26911                         error "Fail to create $DIR/$tdir/foo$i"
26912         done
26913
26914         sync; sleep 3
26915         echo "after create:"
26916         $LFS df -i $MOUNT
26917         local after_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
26918
26919         # allow for an llog to be cleaned up during the test
26920         [ $after_used -ge $((before_used + 10 - 1)) ] ||
26921                 error "before ($before_used) + 10 > after ($after_used)"
26922
26923         for i in {1..10}; do
26924                 rm -rf $DIR/$tdir/foo$i ||
26925                         error "Fail to remove $DIR/$tdir/foo$i"
26926         done
26927
26928         sleep 3 # avoid MDT return cached statfs
26929         wait_delete_completed
26930         echo "after unlink:"
26931         $LFS df -i $MOUNT
26932         after_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
26933
26934         # allow for an llog to be created during the test
26935         [ $after_used -le $((before_used + 1)) ] ||
26936                 error "after ($after_used) > before ($before_used) + 1"
26937 }
26938 run_test 803a "verify agent object for remote object"
26939
26940 test_803b() {
26941         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
26942         [ $MDS1_VERSION -lt $(version_code 2.13.56) ] &&
26943                 skip "MDS needs to be newer than 2.13.56"
26944         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26945
26946         for i in $(seq 0 $((MDSCOUNT - 1))); do
26947                 $LFS mkdir -i $i $DIR/$tdir.$i || error "mkdir $tdir.$i"
26948         done
26949
26950         local before=0
26951         local after=0
26952
26953         local tmp
26954
26955         stat $DIR/$tdir.* >/dev/null || error "stat $tdir.*"
26956         for i in $(seq 0 $((MDSCOUNT - 1))); do
26957                 tmp=$(do_facet mds$i $LCTL get_param mdt.*-MDT000$i.md_stats |
26958                         awk '/getattr/ { print $2 }')
26959                 before=$((before + tmp))
26960         done
26961         stat $DIR/$tdir.* >/dev/null || error "stat $tdir.*"
26962         for i in $(seq 0 $((MDSCOUNT - 1))); do
26963                 tmp=$(do_facet mds$i $LCTL get_param mdt.*-MDT000$i.md_stats |
26964                         awk '/getattr/ { print $2 }')
26965                 after=$((after + tmp))
26966         done
26967
26968         [ $before -eq $after ] || error "getattr count $before != $after"
26969 }
26970 run_test 803b "remote object can getattr from cache"
26971
26972 test_804() {
26973         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
26974         [ $MDS1_VERSION -lt $(version_code 2.10.54) ] &&
26975                 skip "MDS needs to be newer than 2.10.54"
26976         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
26977
26978         mkdir -p $DIR/$tdir
26979         $LFS mkdir -c 1 -i 1 $DIR/$tdir/dir0 ||
26980                 error "Fail to create $DIR/$tdir/dir0"
26981
26982         local fid=$($LFS path2fid $DIR/$tdir/dir0)
26983         local dev=$(mdsdevname 2)
26984
26985         do_facet mds2 "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
26986                 grep ${fid} || error "NOT found agent entry for dir0"
26987
26988         $LFS mkdir -c $MDSCOUNT -i 0 $DIR/$tdir/dir1 ||
26989                 error "Fail to create $DIR/$tdir/dir1"
26990
26991         touch $DIR/$tdir/dir1/foo0 ||
26992                 error "Fail to create $DIR/$tdir/dir1/foo0"
26993         fid=$($LFS path2fid $DIR/$tdir/dir1/foo0)
26994         local rc=0
26995
26996         for idx in $(seq $MDSCOUNT); do
26997                 dev=$(mdsdevname $idx)
26998                 do_facet mds${idx} \
26999                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
27000                         grep ${fid} && rc=$idx
27001         done
27002
27003         mv $DIR/$tdir/dir1/foo0 $DIR/$tdir/dir1/foo1 ||
27004                 error "Fail to rename foo0 to foo1"
27005         if [ $rc -eq 0 ]; then
27006                 for idx in $(seq $MDSCOUNT); do
27007                         dev=$(mdsdevname $idx)
27008                         do_facet mds${idx} \
27009                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
27010                         grep ${fid} && rc=$idx
27011                 done
27012         fi
27013
27014         mv $DIR/$tdir/dir1/foo1 $DIR/$tdir/dir1/foo2 ||
27015                 error "Fail to rename foo1 to foo2"
27016         if [ $rc -eq 0 ]; then
27017                 for idx in $(seq $MDSCOUNT); do
27018                         dev=$(mdsdevname $idx)
27019                         do_facet mds${idx} \
27020                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
27021                         grep ${fid} && rc=$idx
27022                 done
27023         fi
27024
27025         [ $rc -ne 0 ] || error "NOT found agent entry for foo"
27026
27027         ln $DIR/$tdir/dir1/foo2 $DIR/$tdir/dir0/guard ||
27028                 error "Fail to link to $DIR/$tdir/dir1/foo2"
27029         mv $DIR/$tdir/dir1/foo2 $DIR/$tdir/dir1/foo0 ||
27030                 error "Fail to rename foo2 to foo0"
27031         unlink $DIR/$tdir/dir1/foo0 ||
27032                 error "Fail to unlink $DIR/$tdir/dir1/foo0"
27033         rm -rf $DIR/$tdir/dir0 ||
27034                 error "Fail to rm $DIR/$tdir/dir0"
27035
27036         for idx in $(seq $MDSCOUNT); do
27037                 dev=$(mdsdevname $idx)
27038                 rc=0
27039
27040                 stop mds${idx}
27041                 run_e2fsck $(facet_active_host mds$idx) $dev -n ||
27042                         rc=$?
27043                 start mds${idx} $dev $MDS_MOUNT_OPTS ||
27044                         error "mount mds$idx failed"
27045                 df $MOUNT > /dev/null 2>&1
27046
27047                 # e2fsck should not return error
27048                 [ $rc -eq 0 ] ||
27049                         error "e2fsck detected error on MDT${idx}: rc=$rc"
27050         done
27051 }
27052 run_test 804 "verify agent entry for remote entry"
27053
27054 cleanup_805() {
27055         do_facet $SINGLEMDS zfs set quota=$old $fsset
27056         unlinkmany $DIR/$tdir/f- 1000000
27057         trap 0
27058 }
27059
27060 test_805() {
27061         local zfs_version=$(do_facet mds1 cat /sys/module/zfs/version)
27062         [ "$mds1_FSTYPE" != "zfs" ] && skip "ZFS specific test"
27063         [ $(version_code $zfs_version) -lt $(version_code 0.7.2) ] &&
27064                 skip "netfree not implemented before 0.7"
27065         [[ $MDS1_VERSION -ge $(version_code 2.10.57) ]] ||
27066                 skip "Need MDS version at least 2.10.57"
27067
27068         local fsset
27069         local freekb
27070         local usedkb
27071         local old
27072         local quota
27073         local pref="osd-zfs.$FSNAME-MDT0000."
27074
27075         # limit available space on MDS dataset to meet nospace issue
27076         # quickly. then ZFS 0.7.2 can use reserved space if asked
27077         # properly (using netfree flag in osd_declare_destroy()
27078         fsset=$(do_facet $SINGLEMDS lctl get_param -n $pref.mntdev)
27079         old=$(do_facet $SINGLEMDS zfs get -H quota $fsset | \
27080                 gawk '{print $3}')
27081         freekb=$(do_facet $SINGLEMDS lctl get_param -n $pref.kbytesfree)
27082         usedkb=$(do_facet $SINGLEMDS lctl get_param -n $pref.kbytestotal)
27083         let "usedkb=usedkb-freekb"
27084         let "freekb=freekb/2"
27085         if let "freekb > 5000"; then
27086                 let "freekb=5000"
27087         fi
27088         do_facet $SINGLEMDS zfs set quota=$(((usedkb+freekb)*1024)) $fsset
27089         trap cleanup_805 EXIT
27090         mkdir_on_mdt0 $DIR/$tdir
27091         $LFS setstripe -E 1M -c2 -E 4M -c2 -E -1 -c2 $DIR/$tdir ||
27092                 error "Can't set PFL layout"
27093         createmany -m $DIR/$tdir/f- 1000000 && error "ENOSPC wasn't met"
27094         rm -rf $DIR/$tdir || error "not able to remove"
27095         do_facet $SINGLEMDS zfs set quota=$old $fsset
27096         trap 0
27097 }
27098 run_test 805 "ZFS can remove from full fs"
27099
27100 # Size-on-MDS test
27101 check_lsom_data()
27102 {
27103         local file=$1
27104         local expect=$(stat -c %s $file)
27105
27106         check_lsom_size $1 $expect
27107
27108         local blocks=$($LFS getsom -b $file)
27109         expect=$(stat -c %b $file)
27110         [[ $blocks == $expect ]] ||
27111                 error "$file expected blocks: $expect, got: $blocks"
27112 }
27113
27114 check_lsom_size()
27115 {
27116         local size
27117         local expect=$2
27118
27119         cancel_lru_locks mdc
27120
27121         size=$($LFS getsom -s $1)
27122         [[ $size == $expect ]] ||
27123                 error "$file expected size: $expect, got: $size"
27124 }
27125
27126 test_806() {
27127         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
27128                 skip "Need MDS version at least 2.11.52"
27129
27130         local bs=1048576
27131
27132         touch $DIR/$tfile || error "touch $tfile failed"
27133
27134         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
27135         save_lustre_params client "llite.*.xattr_cache" > $save
27136         lctl set_param llite.*.xattr_cache=0
27137         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
27138
27139         # single-threaded write
27140         echo "Test SOM for single-threaded write"
27141         dd if=/dev/zero of=$DIR/$tfile bs=$bs count=1 ||
27142                 error "write $tfile failed"
27143         check_lsom_size $DIR/$tfile $bs
27144
27145         local num=32
27146         local size=$(($num * $bs))
27147         local offset=0
27148         local i
27149
27150         echo "Test SOM for single client multi-threaded($num) write"
27151         $TRUNCATE $DIR/$tfile 0
27152         for ((i = 0; i < $num; i++)); do
27153                 $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
27154                 local pids[$i]=$!
27155                 offset=$((offset + $bs))
27156         done
27157         for (( i=0; i < $num; i++ )); do
27158                 wait ${pids[$i]}
27159         done
27160         check_lsom_size $DIR/$tfile $size
27161
27162         $TRUNCATE $DIR/$tfile 0
27163         for ((i = 0; i < $num; i++)); do
27164                 offset=$((offset - $bs))
27165                 $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
27166                 local pids[$i]=$!
27167         done
27168         for (( i=0; i < $num; i++ )); do
27169                 wait ${pids[$i]}
27170         done
27171         check_lsom_size $DIR/$tfile $size
27172
27173         # multi-client writes
27174         num=$(get_node_count ${CLIENTS//,/ })
27175         size=$(($num * $bs))
27176         offset=0
27177         i=0
27178
27179         echo "Test SOM for multi-client ($num) writes"
27180         $TRUNCATE $DIR/$tfile 0
27181         for client in ${CLIENTS//,/ }; do
27182                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
27183                 local pids[$i]=$!
27184                 i=$((i + 1))
27185                 offset=$((offset + $bs))
27186         done
27187         for (( i=0; i < $num; i++ )); do
27188                 wait ${pids[$i]}
27189         done
27190         check_lsom_size $DIR/$tfile $offset
27191
27192         i=0
27193         $TRUNCATE $DIR/$tfile 0
27194         for client in ${CLIENTS//,/ }; do
27195                 offset=$((offset - $bs))
27196                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
27197                 local pids[$i]=$!
27198                 i=$((i + 1))
27199         done
27200         for (( i=0; i < $num; i++ )); do
27201                 wait ${pids[$i]}
27202         done
27203         check_lsom_size $DIR/$tfile $size
27204
27205         # verify truncate
27206         echo "Test SOM for truncate"
27207         $TRUNCATE $DIR/$tfile 1048576
27208         check_lsom_size $DIR/$tfile 1048576
27209         $TRUNCATE $DIR/$tfile 1234
27210         check_lsom_size $DIR/$tfile 1234
27211
27212         # verify SOM blocks count
27213         echo "Verify SOM block count"
27214         $TRUNCATE $DIR/$tfile 0
27215         $MULTIOP $DIR/$tfile oO_TRUNC:O_RDWR:w1048576YSc ||
27216                 error "failed to write file $tfile"
27217         check_lsom_data $DIR/$tfile
27218 }
27219 run_test 806 "Verify Lazy Size on MDS"
27220
27221 test_807() {
27222         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
27223         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
27224                 skip "Need MDS version at least 2.11.52"
27225
27226         # Registration step
27227         changelog_register || error "changelog_register failed"
27228         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
27229         changelog_users $SINGLEMDS | grep -q $cl_user ||
27230                 error "User $cl_user not found in changelog_users"
27231
27232         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
27233         save_lustre_params client "llite.*.xattr_cache" > $save
27234         lctl set_param llite.*.xattr_cache=0
27235         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
27236
27237         rm -rf $DIR/$tdir || error "rm $tdir failed"
27238         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
27239         touch $DIR/$tdir/trunc || error "touch $tdir/trunc failed"
27240         $TRUNCATE $DIR/$tdir/trunc 1024 || error "truncate $tdir/trunc failed"
27241         $TRUNCATE $DIR/$tdir/trunc 1048576 ||
27242                 error "truncate $tdir/trunc failed"
27243
27244         local bs=1048576
27245         dd if=/dev/zero of=$DIR/$tdir/single_dd bs=$bs count=1 conv=fsync ||
27246                 error "write $tfile failed"
27247
27248         # multi-client wirtes
27249         local num=$(get_node_count ${CLIENTS//,/ })
27250         local offset=0
27251         local i=0
27252
27253         echo "Test SOM for multi-client ($num) writes"
27254         touch $DIR/$tfile || error "touch $tfile failed"
27255         $TRUNCATE $DIR/$tfile 0
27256         for client in ${CLIENTS//,/ }; do
27257                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
27258                 local pids[$i]=$!
27259                 i=$((i + 1))
27260                 offset=$((offset + $bs))
27261         done
27262         for (( i=0; i < $num; i++ )); do
27263                 wait ${pids[$i]}
27264         done
27265
27266         do_rpc_nodes "$CLIENTS" cancel_lru_locks osc
27267         do_nodes "$CLIENTS" "sync ; sleep 5 ; sync"
27268         $LSOM_SYNC -u $cl_user -m $FSNAME-MDT0000 $MOUNT
27269         check_lsom_data $DIR/$tdir/trunc
27270         check_lsom_data $DIR/$tdir/single_dd
27271         check_lsom_data $DIR/$tfile
27272
27273         rm -rf $DIR/$tdir
27274         # Deregistration step
27275         changelog_deregister || error "changelog_deregister failed"
27276 }
27277 run_test 807 "verify LSOM syncing tool"
27278
27279 check_som_nologged()
27280 {
27281         local lines=$($LFS changelog $FSNAME-MDT0000 |
27282                 grep 'x=trusted.som' | wc -l)
27283         [ $lines -ne 0 ] && error "trusted.som xattr is logged in Changelogs"
27284 }
27285
27286 test_808() {
27287         [ $MDS1_VERSION -lt $(version_code 2.11.55) ] &&
27288                 skip "Need MDS version at least 2.11.55"
27289
27290         # Registration step
27291         changelog_register || error "changelog_register failed"
27292
27293         touch $DIR/$tfile || error "touch $tfile failed"
27294         check_som_nologged
27295
27296         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=1 ||
27297                 error "write $tfile failed"
27298         check_som_nologged
27299
27300         $TRUNCATE $DIR/$tfile 1234
27301         check_som_nologged
27302
27303         $TRUNCATE $DIR/$tfile 1048576
27304         check_som_nologged
27305
27306         # Deregistration step
27307         changelog_deregister || error "changelog_deregister failed"
27308 }
27309 run_test 808 "Check trusted.som xattr not logged in Changelogs"
27310
27311 check_som_nodata()
27312 {
27313         $LFS getsom $1
27314         [[ $? -eq 61 ]] || error "DoM-only file $1 has SOM xattr"
27315 }
27316
27317 test_809() {
27318         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
27319                 skip "Need MDS version at least 2.11.56"
27320
27321         $LFS setstripe -E 1M -L mdt $DIR/$tfile ||
27322                 error "failed to create DoM-only file $DIR/$tfile"
27323         touch $DIR/$tfile || error "touch $tfile failed"
27324         check_som_nodata $DIR/$tfile
27325
27326         dd if=/dev/zero of=$DIR/$tfile bs=2048 count=1 ||
27327                 error "write $tfile failed"
27328         check_som_nodata $DIR/$tfile
27329
27330         $TRUNCATE $DIR/$tfile 1234
27331         check_som_nodata $DIR/$tfile
27332
27333         $TRUNCATE $DIR/$tfile 4097
27334         check_som_nodata $DIR/$file
27335 }
27336 run_test 809 "Verify no SOM xattr store for DoM-only files"
27337
27338 test_810() {
27339         [ $PARALLEL == "yes" ] && skip "skip parallel run"
27340         $GSS && skip_env "could not run with gss"
27341         [[ $OST1_VERSION -gt $(version_code 2.12.58) ]] ||
27342                 skip "OST < 2.12.58 doesn't align checksum"
27343
27344         set_checksums 1
27345         stack_trap "set_checksums $ORIG_CSUM" EXIT
27346         stack_trap "set_checksum_type $ORIG_CSUM_TYPE" EXIT
27347
27348         local csum
27349         local before
27350         local after
27351         for csum in $CKSUM_TYPES; do
27352                 #define OBD_FAIL_OSC_NO_GRANT   0x411
27353                 $LCTL set_param osc.*.checksum_type=$csum fail_loc=0x411
27354                 for i in "10240 0" "10000 0" "4000 1" "500 1"; do
27355                         eval set -- $i
27356                         dd if=/dev/urandom of=$DIR/$tfile bs=$1 count=2 seek=$2
27357                         before=$(md5sum $DIR/$tfile)
27358                         $LCTL set_param ldlm.namespaces.*osc*.lru_size=clear
27359                         after=$(md5sum $DIR/$tfile)
27360                         [ "$before" == "$after" ] ||
27361                                 error "$csum: $before != $after bs=$1 seek=$2"
27362                 done
27363         done
27364 }
27365 run_test 810 "partial page writes on ZFS (LU-11663)"
27366
27367 test_812a() {
27368         [ $OST1_VERSION -lt $(version_code 2.12.51) ] &&
27369                 skip "OST < 2.12.51 doesn't support this fail_loc"
27370
27371         $LFS setstripe -c 1 -i 0 $DIR/$tfile
27372         # ensure ost1 is connected
27373         stat $DIR/$tfile >/dev/null || error "can't stat"
27374         wait_osc_import_state client ost1 FULL
27375         # no locks, no reqs to let the connection idle
27376         cancel_lru_locks osc
27377
27378         # delay OST_DISCONNECT on OST1 to put OSC into intermediate state
27379 #define OBD_FAIL_OST_DISCONNECT_DELAY    0x245
27380         do_facet ost1 "$LCTL set_param fail_loc=0x245 fail_val=8"
27381         wait_osc_import_state client ost1 CONNECTING
27382         do_facet ost1 "$LCTL set_param fail_loc=0 fail_val=0"
27383
27384         stat $DIR/$tfile >/dev/null || error "can't stat file"
27385 }
27386 run_test 812a "do not drop reqs generated when imp is going to idle (LU-11951)"
27387
27388 test_812b() { # LU-12378
27389         [ $OST1_VERSION -lt $(version_code 2.12.51) ] &&
27390                 skip "OST < 2.12.51 doesn't support this fail_loc"
27391
27392         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "setstripe failed"
27393         # ensure ost1 is connected
27394         stat $DIR/$tfile >/dev/null || error "can't stat"
27395         wait_osc_import_state client ost1 FULL
27396         # no locks, no reqs to let the connection idle
27397         cancel_lru_locks osc
27398
27399         # delay OST_DISCONNECT on OST1 to put OSC into intermediate state
27400 #define OBD_FAIL_OST_DISCONNECT_DELAY    0x245
27401         do_facet ost1 "$LCTL set_param fail_loc=0x245 fail_val=8"
27402         wait_osc_import_state client ost1 CONNECTING
27403         do_facet ost1 "$LCTL set_param fail_loc=0 fail_val=0"
27404
27405         $LFS quota -u 0 $DIR/ || error "lfs quota should succeed"
27406         wait_osc_import_state client ost1 IDLE
27407 }
27408 run_test 812b "do not drop no resend request for idle connect"
27409
27410 test_812c() {
27411         local old
27412
27413         old=$($LCTL get_param -n osc.*.idle_timeout | head -n 1)
27414
27415         $LFS setstripe -c 1 -o 0 $DIR/$tfile
27416         $LFS getstripe $DIR/$tfile
27417         $LCTL set_param osc.*.idle_timeout=10
27418         stack_trap "$LCTL set_param osc.*.idle_timeout=$old" EXIT
27419         # ensure ost1 is connected
27420         stat $DIR/$tfile >/dev/null || error "can't stat"
27421         wait_osc_import_state client ost1 FULL
27422         # no locks, no reqs to let the connection idle
27423         cancel_lru_locks osc
27424
27425 #define OBD_FAIL_PTLRPC_IDLE_RACE        0x533
27426         $LCTL set_param fail_loc=0x80000533
27427         sleep 15
27428         dd if=/dev/zero of=$DIR/$tfile count=1 conv=sync || error "dd failed"
27429 }
27430 run_test 812c "idle import vs lock enqueue race"
27431
27432 test_813() {
27433         local file_heat_sav=$($LCTL get_param -n llite.*.file_heat 2>/dev/null)
27434         [ -z "$file_heat_sav" ] && skip "no file heat support"
27435
27436         local readsample
27437         local writesample
27438         local readbyte
27439         local writebyte
27440         local readsample1
27441         local writesample1
27442         local readbyte1
27443         local writebyte1
27444
27445         local period_second=$($LCTL get_param -n llite.*.heat_period_second)
27446         local decay_pct=$($LCTL get_param -n llite.*.heat_decay_percentage)
27447
27448         $LCTL set_param -n llite.*.file_heat=1
27449         echo "Turn on file heat"
27450         echo "Period second: $period_second, Decay percentage: $decay_pct"
27451
27452         echo "QQQQ" > $DIR/$tfile
27453         echo "QQQQ" > $DIR/$tfile
27454         echo "QQQQ" > $DIR/$tfile
27455         cat $DIR/$tfile > /dev/null
27456         cat $DIR/$tfile > /dev/null
27457         cat $DIR/$tfile > /dev/null
27458         cat $DIR/$tfile > /dev/null
27459
27460         local out=$($LFS heat_get $DIR/$tfile)
27461
27462         $LFS heat_get $DIR/$tfile
27463         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
27464         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
27465         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
27466         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
27467
27468         [ $readsample -le 4 ] || error "read sample ($readsample) is wrong"
27469         [ $writesample -le 3 ] || error "write sample ($writesample) is wrong"
27470         [ $readbyte -le 20 ] || error "read bytes ($readbyte) is wrong"
27471         [ $writebyte -le 15 ] || error "write bytes ($writebyte) is wrong"
27472
27473         sleep $((period_second + 3))
27474         echo "Sleep $((period_second + 3)) seconds..."
27475         # The recursion formula to calculate the heat of the file f is as
27476         # follow:
27477         # Hi+1(f) = (1-P)*Hi(f)+ P*Ci
27478         # Where Hi is the heat value in the period between time points i*I and
27479         # (i+1)*I; Ci is the access count in the period; the symbol P refers
27480         # to the weight of Ci.
27481         out=$($LFS heat_get $DIR/$tfile)
27482         $LFS heat_get $DIR/$tfile
27483         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
27484         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
27485         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
27486         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
27487
27488         [ $(bc <<< "$readsample <= 4 * $decay_pct / 100") -eq 1 ] ||
27489                 error "read sample ($readsample) is wrong"
27490         [ $(bc <<< "$writesample <= 3 * $decay_pct / 100") -eq 1 ] ||
27491                 error "write sample ($writesample) is wrong"
27492         [ $(bc <<< "$readbyte <= 20 * $decay_pct / 100") -eq 1 ] ||
27493                 error "read bytes ($readbyte) is wrong"
27494         [ $(bc <<< "$writebyte <= 15 * $decay_pct / 100") -eq 1 ] ||
27495                 error "write bytes ($writebyte) is wrong"
27496
27497         echo "QQQQ" > $DIR/$tfile
27498         echo "QQQQ" > $DIR/$tfile
27499         echo "QQQQ" > $DIR/$tfile
27500         cat $DIR/$tfile > /dev/null
27501         cat $DIR/$tfile > /dev/null
27502         cat $DIR/$tfile > /dev/null
27503         cat $DIR/$tfile > /dev/null
27504
27505         sleep $((period_second + 3))
27506         echo "Sleep $((period_second + 3)) seconds..."
27507
27508         out=$($LFS heat_get $DIR/$tfile)
27509         $LFS heat_get $DIR/$tfile
27510         readsample1=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
27511         writesample1=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
27512         readbyte1=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
27513         writebyte1=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
27514
27515         [ $(bc <<< "$readsample1 <= ($readsample * (100 - $decay_pct) + \
27516                 4 * $decay_pct) / 100") -eq 1 ] ||
27517                 error "read sample ($readsample1) is wrong"
27518         [ $(bc <<< "$writesample1 <= ($writesample * (100 - $decay_pct) + \
27519                 3 * $decay_pct) / 100") -eq 1 ] ||
27520                 error "write sample ($writesample1) is wrong"
27521         [ $(bc <<< "$readbyte1 <= ($readbyte * (100 - $decay_pct) + \
27522                 20 * $decay_pct) / 100") -eq 1 ] ||
27523                 error "read bytes ($readbyte1) is wrong"
27524         [ $(bc <<< "$writebyte1 <= ($writebyte * (100 - $decay_pct) + \
27525                 15 * $decay_pct) / 100") -eq 1 ] ||
27526                 error "write bytes ($writebyte1) is wrong"
27527
27528         echo "Turn off file heat for the file $DIR/$tfile"
27529         $LFS heat_set -o $DIR/$tfile
27530
27531         echo "QQQQ" > $DIR/$tfile
27532         echo "QQQQ" > $DIR/$tfile
27533         echo "QQQQ" > $DIR/$tfile
27534         cat $DIR/$tfile > /dev/null
27535         cat $DIR/$tfile > /dev/null
27536         cat $DIR/$tfile > /dev/null
27537         cat $DIR/$tfile > /dev/null
27538
27539         out=$($LFS heat_get $DIR/$tfile)
27540         $LFS heat_get $DIR/$tfile
27541         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
27542         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
27543         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
27544         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
27545
27546         [ $readsample -eq 0 ] || error "read sample ($readsample) is wrong"
27547         [ $writesample -eq 0 ] || error "write sample ($writesample) is wrong"
27548         [ $readbyte -eq 0 ] || error "read bytes ($readbyte) is wrong"
27549         [ $writebyte -eq 0 ] || error "write bytes ($writebyte) is wrong"
27550
27551         echo "Trun on file heat for the file $DIR/$tfile"
27552         $LFS heat_set -O $DIR/$tfile
27553
27554         echo "QQQQ" > $DIR/$tfile
27555         echo "QQQQ" > $DIR/$tfile
27556         echo "QQQQ" > $DIR/$tfile
27557         cat $DIR/$tfile > /dev/null
27558         cat $DIR/$tfile > /dev/null
27559         cat $DIR/$tfile > /dev/null
27560         cat $DIR/$tfile > /dev/null
27561
27562         out=$($LFS heat_get $DIR/$tfile)
27563         $LFS heat_get $DIR/$tfile
27564         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
27565         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
27566         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
27567         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
27568
27569         [ $readsample -gt 0 ] || error "read sample ($readsample) is wrong"
27570         [ $writesample -gt 0 ] || error "write sample ($writesample) is wrong"
27571         [ $readbyte -gt 0 ] || error "read bytes ($readbyte) is wrong"
27572         [ $writebyte -gt 0 ] || error "write bytes ($writebyte) is wrong"
27573
27574         $LFS heat_set -c $DIR/$tfile
27575         $LCTL set_param -n llite.*.file_heat=0
27576         echo "Turn off file heat support for the Lustre filesystem"
27577
27578         echo "QQQQ" > $DIR/$tfile
27579         echo "QQQQ" > $DIR/$tfile
27580         echo "QQQQ" > $DIR/$tfile
27581         cat $DIR/$tfile > /dev/null
27582         cat $DIR/$tfile > /dev/null
27583         cat $DIR/$tfile > /dev/null
27584         cat $DIR/$tfile > /dev/null
27585
27586         out=$($LFS heat_get $DIR/$tfile)
27587         $LFS heat_get $DIR/$tfile
27588         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
27589         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
27590         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
27591         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
27592
27593         [ $readsample -eq 0 ] || error "read sample ($readsample) is wrong"
27594         [ $writesample -eq 0 ] || error "write sample ($writesample) is wrong"
27595         [ $readbyte -eq 0 ] || error "read bytes ($readbyte) is wrong"
27596         [ $writebyte -eq 0 ] || error "write bytes ($writebyte) is wrong"
27597
27598         $LCTL set_param -n llite.*.file_heat=$file_heat_sav
27599         rm -f $DIR/$tfile
27600 }
27601 run_test 813 "File heat verfication"
27602
27603 test_814()
27604 {
27605         dd of=$DIR/$tfile seek=128 bs=1k < /dev/null
27606         echo -n y >> $DIR/$tfile
27607         cp --sparse=always $DIR/$tfile $DIR/${tfile}.cp || error "copy failed"
27608         diff $DIR/$tfile $DIR/${tfile}.cp || error "files should be same"
27609 }
27610 run_test 814 "sparse cp works as expected (LU-12361)"
27611
27612 test_815()
27613 {
27614         writeme -b 100 $DIR/$tfile || error "write 100 bytes failed"
27615         writeme -b 0 $DIR/$tfile || error "write 0 byte failed"
27616 }
27617 run_test 815 "zero byte tiny write doesn't hang (LU-12382)"
27618
27619 test_816() {
27620         local ost1_imp=$(get_osc_import_name client ost1)
27621         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
27622                          cut -d'.' -f2)
27623
27624         $LFS setstripe -c 1 -i 0 $DIR/$tfile
27625         # ensure ost1 is connected
27626
27627         stat $DIR/$tfile >/dev/null || error "can't stat"
27628         wait_osc_import_state client ost1 FULL
27629         # no locks, no reqs to let the connection idle
27630         cancel_lru_locks osc
27631         lru_resize_disable osc
27632         local before
27633         local now
27634         before=$($LCTL get_param -n \
27635                  ldlm.namespaces.$imp_name.lru_size)
27636
27637         wait_osc_import_state client ost1 IDLE
27638         dd if=/dev/null of=$DIR/$tfile bs=1k count=1 conv=sync
27639         now=$($LCTL get_param -n \
27640               ldlm.namespaces.$imp_name.lru_size)
27641         [ $before == $now ] || error "lru_size changed $before != $now"
27642 }
27643 run_test 816 "do not reset lru_resize on idle reconnect"
27644
27645 cleanup_817() {
27646         umount $tmpdir
27647         exportfs -u localhost:$DIR/nfsexp
27648         rm -rf $DIR/nfsexp
27649 }
27650
27651 test_817() {
27652         systemctl restart nfs-server.service || skip "failed to restart nfsd"
27653
27654         mkdir -p $DIR/nfsexp
27655         exportfs -orw,no_root_squash localhost:$DIR/nfsexp ||
27656                 error "failed to export nfs"
27657
27658         tmpdir=$(mktemp -d /tmp/nfs-XXXXXX)
27659         stack_trap cleanup_817 EXIT
27660
27661         mount -t nfs -orw localhost:$DIR/nfsexp $tmpdir ||
27662                 error "failed to mount nfs to $tmpdir"
27663
27664         cp /bin/true $tmpdir
27665         $DIR/nfsexp/true || error "failed to execute 'true' command"
27666 }
27667 run_test 817 "nfsd won't cache write lock for exec file"
27668
27669 test_818() {
27670         test_mkdir -i0 -c1 $DIR/$tdir
27671         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
27672         $LFS setstripe -c1 -i1 $DIR/$tdir/$tfile
27673         stop $SINGLEMDS
27674
27675         # restore osp-syn threads
27676         stack_trap "fail $SINGLEMDS"
27677
27678         #define OBD_FAIL_OSP_CANT_PROCESS_LLOG          0x2105
27679         do_facet $SINGLEMDS lctl set_param fail_loc=0x80002105
27680         start $SINGLEMDS $(mdsdevname ${SINGLEMDS//mds/}) $MDS_MOUNT_OPTS ||
27681                 error "start $SINGLEMDS failed"
27682         rm -rf $DIR/$tdir
27683
27684         local testid=$(echo $TESTNAME | tr '_' ' ')
27685
27686         do_facet mds1 dmesg | tac | sed "/$testid/,$ d" |
27687                 grep "run LFSCK" || error "run LFSCK is not suggested"
27688 }
27689 run_test 818 "unlink with failed llog"
27690
27691 test_819a() {
27692         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
27693         cancel_lru_locks osc
27694         #define OBD_FAIL_OST_2BIG_NIOBUF                0x248
27695         do_facet $SINGLEMDS lctl set_param fail_loc=0x80000248
27696         dd if=$DIR/$tfile of=/dev/null bs=1M count=1
27697         rm -f $TDIR/$tfile
27698 }
27699 run_test 819a "too big niobuf in read"
27700
27701 test_819b() {
27702         #define OBD_FAIL_OST_2BIG_NIOBUF                0x248
27703         do_facet $SINGLEMDS lctl set_param fail_loc=0x80000248
27704         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
27705         cancel_lru_locks osc
27706         sleep 1
27707         rm -f $TDIR/$tfile
27708 }
27709 run_test 819b "too big niobuf in write"
27710
27711
27712 function test_820_start_ost() {
27713         sleep 5
27714
27715         for num in $(seq $OSTCOUNT); do
27716                 start ost$num $(ostdevname $num) $OST_MOUNT_OPTS
27717         done
27718 }
27719
27720 test_820() {
27721         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
27722
27723         mkdir $DIR/$tdir
27724         umount_client $MOUNT || error "umount failed"
27725         for num in $(seq $OSTCOUNT); do
27726                 stop ost$num
27727         done
27728
27729         # mount client with no active OSTs
27730         # so that the client can't initialize max LOV EA size
27731         # from OSC notifications
27732         mount_client $MOUNT || error "mount failed"
27733         # delay OST starting to keep this 0 max EA size for a while
27734         test_820_start_ost &
27735
27736         # create a directory on MDS2
27737         test_mkdir -i 1 -c1 $DIR/$tdir/mds2 ||
27738                 error "Failed to create directory"
27739         # open intent should update default EA size
27740         # see mdc_update_max_ea_from_body()
27741         # notice this is the very first RPC to MDS2
27742         out=$(cp /etc/services $DIR/$tdir/mds2 2>&1)
27743         ret=$?
27744         echo $out
27745         # With SSK, this situation can lead to -EPERM being returned.
27746         # In that case, simply retry.
27747         if [ $ret -ne 0 ] && $SHARED_KEY; then
27748                 if echo "$out" | grep -q "not permitted"; then
27749                         cp /etc/services $DIR/$tdir/mds2
27750                         ret=$?
27751                 fi
27752         fi
27753         [ $ret -eq 0 ] || error "Failed to copy files to mds$n"
27754 }
27755 run_test 820 "update max EA from open intent"
27756
27757 test_822() {
27758         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
27759
27760         save_lustre_params mds1 \
27761                 "osp.$FSNAME-OST*-osc-MDT0000.max_create_count" > $p
27762         do_facet $SINGLEMDS "$LCTL set_param -n \
27763                         osp.$FSNAME-OST*MDT0000.max_create_count=0"
27764         do_facet $SINGLEMDS "$LCTL set_param -n \
27765                         osp.$FSNAME-OST0000*MDT0000.max_create_count=20000"
27766
27767         # wait for statfs update to clear OS_STATFS_NOPRECREATE
27768         local maxage=$(do_facet mds1 $LCTL get_param -n \
27769                        osp.$FSNAME-OST0000*MDT0000.maxage)
27770         sleep $((maxage + 1))
27771
27772         #define OBD_FAIL_NET_ERROR_RPC          0x532
27773         do_facet mds1 "$LCTL set_param fail_loc=0x80000532 fail_val=5"
27774
27775         stack_trap "restore_lustre_params < $p; rm $p"
27776
27777         local count=$(do_facet $SINGLEMDS "lctl get_param -n \
27778                       osp.$FSNAME-OST0000*MDT0000.create_count")
27779         for i in $(seq 1 $count); do
27780                 touch $DIR/$tfile.${i} || error "touch failed"
27781         done
27782 }
27783 run_test 822 "test precreate failure"
27784
27785 test_823() {
27786         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
27787         local OST_MAX_PRECREATE=20000
27788
27789         save_lustre_params mds1 \
27790                 "osp.$FSNAME-OST*-osc-MDT0000.max_create_count" > $p
27791         do_facet $SINGLEMDS "$LCTL set_param -n \
27792                 osp.$FSNAME-OST*MDT0000.max_create_count=0"
27793         do_facet $SINGLEMDS "$LCTL set_param -n \
27794                 osp.$FSNAME-OST0000*MDT0000.max_create_count=$OST_MAX_PRECREATE"
27795
27796         stack_trap "restore_lustre_params < $p; rm $p"
27797
27798         do_facet $SINGLEMDS "$LCTL set_param -n \
27799                 osp.$FSNAME-OST*-osc-MDT*.create_count=100200"
27800
27801         local count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
27802                       osp.$FSNAME-OST0000*MDT0000.create_count")
27803         local max=$(do_facet $SINGLEMDS "$LCTL get_param -n \
27804                     osp.$FSNAME-OST0000*MDT0000.max_create_count")
27805         local expect_count=$(((($max/2)/256) * 256))
27806
27807         log "setting create_count to 100200:"
27808         log " -result- count: $count with max: $max, expecting: $expect_count"
27809
27810         [[ $count -eq expect_count ]] ||
27811                 error "Create count not set to max precreate."
27812 }
27813 run_test 823 "Setting create_count > OST_MAX_PRECREATE is lowered to maximum"
27814
27815 test_831() {
27816         local sync_changes=$(do_facet $SINGLEMDS \
27817                 $LCTL get_param -n osp.$FSNAME-OST0000-osc-MDT0000.sync_changes)
27818
27819         [ "$sync_changes" -gt 100 ] &&
27820                 skip "Sync changes $sync_changes > 100 already"
27821
27822         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
27823
27824         $LFS mkdir -i 0 $DIR/$tdir
27825         $LFS setstripe -c 1 -i 0 $DIR/$tdir
27826
27827         save_lustre_params mds1 \
27828                 "osp.$FSNAME-OST*-osc-MDT0000.max_sync_changes" > $p
27829         save_lustre_params mds1 \
27830                 "osp.$FSNAME-OST*-osc-MDT0000.max_rpcs_in_progress" >> $p
27831
27832         do_facet mds1 "$LCTL set_param -n \
27833                 osp.$FSNAME-OST*-osc-MDT0000.max_sync_changes=100 \
27834                 osp.$FSNAME-OST*-osc-MDT0000.max_rpcs_in_progress=128"
27835         stack_trap "restore_lustre_params < $p" EXIT
27836
27837         createmany -o $DIR/$tdir/f- 1000
27838         unlinkmany $DIR/$tdir/f- 1000 &
27839         local UNLINK_PID=$!
27840
27841         while sleep 1; do
27842                 sync_changes=$(do_facet mds1 \
27843                 $LCTL get_param -n osp.$FSNAME-OST0000-osc-MDT0000.sync_changes)
27844                 # the check in the code is racy, fail the test
27845                 # if the value above the limit by 10.
27846                 [ $sync_changes -gt 110 ] && {
27847                         kill -2 $UNLINK_PID
27848                         wait
27849                         error "osp changes throttling failed, $sync_changes>110"
27850                 }
27851                 kill -0 $UNLINK_PID 2> /dev/null || break
27852         done
27853         wait
27854 }
27855 run_test 831 "throttling unlink/setattr queuing on OSP"
27856
27857 #
27858 # tests that do cleanup/setup should be run at the end
27859 #
27860
27861 test_900() {
27862         [ $PARALLEL == "yes" ] && skip "skip parallel run"
27863         local ls
27864
27865         #define OBD_FAIL_MGC_PAUSE_PROCESS_LOG   0x903
27866         $LCTL set_param fail_loc=0x903
27867
27868         cancel_lru_locks MGC
27869
27870         FAIL_ON_ERROR=true cleanup
27871         FAIL_ON_ERROR=true setup
27872 }
27873 run_test 900 "umount should not race with any mgc requeue thread"
27874
27875 # LUS-6253/LU-11185
27876 test_901() {
27877         local oldc
27878         local newc
27879         local olds
27880         local news
27881         [ $PARALLEL == "yes" ] && skip "skip parallel run"
27882
27883         # some get_param have a bug to handle dot in param name
27884         cancel_lru_locks MGC
27885         oldc=$($LCTL get_param -n 'ldlm.namespaces.MGC*.lock_count')
27886         olds=$(do_facet mgs $LCTL get_param -n 'ldlm.namespaces.MGS*.lock_count')
27887         umount_client $MOUNT || error "umount failed"
27888         mount_client $MOUNT || error "mount failed"
27889         cancel_lru_locks MGC
27890         newc=$($LCTL get_param -n 'ldlm.namespaces.MGC*.lock_count')
27891         news=$(do_facet mgs $LCTL get_param -n 'ldlm.namespaces.MGS*.lock_count')
27892
27893         [ $oldc -lt $newc ] && error "mgc lock leak ($oldc != $newc)"
27894         [ $olds -lt $news ] && error "mgs lock leak ($olds != $news)"
27895
27896         return 0
27897 }
27898 run_test 901 "don't leak a mgc lock on client umount"
27899
27900 # LU-13377
27901 test_902() {
27902         [ $CLIENT_VERSION -lt $(version_code 2.13.52) ] &&
27903                 skip "client does not have LU-13377 fix"
27904         #define OBD_FAIL_LLITE_SHORT_COMMIT 0x1415
27905         $LCTL set_param fail_loc=0x1415
27906         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
27907         cancel_lru_locks osc
27908         rm -f $DIR/$tfile
27909 }
27910 run_test 902 "test short write doesn't hang lustre"
27911
27912 # LU-14711
27913 test_903() {
27914         $LFS setstripe -i 0 -c 1 $DIR/$tfile $DIR/${tfile}-2
27915         echo "blah" > $DIR/${tfile}-2
27916         dd if=/dev/zero of=$DIR/$tfile bs=1M count=6 conv=fsync
27917         #define OBD_FAIL_OSC_SLOW_PAGE_EVICT 0x417
27918         $LCTL set_param fail_loc=0x417 fail_val=20
27919
27920         mv $DIR/${tfile}-2 $DIR/$tfile # Destroys the big object
27921         sleep 1 # To start the destroy
27922         wait_destroy_complete 150 || error "Destroy taking too long"
27923         cat $DIR/$tfile > /dev/null || error "Evicted"
27924 }
27925 run_test 903 "Test long page discard does not cause evictions"
27926
27927 test_904() {
27928         [ "$mds1_FSTYPE" == "ldiskfs" ] || skip "ldiskfs only test"
27929         do_facet mds1 $DEBUGFS -R features $(mdsdevname 1) |
27930                 grep -q project || skip "skip project quota not supported"
27931
27932         local testfile="$DIR/$tdir/$tfile"
27933         local xattr="trusted.projid"
27934         local projid
27935
27936         mkdir -p $DIR/$tdir
27937         touch $testfile
27938         #should be hidden when projid is 0
27939         $LFS project -p 0 $testfile ||
27940                 error "set $testfile project id failed"
27941         getfattr -m - $testfile | grep $xattr &&
27942                 error "do not show trusted.projid with project ID 0"
27943
27944         #still can getxattr explicitly
27945         projid=$(getfattr -n $xattr $testfile |
27946                 sed -n 's/^trusted\.projid="\(.*\)"/\1/p')
27947         [ $projid == "0" ] ||
27948                 error "projid expected 0 not $projid"
27949
27950         #set the projid via setxattr
27951         setfattr -n $xattr -v "1000" $testfile ||
27952                 error "setattr failed with $?"
27953         projid=($($LFS project $testfile))
27954         [ ${projid[0]} == "1000" ] ||
27955                 error "projid expected 1000 not $projid"
27956
27957         #check the new projid via getxattr
27958         $LFS project -p 1001 $testfile ||
27959                 error "set $testfile project id failed"
27960         projid=$(getfattr -n $xattr $testfile |
27961                 sed -n 's/^trusted\.projid="\(.*\)"/\1/p')
27962         [ $projid == "1001" ] ||
27963                 error "projid expected 1001 not $projid"
27964
27965         #try to set invalid projid
27966         setfattr -n $xattr -v "4294967295" $testfile &&
27967                 error "set invalid projid should fail"
27968
27969         #remove the xattr means setting projid to 0
27970         setfattr -x $xattr $testfile ||
27971                 error "setfattr failed with $?"
27972         projid=($($LFS project $testfile))
27973         [ ${projid[0]} == "0" ] ||
27974                 error "projid expected 0 not $projid"
27975
27976         #should be hidden when parent has inherit flag and same projid
27977         $LFS project -srp 1002 $DIR/$tdir ||
27978                 error "set $tdir project id failed"
27979         getfattr -m - $testfile | grep $xattr &&
27980                 error "do not show trusted.projid with inherit flag"
27981
27982         #still can getxattr explicitly
27983         projid=$(getfattr -n $xattr $testfile |
27984                 sed -n 's/^trusted\.projid="\(.*\)"/\1/p')
27985         [ $projid == "1002" ] ||
27986                 error "projid expected 1002 not $projid"
27987 }
27988 run_test 904 "virtual project ID xattr"
27989
27990 complete $SECONDS
27991 [ -f $EXT2_DEV ] && rm $EXT2_DEV || true
27992 check_and_cleanup_lustre
27993 if [ "$I_MOUNTED" != "yes" ]; then
27994         lctl set_param debug="$OLDDEBUG" 2> /dev/null || true
27995 fi
27996 exit_status