Whamcloud - gitweb
LU-9162 lod: option to set max stripe count per filesystem
[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 rc=0
1188         trap 0
1189         [ -z "$DIR" ] || [ -z "$tdir" ] && return 0
1190
1191         local start=$SECONDS
1192         rm -rf $DIR/$tdir
1193         rc=$?
1194         wait_delete_completed
1195         echo "cleanup time $((SECONDS - start))"
1196         return $rc
1197 }
1198
1199 max_pages_per_rpc() {
1200         local mdtname="$(printf "MDT%04x" ${1:-0})"
1201         $LCTL get_param -n mdc.*$mdtname*.max_pages_per_rpc
1202 }
1203
1204 test_24v() {
1205         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1206
1207         local nrfiles=${COUNT:-100000}
1208         local fname="$DIR/$tdir/$tfile"
1209
1210         # Performance issue on ZFS see LU-4072 (c.f. LU-2887)
1211         [ "$mds1_FSTYPE" = "zfs" ] && nrfiles=${COUNT:-10000}
1212
1213         test_mkdir "$(dirname $fname)"
1214         # assume MDT0000 has the fewest inodes
1215         local stripes=$($LFS getdirstripe -c $(dirname $fname))
1216         local free_inodes=$(($(mdt_free_inodes 0) * stripes))
1217         [[ $free_inodes -lt $nrfiles ]] && nrfiles=$free_inodes
1218
1219         trap simple_cleanup_common EXIT
1220
1221         createmany -m "$fname" $nrfiles
1222
1223         cancel_lru_locks mdc
1224         lctl set_param mdc.*.stats clear
1225
1226         # was previously test_24D: LU-6101
1227         # readdir() returns correct number of entries after cursor reload
1228         local num_ls=$(ls $DIR/$tdir | wc -l)
1229         local num_uniq=$(ls $DIR/$tdir | sort -u | wc -l)
1230         local num_all=$(ls -a $DIR/$tdir | wc -l)
1231         if [ $num_ls -ne $nrfiles ] || [ $num_uniq -ne $nrfiles ] ||
1232                 [ $num_all -ne $((nrfiles + 2)) ]; then
1233                         error "Expected $nrfiles files, got $num_ls " \
1234                                 "($num_uniq unique $num_all .&..)"
1235         fi
1236         # LU-5 large readdir
1237         # dirent_size = 32 bytes for sizeof(struct lu_dirent) +
1238         #               N bytes for name (len($nrfiles) rounded to 8 bytes) +
1239         #               8 bytes for luda_type (4 bytes rounded to 8 bytes)
1240         # take into account of overhead in lu_dirpage header and end mark in
1241         # each page, plus one in rpc_num calculation.
1242         local dirent_size=$((32 + (${#tfile} | 7) + 1 + 8))
1243         local page_entries=$(((PAGE_SIZE - 24) / dirent_size))
1244         local mdt_idx=$($LFS getdirstripe -i $(dirname $fname))
1245         local rpc_pages=$(max_pages_per_rpc $mdt_idx)
1246         local rpc_max=$((nrfiles / (page_entries * rpc_pages) + stripes))
1247         local mds_readpage=$(calc_stats mdc.*.stats mds_readpage)
1248         echo "readpages: $mds_readpage rpc_max: $rpc_max"
1249         (( $mds_readpage < $rpc_max - 2 || $mds_readpage > $rpc_max + 1)) &&
1250                 error "large readdir doesn't take effect: " \
1251                       "$mds_readpage should be about $rpc_max"
1252
1253         simple_cleanup_common
1254 }
1255 run_test 24v "list large directory (test hash collision, b=17560)"
1256
1257 test_24w() { # bug21506
1258         SZ1=234852
1259         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=4096 || return 1
1260         dd if=/dev/zero bs=$SZ1 count=1 >> $DIR/$tfile || return 2
1261         dd if=$DIR/$tfile of=$DIR/${tfile}_left bs=1M skip=4097 || return 3
1262         SZ2=`ls -l $DIR/${tfile}_left | awk '{print $5}'`
1263         [[ "$SZ1" -eq "$SZ2" ]] ||
1264                 error "Error reading at the end of the file $tfile"
1265 }
1266 run_test 24w "Reading a file larger than 4Gb"
1267
1268 test_24x() {
1269         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
1270         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1271         [[ $MDS1_VERSION -lt $(version_code 2.7.56) ]] &&
1272                 skip "Need MDS version at least 2.7.56"
1273
1274         local MDTIDX=1
1275         local remote_dir=$DIR/$tdir/remote_dir
1276
1277         test_mkdir $DIR/$tdir
1278         $LFS mkdir -i $MDTIDX $remote_dir ||
1279                 error "create remote directory failed"
1280
1281         test_mkdir $DIR/$tdir/src_dir
1282         touch $DIR/$tdir/src_file
1283         test_mkdir $remote_dir/tgt_dir
1284         touch $remote_dir/tgt_file
1285
1286         mrename $DIR/$tdir/src_dir $remote_dir/tgt_dir ||
1287                 error "rename dir cross MDT failed!"
1288
1289         mrename $DIR/$tdir/src_file $remote_dir/tgt_file ||
1290                 error "rename file cross MDT failed!"
1291
1292         touch $DIR/$tdir/ln_file
1293         ln $DIR/$tdir/ln_file $remote_dir/ln_name ||
1294                 error "ln file cross MDT failed"
1295
1296         rm -rf $DIR/$tdir || error "Can not delete directories"
1297 }
1298 run_test 24x "cross MDT rename/link"
1299
1300 test_24y() {
1301         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
1302         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1303
1304         local remote_dir=$DIR/$tdir/remote_dir
1305         local mdtidx=1
1306
1307         test_mkdir $DIR/$tdir
1308         $LFS mkdir -i $mdtidx $remote_dir ||
1309                 error "create remote directory failed"
1310
1311         test_mkdir $remote_dir/src_dir
1312         touch $remote_dir/src_file
1313         test_mkdir $remote_dir/tgt_dir
1314         touch $remote_dir/tgt_file
1315
1316         mrename $remote_dir/src_dir $remote_dir/tgt_dir ||
1317                 error "rename subdir in the same remote dir failed!"
1318
1319         mrename $remote_dir/src_file $remote_dir/tgt_file ||
1320                 error "rename files in the same remote dir failed!"
1321
1322         ln $remote_dir/tgt_file $remote_dir/tgt_file1 ||
1323                 error "link files in the same remote dir failed!"
1324
1325         rm -rf $DIR/$tdir || error "Can not delete directories"
1326 }
1327 run_test 24y "rename/link on the same dir should succeed"
1328
1329 test_24z() {
1330         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
1331         [[ $MDS1_VERSION -lt $(version_code 2.12.51) ]] &&
1332                 skip "Need MDS version at least 2.12.51"
1333
1334         local index
1335
1336         for index in 0 1; do
1337                 $LFS mkdir -i $index $DIR/$tdir.$index || error "mkdir failed"
1338                 touch $DIR/$tdir.0/$tfile.$index || error "touch failed"
1339         done
1340
1341         mv $DIR/$tdir.0/$tfile.0 $DIR/$tdir.1 || error "mv $tfile.0 failed"
1342
1343         index=$($LFS getstripe -m $DIR/$tdir.1/$tfile.0)
1344         [ $index -eq 0 ] || error "$tfile.0 is on MDT$index"
1345
1346         local mdts=$(comma_list $(mdts_nodes))
1347
1348         do_nodes $mdts $LCTL set_param mdt.*.enable_remote_rename=0
1349         stack_trap "do_nodes $mdts $LCTL \
1350                 set_param mdt.*.enable_remote_rename=1" EXIT
1351
1352         mv $DIR/$tdir.0/$tfile.1 $DIR/$tdir.1 || error "mv $tfile.1 failed"
1353
1354         index=$($LFS getstripe -m $DIR/$tdir.1/$tfile.1)
1355         [ $index -eq 1 ] || error "$tfile.1 is on MDT$index"
1356 }
1357 run_test 24z "cross-MDT rename is done as cp"
1358
1359 test_24A() { # LU-3182
1360         local NFILES=5000
1361
1362         rm -rf $DIR/$tdir
1363         test_mkdir $DIR/$tdir
1364         trap simple_cleanup_common EXIT
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         if [ $t -ne $NFILES ] || [ $u -ne $NFILES ] ||
1370            [ $v -ne $((NFILES + 2)) ] ; then
1371                 error "Expected $NFILES files, got $t ($u unique $v .&..)"
1372         fi
1373
1374         simple_cleanup_common || error "Can not delete directories"
1375 }
1376 run_test 24A "readdir() returns correct number of entries."
1377
1378 test_24B() { # LU-4805
1379         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
1380
1381         local count
1382
1383         test_mkdir $DIR/$tdir
1384         $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir ||
1385                 error "create striped dir failed"
1386
1387         count=$(ls -ai $DIR/$tdir/striped_dir | wc -l)
1388         [ $count -eq 2 ] || error "Expected 2, got $count"
1389
1390         touch $DIR/$tdir/striped_dir/a
1391
1392         count=$(ls -ai $DIR/$tdir/striped_dir | wc -l)
1393         [ $count -eq 3 ] || error "Expected 3, got $count"
1394
1395         touch $DIR/$tdir/striped_dir/.f
1396
1397         count=$(ls -ai $DIR/$tdir/striped_dir | wc -l)
1398         [ $count -eq 4 ] || error "Expected 4, got $count"
1399
1400         rm -rf $DIR/$tdir || error "Can not delete directories"
1401 }
1402 run_test 24B "readdir for striped dir return correct number of entries"
1403
1404 test_24C() {
1405         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
1406
1407         mkdir $DIR/$tdir
1408         mkdir $DIR/$tdir/d0
1409         mkdir $DIR/$tdir/d1
1410
1411         $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/d0/striped_dir ||
1412                 error "create striped dir failed"
1413
1414         cd $DIR/$tdir/d0/striped_dir
1415
1416         local d0_ino=$(ls -i -l -a $DIR/$tdir | grep "d0" | awk '{print $1}')
1417         local d1_ino=$(ls -i -l -a $DIR/$tdir | grep "d1" | awk '{print $1}')
1418         local parent_ino=$(ls -i -l -a | grep "\.\." | awk '{print $1}')
1419
1420         [ "$d0_ino" = "$parent_ino" ] ||
1421                 error ".. wrong, expect $d0_ino, get $parent_ino"
1422
1423         mv $DIR/$tdir/d0/striped_dir $DIR/$tdir/d1/ ||
1424                 error "mv striped dir failed"
1425
1426         parent_ino=$(ls -i -l -a | grep "\.\." | awk '{print $1}')
1427
1428         [ "$d1_ino" = "$parent_ino" ] ||
1429                 error ".. wrong after mv, expect $d1_ino, get $parent_ino"
1430 }
1431 run_test 24C "check .. in striped dir"
1432
1433 test_24E() {
1434         [[ $MDSCOUNT -lt 4 ]] && skip_env "needs >= 4 MDTs"
1435         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1436
1437         mkdir -p $DIR/$tdir
1438         mkdir $DIR/$tdir/src_dir
1439         $LFS mkdir -i 1 $DIR/$tdir/src_dir/src_child ||
1440                 error "create remote source failed"
1441
1442         touch $DIR/$tdir/src_dir/src_child/a
1443
1444         $LFS mkdir -i 2 $DIR/$tdir/tgt_dir ||
1445                 error "create remote target dir failed"
1446
1447         $LFS mkdir -i 3 $DIR/$tdir/tgt_dir/tgt_child ||
1448                 error "create remote target child failed"
1449
1450         mrename $DIR/$tdir/src_dir/src_child $DIR/$tdir/tgt_dir/tgt_child ||
1451                 error "rename dir cross MDT failed!"
1452
1453         find $DIR/$tdir
1454
1455         $CHECKSTAT -t dir $DIR/$tdir/src_dir/src_child &&
1456                 error "src_child still exists after rename"
1457
1458         $CHECKSTAT -t file $DIR/$tdir/tgt_dir/tgt_child/a ||
1459                 error "missing file(a) after rename"
1460
1461         rm -rf $DIR/$tdir || error "Can not delete directories"
1462 }
1463 run_test 24E "cross MDT rename/link"
1464
1465 test_24F () {
1466         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return 0
1467
1468         local repeats=1000
1469         [ "$SLOW" = "no" ] && repeats=100
1470
1471         mkdir -p $DIR/$tdir
1472
1473         echo "$repeats repeats"
1474         for ((i = 0; i < repeats; i++)); do
1475                 $LFS mkdir -i0 -c2 $DIR/$tdir/test || error "mkdir fails"
1476                 touch $DIR/$tdir/test/a || error "touch fails"
1477                 mkdir $DIR/$tdir/test/b || error "mkdir fails"
1478                 rm -rf $DIR/$tdir/test || error "rmdir fails"
1479         done
1480
1481         true
1482 }
1483 run_test 24F "hash order vs readdir (LU-11330)"
1484
1485 test_24G () {
1486         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
1487
1488         local ino1
1489         local ino2
1490
1491         $LFS mkdir -i 0 $DIR/$tdir-0 || error "mkdir $tdir-0"
1492         $LFS mkdir -i 1 $DIR/$tdir-1 || error "mkdir $tdir-1"
1493         touch $DIR/$tdir-0/f1 || error "touch f1"
1494         ln -s $DIR/$tdir-0/f1 $DIR/$tdir-0/s1 || error "ln s1"
1495         ino1=$(stat -c%i $DIR/$tdir-0/s1)
1496         mv $DIR/$tdir-0/s1 $DIR/$tdir-1 || error "mv s1"
1497         ino2=$(stat -c%i $DIR/$tdir-1/s1)
1498         [ $ino1 -ne $ino2 ] || error "s1 should be migrated"
1499 }
1500 run_test 24G "migrate symlink in rename"
1501
1502 test_25a() {
1503         echo '== symlink sanity ============================================='
1504
1505         test_mkdir $DIR/d25
1506         ln -s d25 $DIR/s25
1507         touch $DIR/s25/foo ||
1508                 error "File creation in symlinked directory failed"
1509 }
1510 run_test 25a "create file in symlinked directory ==============="
1511
1512 test_25b() {
1513         [ ! -d $DIR/d25 ] && test_25a
1514         $CHECKSTAT -t file $DIR/s25/foo || error "$DIR/s25/foo not file type"
1515 }
1516 run_test 25b "lookup file in symlinked directory ==============="
1517
1518 test_26a() {
1519         test_mkdir $DIR/d26
1520         test_mkdir $DIR/d26/d26-2
1521         ln -s d26/d26-2 $DIR/s26
1522         touch $DIR/s26/foo || error "File creation failed"
1523 }
1524 run_test 26a "multiple component symlink ======================="
1525
1526 test_26b() {
1527         test_mkdir -p $DIR/$tdir/d26-2
1528         ln -s $tdir/d26-2/foo $DIR/s26-2
1529         touch $DIR/s26-2 || error "File creation failed"
1530 }
1531 run_test 26b "multiple component symlink at end of lookup ======"
1532
1533 test_26c() {
1534         test_mkdir $DIR/d26.2
1535         touch $DIR/d26.2/foo
1536         ln -s d26.2 $DIR/s26.2-1
1537         ln -s s26.2-1 $DIR/s26.2-2
1538         ln -s s26.2-2 $DIR/s26.2-3
1539         chmod 0666 $DIR/s26.2-3/foo
1540 }
1541 run_test 26c "chain of symlinks"
1542
1543 # recursive symlinks (bug 439)
1544 test_26d() {
1545         ln -s d26-3/foo $DIR/d26-3
1546 }
1547 run_test 26d "create multiple component recursive symlink"
1548
1549 test_26e() {
1550         [ ! -h $DIR/d26-3 ] && test_26d
1551         rm $DIR/d26-3
1552 }
1553 run_test 26e "unlink multiple component recursive symlink"
1554
1555 # recursive symlinks (bug 7022)
1556 test_26f() {
1557         test_mkdir $DIR/$tdir
1558         test_mkdir $DIR/$tdir/$tfile
1559         cd $DIR/$tdir/$tfile           || error "cd $DIR/$tdir/$tfile failed"
1560         test_mkdir -p lndir/bar1
1561         test_mkdir $DIR/$tdir/$tfile/$tfile
1562         cd $tfile                || error "cd $tfile failed"
1563         ln -s .. dotdot          || error "ln dotdot failed"
1564         ln -s dotdot/lndir lndir || error "ln lndir failed"
1565         cd $DIR/$tdir                 || error "cd $DIR/$tdir failed"
1566         output=`ls $tfile/$tfile/lndir/bar1`
1567         [ "$output" = bar1 ] && error "unexpected output"
1568         rm -r $tfile             || error "rm $tfile failed"
1569         $CHECKSTAT -a $DIR/$tfile || error "$tfile not gone"
1570 }
1571 run_test 26f "rm -r of a directory which has recursive symlink"
1572
1573 test_27a() {
1574         test_mkdir $DIR/$tdir
1575         $LFS getstripe $DIR/$tdir
1576         $LFS setstripe -c 1 $DIR/$tdir/$tfile || error "setstripe failed"
1577         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "checkstat failed"
1578         cp /etc/hosts $DIR/$tdir/$tfile || error "Can't copy to one stripe file"
1579 }
1580 run_test 27a "one stripe file"
1581
1582 test_27b() {
1583         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1584
1585         test_mkdir $DIR/$tdir
1586         $LFS setstripe -c 2 $DIR/$tdir/$tfile || error "setstripe failed"
1587         $LFS getstripe -c $DIR/$tdir/$tfile
1588         [ $($LFS getstripe -c $DIR/$tdir/$tfile) -eq 2 ] ||
1589                 error "two-stripe file doesn't have two stripes"
1590
1591         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
1592 }
1593 run_test 27b "create and write to two stripe file"
1594
1595 # 27c family tests specific striping, setstripe -o
1596 test_27ca() {
1597         [[ $OSTCOUNT -lt 2 ]] && skip_env "skipping 2-stripe test"
1598         test_mkdir -p $DIR/$tdir
1599         local osts="1"
1600
1601         $LFS setstripe -o $osts $DIR/$tdir/$tfile  || error "setstripe failed"
1602         $LFS getstripe -i $DIR/$tdir/$tfile
1603         [ $($LFS getstripe -i $DIR/$tdir/$tfile ) -eq $osts ] ||
1604                 error "stripe not on specified OST"
1605
1606         dd if=/dev/zero of=$DIR/$tdir/$tfile  bs=1M count=4 || error "dd failed"
1607 }
1608 run_test 27ca "one stripe on specified OST"
1609
1610 test_27cb() {
1611         [[ $OSTCOUNT -lt 2 ]] && skip_env "skipping 2-stripe test"
1612         test_mkdir -p $DIR/$tdir
1613         local osts="1,0"
1614         $LFS setstripe -o $osts $DIR/$tdir/$tfile || error "setstripe failed"
1615         local getstripe=$($LFS getstripe $DIR/$tdir/$tfile)
1616         echo "$getstripe"
1617
1618         # Strip getstripe output to a space separated list of OSTs
1619         local getstripe_osts=$(echo "$getstripe" | sed -e '1,/obdidx/d' |\
1620                 awk '{print $1}' | tr '\n' ' ' | sed -e 's/[[:space:]]*$//')
1621         [ "$getstripe_osts" = "${osts//,/ }" ] ||
1622                 error "stripes not on specified OSTs"
1623
1624         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 || error "dd failed"
1625 }
1626 run_test 27cb "two stripes on specified OSTs"
1627
1628 test_27cc() {
1629         [[ $OSTCOUNT -lt 2 ]] && skip_env "skipping 2-stripe test"
1630         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
1631                 skip "server does not support overstriping"
1632
1633         test_mkdir -p $DIR/$tdir
1634         local osts="0,0"
1635         $LFS setstripe -o $osts $DIR/$tdir/$tfile || error "setstripe failed"
1636         local getstripe=$($LFS getstripe $DIR/$tdir/$tfile)
1637         echo "$getstripe"
1638
1639         # Strip getstripe output to a space separated list of OSTs
1640         local getstripe_osts=$(echo "$getstripe" | sed -e '1,/obdidx/d' |\
1641                 awk '{print $1}' | tr '\n' ' ' | sed -e 's/[[:space:]]*$//')
1642         [ "$getstripe_osts" = "${osts//,/ }" ] ||
1643                 error "stripes not on specified OSTs"
1644
1645         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 || error "dd failed"
1646 }
1647 run_test 27cc "two stripes on the same OST"
1648
1649 test_27cd() {
1650         [[ $OSTCOUNT -lt 2 ]] && skip_env "skipping 2-stripe test"
1651         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
1652                 skip "server does not support overstriping"
1653         test_mkdir -p $DIR/$tdir
1654         local osts="0,1,1,0"
1655         $LFS setstripe -o $osts $DIR/$tdir/$tfile || error "setstripe failed"
1656         local getstripe=$($LFS getstripe $DIR/$tdir/$tfile)
1657         echo "$getstripe"
1658
1659         # Strip getstripe output to a space separated list of OSTs
1660         local getstripe_osts=$(echo "$getstripe" | sed -e '1,/obdidx/d' |\
1661                 awk '{print $1}' | tr '\n' ' ' | sed -e 's/[[:space:]]*$//')
1662         [ "$getstripe_osts" = "${osts//,/ }" ] ||
1663                 error "stripes not on specified OSTs"
1664
1665         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 || error "dd failed"
1666 }
1667 run_test 27cd "four stripes on two OSTs"
1668
1669 test_27ce() {
1670         [[ $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
1671                 skip_env "too many osts, skipping"
1672         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
1673                 skip "server does not support overstriping"
1674         # We do one more stripe than we have OSTs
1675         [ $OSTCOUNT -lt 159 ] || large_xattr_enabled ||
1676                 skip_env "ea_inode feature disabled"
1677
1678         test_mkdir -p $DIR/$tdir
1679         local osts=""
1680         for i in $(seq 0 $OSTCOUNT);
1681         do
1682                 osts=$osts"0"
1683                 if [ $i -ne $OSTCOUNT ]; then
1684                         osts=$osts","
1685                 fi
1686         done
1687         $LFS setstripe -o $osts $DIR/$tdir/$tfile || error "setstripe failed"
1688         local getstripe=$($LFS getstripe $DIR/$tdir/$tfile)
1689         echo "$getstripe"
1690
1691         # Strip getstripe output to a space separated list of OSTs
1692         local getstripe_osts=$(echo "$getstripe" | sed -e '1,/obdidx/d' |\
1693                 awk '{print $1}' | tr '\n' ' ' | sed -e 's/[[:space:]]*$//')
1694         [ "$getstripe_osts" = "${osts//,/ }" ] ||
1695                 error "stripes not on specified OSTs"
1696
1697         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 || error "dd failed"
1698 }
1699 run_test 27ce "more stripes than OSTs with -o"
1700
1701 test_27cf() {
1702         local osp_proc="osp.$FSNAME-OST0000-osc-MDT000*.active"
1703         local pid=0
1704
1705         test_mkdir -p $DIR/$tdir || error "failed to mkdir $DIR/$tdir"
1706         do_facet $SINGLEMDS "$LCTL set_param -n $osp_proc=0"
1707         stack_trap "do_facet $SINGLEMDS $LCTL set_param -n $osp_proc=1" EXIT
1708         wait_update_facet $SINGLEMDS "$LCTL get_param -n $osp_proc | grep 1" ||
1709                 error "failed to set $osp_proc=0"
1710
1711         $LFS setstripe -o 0 $DIR/$tdir/$tfile &
1712         pid=$!
1713         sleep 1
1714         do_facet $SINGLEMDS "$LCTL set_param -n $osp_proc=1"
1715         wait_update_facet $SINGLEMDS "$LCTL get_param -n $osp_proc | grep 0" ||
1716                 error "failed to set $osp_proc=1"
1717         wait $pid
1718         [[ $pid -ne 0 ]] ||
1719                 error "should return error due to $osp_proc=0"
1720 }
1721 run_test 27cf "'setstripe -o' on inactive OSTs should return error"
1722
1723 test_27d() {
1724         test_mkdir $DIR/$tdir
1725         $LFS setstripe -c 0 -i -1 -S 0 $DIR/$tdir/$tfile ||
1726                 error "setstripe failed"
1727         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "checkstat failed"
1728         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
1729 }
1730 run_test 27d "create file with default settings"
1731
1732 test_27e() {
1733         # LU-5839 adds check for existed layout before setting it
1734         [[ $MDS1_VERSION -lt $(version_code 2.7.56) ]] &&
1735                 skip "Need MDS version at least 2.7.56"
1736
1737         test_mkdir $DIR/$tdir
1738         $LFS setstripe -c 2 $DIR/$tdir/$tfile || error "setstripe failed"
1739         $LFS setstripe -c 2 $DIR/$tdir/$tfile && error "setstripe worked twice"
1740         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "checkstat failed"
1741 }
1742 run_test 27e "setstripe existing file (should return error)"
1743
1744 test_27f() {
1745         test_mkdir $DIR/$tdir
1746         $LFS setstripe -S 100 -i 0 -c 1 $DIR/$tdir/$tfile &&
1747                 error "$LFS setstripe $DIR/$tdir/$tfile failed"
1748         $CHECKSTAT -t file $DIR/$tdir/$tfile &&
1749                 error "$CHECKSTAT -t file $DIR/$tdir/$tfile should fail"
1750         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
1751         $LFS getstripe $DIR/$tdir/$tfile || error "$LFS getstripe failed"
1752 }
1753 run_test 27f "setstripe with bad stripe size (should return error)"
1754
1755 test_27g() {
1756         test_mkdir $DIR/$tdir
1757         $MCREATE $DIR/$tdir/$tfile || error "mcreate failed"
1758         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "no stripe info" ||
1759                 error "$DIR/$tdir/$tfile has object"
1760 }
1761 run_test 27g "$LFS getstripe with no objects"
1762
1763 test_27ga() {
1764         test_mkdir $DIR/$tdir
1765         touch $DIR/$tdir/$tfile || error "touch failed"
1766         ln -s bogus $DIR/$tdir/$tfile.2 || error "ln failed"
1767         $LFS getstripe -m $DIR/$tdir/$tfile $DIR/$tdir/$tfile.2
1768         local rc=$?
1769         (( rc == 2 )) || error "getstripe did not return ENOENT"
1770 }
1771 run_test 27ga "$LFS getstripe with missing file (should return error)"
1772
1773 test_27i() {
1774         test_mkdir $DIR/$tdir
1775         touch $DIR/$tdir/$tfile || error "touch failed"
1776         [[ $($LFS getstripe -c $DIR/$tdir/$tfile) -gt 0 ]] ||
1777                 error "missing objects"
1778 }
1779 run_test 27i "$LFS getstripe with some objects"
1780
1781 test_27j() {
1782         test_mkdir $DIR/$tdir
1783         $LFS setstripe -i $OSTCOUNT $DIR/$tdir/$tfile &&
1784                 error "setstripe failed" || true
1785 }
1786 run_test 27j "setstripe with bad stripe offset (should return error)"
1787
1788 test_27k() { # bug 2844
1789         test_mkdir $DIR/$tdir
1790         local file=$DIR/$tdir/$tfile
1791         local ll_max_blksize=$((4 * 1024 * 1024))
1792         $LFS setstripe -S 67108864 $file || error "setstripe failed"
1793         local blksize=$(stat $file | awk '/IO Block:/ { print $7 }')
1794         [ $blksize -le $ll_max_blksize ] || error "1:$blksize > $ll_max_blksize"
1795         dd if=/dev/zero of=$file bs=4k count=1
1796         blksize=$(stat $file | awk '/IO Block:/ { print $7 }')
1797         [ $blksize -le $ll_max_blksize ] || error "2:$blksize > $ll_max_blksize"
1798 }
1799 run_test 27k "limit i_blksize for broken user apps"
1800
1801 test_27l() {
1802         mcreate $DIR/$tfile || error "creating file"
1803         $RUNAS $LFS setstripe -c 1 $DIR/$tfile &&
1804                 error "setstripe should have failed" || true
1805 }
1806 run_test 27l "check setstripe permissions (should return error)"
1807
1808 test_27m() {
1809         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1810
1811         [ -n "$RCLIENTS" -o -n "$MOUNT_2" ] &&
1812                 skip_env "multiple clients -- skipping"
1813
1814         ORIGFREE=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
1815                    head -n1)
1816         if [[ $ORIGFREE -gt $MAXFREE ]]; then
1817                 skip "$ORIGFREE > $MAXFREE skipping out-of-space test on OST0"
1818         fi
1819         trap simple_cleanup_common EXIT
1820         test_mkdir $DIR/$tdir
1821         $LFS setstripe -i 0 -c 1 $DIR/$tdir/$tfile.1
1822         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=1024 count=$MAXFREE &&
1823                 error "dd should fill OST0"
1824         i=2
1825         while $LFS setstripe -i 0 -c 1 $DIR/$tdir/$tfile.$i; do
1826                 i=$((i + 1))
1827                 [ $i -gt 256 ] && break
1828         done
1829         i=$((i + 1))
1830         touch $DIR/$tdir/$tfile.$i
1831         [ $($LFS getstripe $DIR/$tdir/$tfile.$i | grep -A 10 obdidx |
1832             awk '{print $1}'| grep -w "0") ] &&
1833                 error "OST0 was full but new created file still use it"
1834         i=$((i + 1))
1835         touch $DIR/$tdir/$tfile.$i
1836         [ $($LFS getstripe $DIR/$tdir/$tfile.$i | grep -A 10 obdidx |
1837             awk '{print $1}'| grep -w "0") ] &&
1838                 error "OST0 was full but new created file still use it"
1839         simple_cleanup_common
1840 }
1841 run_test 27m "create file while OST0 was full"
1842
1843 # OSCs keep a NOSPC flag that will be reset after ~5s (qos_maxage)
1844 # if the OST isn't full anymore.
1845 reset_enospc() {
1846         local ostidx=${1:-""}
1847         local delay
1848         local ready
1849         local get_prealloc
1850
1851         local list=$(comma_list $(osts_nodes))
1852         [ "$ostidx" ] && list=$(facet_host ost$((ostidx + 1)))
1853
1854         do_nodes $list lctl set_param fail_loc=0
1855         wait_delete_completed   # initiate all OST_DESTROYs from MDS to OST
1856         delay=$(do_facet $SINGLEMDS lctl get_param -n lov.*.qos_maxage |
1857                 awk '{print $1 * 2;exit;}')
1858         get_prealloc="$LCTL get_param -n osc.*MDT*.prealloc_status |
1859                         grep -v \"^0$\""
1860         wait_update_facet $SINGLEMDS "$get_prealloc" "" $delay
1861 }
1862
1863 test_27n() {
1864         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1865         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1866         remote_mds_nodsh && skip "remote MDS with nodsh"
1867         remote_ost_nodsh && skip "remote OST with nodsh"
1868
1869         reset_enospc
1870         rm -f $DIR/$tdir/$tfile
1871         exhaust_precreations 0 0x80000215
1872         $LFS setstripe -c -1 $DIR/$tdir || error "setstripe failed"
1873         touch $DIR/$tdir/$tfile || error "touch failed"
1874         $LFS getstripe $DIR/$tdir/$tfile
1875         reset_enospc
1876 }
1877 run_test 27n "create file with some full OSTs"
1878
1879 test_27o() {
1880         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1881         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1882         remote_mds_nodsh && skip "remote MDS with nodsh"
1883         remote_ost_nodsh && skip "remote OST with nodsh"
1884
1885         reset_enospc
1886         rm -f $DIR/$tdir/$tfile
1887         exhaust_all_precreations 0x215
1888
1889         touch $DIR/$tdir/$tfile && error "able to create $DIR/$tdir/$tfile"
1890
1891         reset_enospc
1892         rm -rf $DIR/$tdir/*
1893 }
1894 run_test 27o "create file with all full OSTs (should error)"
1895
1896 function create_and_checktime() {
1897         local fname=$1
1898         local loops=$2
1899         local i
1900
1901         for ((i=0; i < $loops; i++)); do
1902                 local start=$SECONDS
1903                 multiop $fname-$i Oc
1904                 ((SECONDS-start < TIMEOUT)) ||
1905                         error "creation took " $((SECONDS-$start)) && return 1
1906         done
1907 }
1908
1909 test_27oo() {
1910         local mdts=$(comma_list $(mdts_nodes))
1911
1912         [ $MDS1_VERSION -lt $(version_code 2.13.57) ] &&
1913                 skip "Need MDS version at least 2.13.57"
1914
1915         local f0=$DIR/${tfile}-0
1916         local f1=$DIR/${tfile}-1
1917
1918         wait_delete_completed
1919
1920         # refill precreated objects
1921         $LFS setstripe -i0 -c1 $f0
1922
1923         saved=$(do_facet mds1 $LCTL get_param -n lov.*0000*.qos_threshold_rr)
1924         # force QoS allocation policy
1925         do_nodes $mdts $LCTL set_param lov.*.qos_threshold_rr=0%
1926         stack_trap "do_nodes $mdts $LCTL set_param \
1927                 lov.*.qos_threshold_rr=$saved" EXIT
1928         sleep_maxage
1929
1930         # one OST is unavailable, but still have few objects preallocated
1931         stop ost1
1932         stack_trap "start ost1 $(ostdevname 1) $OST_MOUNT_OPTS; \
1933                 rm -rf $f1 $DIR/$tdir*" EXIT
1934
1935         for ((i=0; i < 7; i++)); do
1936                 mkdir $DIR/$tdir$i || error "can't create dir"
1937                 $LFS setstripe -c$((OSTCOUNT-1)) $DIR/$tdir$i ||
1938                         error "can't set striping"
1939         done
1940         for ((i=0; i < 7; i++)); do
1941                 create_and_checktime $DIR/$tdir$i/$tfile 100 &
1942         done
1943         wait
1944 }
1945 run_test 27oo "don't let few threads to reserve too many objects"
1946
1947 test_27p() {
1948         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1949         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1950         remote_mds_nodsh && skip "remote MDS with nodsh"
1951         remote_ost_nodsh && skip "remote OST with nodsh"
1952
1953         reset_enospc
1954         rm -f $DIR/$tdir/$tfile
1955         test_mkdir $DIR/$tdir
1956
1957         $MCREATE $DIR/$tdir/$tfile || error "mcreate failed"
1958         $TRUNCATE $DIR/$tdir/$tfile 80000000 || error "truncate failed"
1959         $CHECKSTAT -s 80000000 $DIR/$tdir/$tfile || error "checkstat failed"
1960
1961         exhaust_precreations 0 0x80000215
1962         echo foo >> $DIR/$tdir/$tfile || error "append failed"
1963         $CHECKSTAT -s 80000004 $DIR/$tdir/$tfile || error "checkstat failed"
1964         $LFS getstripe $DIR/$tdir/$tfile
1965
1966         reset_enospc
1967 }
1968 run_test 27p "append to a truncated file with some full OSTs"
1969
1970 test_27q() {
1971         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1972         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1973         remote_mds_nodsh && skip "remote MDS with nodsh"
1974         remote_ost_nodsh && skip "remote OST with nodsh"
1975
1976         reset_enospc
1977         rm -f $DIR/$tdir/$tfile
1978
1979         mkdir_on_mdt0 $DIR/$tdir
1980         $MCREATE $DIR/$tdir/$tfile || error "mcreate $DIR/$tdir/$tfile failed"
1981         $TRUNCATE $DIR/$tdir/$tfile 80000000 ||
1982                 error "truncate $DIR/$tdir/$tfile failed"
1983         $CHECKSTAT -s 80000000 $DIR/$tdir/$tfile || error "checkstat failed"
1984
1985         exhaust_all_precreations 0x215
1986
1987         echo foo >> $DIR/$tdir/$tfile && error "append succeeded"
1988         $CHECKSTAT -s 80000000 $DIR/$tdir/$tfile || error "checkstat 2 failed"
1989
1990         reset_enospc
1991 }
1992 run_test 27q "append to truncated file with all OSTs full (should error)"
1993
1994 test_27r() {
1995         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1996         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1997         remote_mds_nodsh && skip "remote MDS with nodsh"
1998         remote_ost_nodsh && skip "remote OST with nodsh"
1999
2000         reset_enospc
2001         rm -f $DIR/$tdir/$tfile
2002         exhaust_precreations 0 0x80000215
2003
2004         $LFS setstripe -i 0 -c 2 $DIR/$tdir/$tfile || error "setstripe failed"
2005
2006         reset_enospc
2007 }
2008 run_test 27r "stripe file with some full OSTs (shouldn't LBUG) ="
2009
2010 test_27s() { # bug 10725
2011         test_mkdir $DIR/$tdir
2012         local stripe_size=$((4096 * 1024 * 1024))       # 2^32
2013         local stripe_count=0
2014         [ $OSTCOUNT -eq 1 ] || stripe_count=2
2015         $LFS setstripe -S $stripe_size -c $stripe_count $DIR/$tdir &&
2016                 error "stripe width >= 2^32 succeeded" || true
2017
2018 }
2019 run_test 27s "lsm_xfersize overflow (should error) (bug 10725)"
2020
2021 test_27t() { # bug 10864
2022         WDIR=$(pwd)
2023         WLFS=$(which lfs)
2024         cd $DIR
2025         touch $tfile
2026         $WLFS getstripe $tfile
2027         cd $WDIR
2028 }
2029 run_test 27t "check that utils parse path correctly"
2030
2031 test_27u() { # bug 4900
2032         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2033         remote_mds_nodsh && skip "remote MDS with nodsh"
2034
2035         local index
2036         local list=$(comma_list $(mdts_nodes))
2037
2038 #define OBD_FAIL_MDS_OSC_PRECREATE      0x139
2039         do_nodes $list $LCTL set_param fail_loc=0x139
2040         test_mkdir -p $DIR/$tdir
2041         trap simple_cleanup_common EXIT
2042         createmany -o $DIR/$tdir/t- 1000
2043         do_nodes $list $LCTL set_param fail_loc=0
2044
2045         TLOG=$TMP/$tfile.getstripe
2046         $LFS getstripe $DIR/$tdir > $TLOG
2047         OBJS=$(awk -vobj=0 '($1 == 0) { obj += 1 } END { print obj; }' $TLOG)
2048         unlinkmany $DIR/$tdir/t- 1000
2049         trap 0
2050         [[ $OBJS -gt 0 ]] &&
2051                 error "$OBJS objects created on OST-0. See $TLOG" ||
2052                 rm -f $TLOG
2053 }
2054 run_test 27u "skip object creation on OSC w/o objects"
2055
2056 test_27v() { # bug 4900
2057         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2058         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2059         remote_mds_nodsh && skip "remote MDS with nodsh"
2060         remote_ost_nodsh && skip "remote OST with nodsh"
2061
2062         exhaust_all_precreations 0x215
2063         reset_enospc
2064
2065         $LFS setstripe -c 1 $DIR/$tdir         # 1 stripe / file
2066
2067         touch $DIR/$tdir/$tfile
2068         #define OBD_FAIL_TGT_DELAY_PRECREATE     0x705
2069         # all except ost1
2070         for (( i=1; i < OSTCOUNT; i++ )); do
2071                 do_facet ost$i lctl set_param fail_loc=0x705
2072         done
2073         local START=`date +%s`
2074         createmany -o $DIR/$tdir/$tfile 32
2075
2076         local FINISH=`date +%s`
2077         local TIMEOUT=`lctl get_param -n timeout`
2078         local PROCESS=$((FINISH - START))
2079         [ $PROCESS -ge $((TIMEOUT / 2)) ] && \
2080                error "$FINISH - $START >= $TIMEOUT / 2"
2081         sleep $((TIMEOUT / 2 - PROCESS))
2082         reset_enospc
2083 }
2084 run_test 27v "skip object creation on slow OST"
2085
2086 test_27w() { # bug 10997
2087         test_mkdir $DIR/$tdir
2088         $LFS setstripe -S 65536 $DIR/$tdir/f0 || error "setstripe failed"
2089         [ $($LFS getstripe -S $DIR/$tdir/f0) -ne 65536 ] &&
2090                 error "stripe size $size != 65536" || true
2091         [ $($LFS getstripe -d $DIR/$tdir | grep -c "stripe_count") -eq 0 ] &&
2092                 error "$LFS getstripe -d $DIR/$tdir no 'stripe_count'" || true
2093 }
2094 run_test 27w "check $LFS setstripe -S and getstrip -d options"
2095
2096 test_27wa() {
2097         [[ $OSTCOUNT -lt 2 ]] &&
2098                 skip_env "skipping multiple stripe count/offset test"
2099
2100         test_mkdir $DIR/$tdir
2101         for i in $(seq 1 $OSTCOUNT); do
2102                 offset=$((i - 1))
2103                 $LFS setstripe -c $i -i $offset $DIR/$tdir/f$i ||
2104                         error "setstripe -c $i -i $offset failed"
2105                 count=$($LFS getstripe -c $DIR/$tdir/f$i)
2106                 index=$($LFS getstripe -i $DIR/$tdir/f$i)
2107                 [ $count -ne $i ] && error "stripe count $count != $i" || true
2108                 [ $index -ne $offset ] &&
2109                         error "stripe offset $index != $offset" || true
2110         done
2111 }
2112 run_test 27wa "check $LFS setstripe -c -i options"
2113
2114 test_27x() {
2115         remote_ost_nodsh && skip "remote OST with nodsh"
2116         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2117         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2118
2119         OFFSET=$(($OSTCOUNT - 1))
2120         OSTIDX=0
2121         local OST=$(ostname_from_index $OSTIDX)
2122
2123         test_mkdir $DIR/$tdir
2124         $LFS setstripe -c 1 $DIR/$tdir  # 1 stripe per file
2125         do_facet ost$((OSTIDX + 1)) lctl set_param -n obdfilter.$OST.degraded 1
2126         sleep_maxage
2127         createmany -o $DIR/$tdir/$tfile $OSTCOUNT
2128         for i in $(seq 0 $OFFSET); do
2129                 [ $($LFS getstripe $DIR/$tdir/$tfile$i | grep -A 10 obdidx |
2130                         awk '{print $1}' | grep -w "$OSTIDX") ] &&
2131                 error "OST0 was degraded but new created file still use it"
2132         done
2133         do_facet ost$((OSTIDX + 1)) lctl set_param -n obdfilter.$OST.degraded 0
2134 }
2135 run_test 27x "create files while OST0 is degraded"
2136
2137 test_27y() {
2138         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2139         remote_mds_nodsh && skip "remote MDS with nodsh"
2140         remote_ost_nodsh && skip "remote OST with nodsh"
2141         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2142
2143         local mdtosc=$(get_mdtosc_proc_path $SINGLEMDS $FSNAME-OST0000)
2144         local last_id=$(do_facet $SINGLEMDS lctl get_param -n \
2145                 osp.$mdtosc.prealloc_last_id)
2146         local next_id=$(do_facet $SINGLEMDS lctl get_param -n \
2147                 osp.$mdtosc.prealloc_next_id)
2148         local fcount=$((last_id - next_id))
2149         [[ $fcount -eq 0 ]] && skip "not enough space on OST0"
2150         [[ $fcount -gt $OSTCOUNT ]] && fcount=$OSTCOUNT
2151
2152         local MDS_OSCS=$(do_facet $SINGLEMDS lctl dl |
2153                          awk '/[oO][sS][cC].*md[ts]/ { print $4 }')
2154         local OST_DEACTIVE_IDX=-1
2155         local OSC
2156         local OSTIDX
2157         local OST
2158
2159         for OSC in $MDS_OSCS; do
2160                 OST=$(osc_to_ost $OSC)
2161                 OSTIDX=$(index_from_ostuuid $OST)
2162                 if [ $OST_DEACTIVE_IDX == -1 ]; then
2163                         OST_DEACTIVE_IDX=$OSTIDX
2164                 fi
2165                 if [ $OSTIDX != $OST_DEACTIVE_IDX ]; then
2166                         echo $OSC "is Deactivated:"
2167                         do_facet $SINGLEMDS lctl --device  %$OSC deactivate
2168                 fi
2169         done
2170
2171         OSTIDX=$(index_from_ostuuid $OST)
2172         test_mkdir $DIR/$tdir
2173         $LFS setstripe -c 1 $DIR/$tdir      # 1 stripe / file
2174
2175         for OSC in $MDS_OSCS; do
2176                 OST=$(osc_to_ost $OSC)
2177                 OSTIDX=$(index_from_ostuuid $OST)
2178                 if [ $OSTIDX == $OST_DEACTIVE_IDX ]; then
2179                         echo $OST "is degraded:"
2180                         do_facet ost$((OSTIDX+1)) lctl set_param -n \
2181                                                 obdfilter.$OST.degraded=1
2182                 fi
2183         done
2184
2185         sleep_maxage
2186         createmany -o $DIR/$tdir/$tfile $fcount
2187
2188         for OSC in $MDS_OSCS; do
2189                 OST=$(osc_to_ost $OSC)
2190                 OSTIDX=$(index_from_ostuuid $OST)
2191                 if [ $OSTIDX == $OST_DEACTIVE_IDX ]; then
2192                         echo $OST "is recovered from degraded:"
2193                         do_facet ost$((OSTIDX+1)) lctl set_param -n \
2194                                                 obdfilter.$OST.degraded=0
2195                 else
2196                         do_facet $SINGLEMDS lctl --device %$OSC activate
2197                 fi
2198         done
2199
2200         # all osp devices get activated, hence -1 stripe count restored
2201         local stripe_count=0
2202
2203         # sleep 2*lod_qos_maxage seconds waiting for lod qos to notice osp
2204         # devices get activated.
2205         sleep_maxage
2206         $LFS setstripe -c -1 $DIR/$tfile
2207         stripe_count=$($LFS getstripe -c $DIR/$tfile)
2208         rm -f $DIR/$tfile
2209         [ $stripe_count -ne $OSTCOUNT ] &&
2210                 error "Of $OSTCOUNT OSTs, only $stripe_count is available"
2211         return 0
2212 }
2213 run_test 27y "create files while OST0 is degraded and the rest inactive"
2214
2215 check_seq_oid()
2216 {
2217         log "check file $1"
2218
2219         lmm_count=$($LFS getstripe -c $1)
2220         lmm_seq=$($LFS getstripe -v $1 | awk '/lmm_seq/ { print $2 }')
2221         lmm_oid=$($LFS getstripe -v $1 | awk '/lmm_object_id/ { print $2 }')
2222
2223         local old_ifs="$IFS"
2224         IFS=$'[:]'
2225         fid=($($LFS path2fid $1))
2226         IFS="$old_ifs"
2227
2228         log "FID seq ${fid[1]}, oid ${fid[2]} ver ${fid[3]}"
2229         log "LOV seq $lmm_seq, oid $lmm_oid, count: $lmm_count"
2230
2231         # compare lmm_seq and lu_fid->f_seq
2232         [ $lmm_seq = ${fid[1]} ] || { error "SEQ mismatch"; return 1; }
2233         # compare lmm_object_id and lu_fid->oid
2234         [ $lmm_oid = ${fid[2]} ] || { error "OID mismatch"; return 2; }
2235
2236         # check the trusted.fid attribute of the OST objects of the file
2237         local have_obdidx=false
2238         local stripe_nr=0
2239         $LFS getstripe $1 | while read obdidx oid hex seq; do
2240                 # skip lines up to and including "obdidx"
2241                 [ -z "$obdidx" ] && break
2242                 [ "$obdidx" = "obdidx" ] && have_obdidx=true && continue
2243                 $have_obdidx || continue
2244
2245                 local ost=$((obdidx + 1))
2246                 local dev=$(ostdevname $ost)
2247                 local oid_hex
2248
2249                 log "want: stripe:$stripe_nr ost:$obdidx oid:$oid/$hex seq:$seq"
2250
2251                 seq=$(echo $seq | sed -e "s/^0x//g")
2252                 if [ $seq == 0 ] || [ $(facet_fstype ost$ost) == zfs ]; then
2253                         oid_hex=$(echo $oid)
2254                 else
2255                         oid_hex=$(echo $hex | sed -e "s/^0x//g")
2256                 fi
2257                 local obj_file="O/$seq/d$((oid %32))/$oid_hex"
2258
2259                 local ff=""
2260                 #
2261                 # Don't unmount/remount the OSTs if we don't need to do that.
2262                 # LU-2577 changes filter_fid to be smaller, so debugfs needs
2263                 # update too, until that use mount/ll_decode_filter_fid/mount.
2264                 # Re-enable when debugfs will understand new filter_fid.
2265                 #
2266                 if [ $(facet_fstype ost$ost) == ldiskfs ]; then
2267                         ff=$(do_facet ost$ost "$DEBUGFS -c -R 'stat $obj_file' \
2268                                 $dev 2>/dev/null" | grep "parent=")
2269                 fi
2270                 if [ -z "$ff" ]; then
2271                         stop ost$ost
2272                         mount_fstype ost$ost
2273                         ff=$(do_facet ost$ost $LL_DECODE_FILTER_FID \
2274                                 $(facet_mntpt ost$ost)/$obj_file)
2275                         unmount_fstype ost$ost
2276                         start ost$ost $dev $OST_MOUNT_OPTS
2277                         clients_up
2278                 fi
2279
2280                 [ -z "$ff" ] && error "$obj_file: no filter_fid info"
2281
2282                 echo "$ff" | sed -e 's#.*objid=#got: objid=#'
2283
2284                 # /mnt/O/0/d23/23: objid=23 seq=0 parent=[0x200000400:0x1e:0x1]
2285                 # fid: objid=23 seq=0 parent=[0x200000400:0x1e:0x0] stripe=1
2286                 #
2287                 # fid: parent=[0x200000400:0x1e:0x0] stripe=1 stripe_count=2 \
2288                 #       stripe_size=1048576 component_id=1 component_start=0 \
2289                 #       component_end=33554432
2290                 local ff_parent=$(sed -e 's/.*parent=.//' <<<$ff)
2291                 local ff_pseq=$(cut -d: -f1 <<<$ff_parent)
2292                 local ff_poid=$(cut -d: -f2 <<<$ff_parent)
2293                 local ff_pstripe
2294                 if grep -q 'stripe=' <<<$ff; then
2295                         ff_pstripe=$(sed -e 's/.*stripe=//' -e 's/ .*//' <<<$ff)
2296                 else
2297                         # $LL_DECODE_FILTER_FID does not print "stripe="; look
2298                         # into f_ver in this case.  See comment on ff_parent.
2299                         ff_pstripe=$(cut -d: -f3 <<<$ff_parent | sed -e 's/]//')
2300                 fi
2301
2302                 # compare lmm_seq and filter_fid->ff_parent.f_seq
2303                 [ $ff_pseq = $lmm_seq ] ||
2304                         error "FF parent SEQ $ff_pseq != $lmm_seq"
2305                 # compare lmm_object_id and filter_fid->ff_parent.f_oid
2306                 [ $ff_poid = $lmm_oid ] ||
2307                         error "FF parent OID $ff_poid != $lmm_oid"
2308                 (($ff_pstripe == $stripe_nr)) ||
2309                         error "FF stripe $ff_pstripe != $stripe_nr"
2310
2311                 stripe_nr=$((stripe_nr + 1))
2312                 [ $CLIENT_VERSION -lt $(version_code 2.9.55) ] &&
2313                         continue
2314                 if grep -q 'stripe_count=' <<<$ff; then
2315                         local ff_scnt=$(sed -e 's/.*stripe_count=//' \
2316                                             -e 's/ .*//' <<<$ff)
2317                         [ $lmm_count = $ff_scnt ] ||
2318                                 error "FF stripe count $lmm_count != $ff_scnt"
2319                 fi
2320         done
2321 }
2322
2323 test_27z() {
2324         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2325         remote_ost_nodsh && skip "remote OST with nodsh"
2326
2327         test_mkdir $DIR/$tdir
2328         $LFS setstripe -c 1 -i 0 -S 64k $DIR/$tdir/$tfile-1 ||
2329                 { error "setstripe -c -1 failed"; return 1; }
2330         # We need to send a write to every object to get parent FID info set.
2331         # This _should_ also work for setattr, but does not currently.
2332         # touch $DIR/$tdir/$tfile-1 ||
2333         dd if=/dev/zero of=$DIR/$tdir/$tfile-1 bs=1M count=1 ||
2334                 { error "dd $tfile-1 failed"; return 2; }
2335         $LFS setstripe -c -1 -i $((OSTCOUNT - 1)) -S 1M $DIR/$tdir/$tfile-2 ||
2336                 { error "setstripe -c -1 failed"; return 3; }
2337         dd if=/dev/zero of=$DIR/$tdir/$tfile-2 bs=1M count=$OSTCOUNT ||
2338                 { error "dd $tfile-2 failed"; return 4; }
2339
2340         # make sure write RPCs have been sent to OSTs
2341         sync; sleep 5; sync
2342
2343         check_seq_oid $DIR/$tdir/$tfile-1 || return 5
2344         check_seq_oid $DIR/$tdir/$tfile-2 || return 6
2345 }
2346 run_test 27z "check SEQ/OID on the MDT and OST filesystems"
2347
2348 test_27A() { # b=19102
2349         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2350
2351         save_layout_restore_at_exit $MOUNT
2352         $LFS setstripe -c 0 -i -1 -S 0 $MOUNT
2353         wait_update $HOSTNAME "$LFS getstripe -c $MOUNT | sed 's/  *//g'" "1" 20 ||
2354                 error "stripe count $($LFS getstripe -c $MOUNT) != 1"
2355         local default_size=$($LFS getstripe -S $MOUNT)
2356         local default_offset=$($LFS getstripe -i $MOUNT)
2357         local dsize=$(do_facet $SINGLEMDS \
2358                 "$LCTL get_param -n lod.$(facet_svc $SINGLEMDS)*.stripesize")
2359         [ $default_size -eq $dsize ] ||
2360                 error "stripe size $default_size != $dsize"
2361         [ $default_offset -eq -1 ] ||
2362                 error "stripe offset $default_offset != -1"
2363 }
2364 run_test 27A "check filesystem-wide default LOV EA values"
2365
2366 test_27B() { # LU-2523
2367         test_mkdir $DIR/$tdir
2368         rm -f $DIR/$tdir/f0 $DIR/$tdir/f1
2369         touch $DIR/$tdir/f0
2370         # open f1 with O_LOV_DELAY_CREATE
2371         # rename f0 onto f1
2372         # call setstripe ioctl on open file descriptor for f1
2373         # close
2374         multiop $DIR/$tdir/f1 oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:nB1c \
2375                 $DIR/$tdir/f0
2376
2377         rm -f $DIR/$tdir/f1
2378         # open f1 with O_LOV_DELAY_CREATE
2379         # unlink f1
2380         # call setstripe ioctl on open file descriptor for f1
2381         # close
2382         multiop $DIR/$tdir/f1 oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:uB1c
2383
2384         # Allow multiop to fail in imitation of NFS's busted semantics.
2385         true
2386 }
2387 run_test 27B "call setstripe on open unlinked file/rename victim"
2388
2389 # 27C family tests full striping and overstriping
2390 test_27Ca() { #LU-2871
2391         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2392
2393         declare -a ost_idx
2394         local index
2395         local found
2396         local i
2397         local j
2398
2399         test_mkdir $DIR/$tdir
2400         cd $DIR/$tdir
2401         for i in $(seq 0 $((OSTCOUNT - 1))); do
2402                 # set stripe across all OSTs starting from OST$i
2403                 $LFS setstripe -i $i -c -1 $tfile$i
2404                 # get striping information
2405                 ost_idx=($($LFS getstripe $tfile$i |
2406                          tail -n $((OSTCOUNT + 1)) | awk '{print $1}'))
2407                 echo ${ost_idx[@]}
2408
2409                 # check the layout
2410                 [ ${#ost_idx[@]} -eq $OSTCOUNT ] ||
2411                         error "${#ost_idx[@]} != $OSTCOUNT"
2412
2413                 for index in $(seq 0 $((OSTCOUNT - 1))); do
2414                         found=0
2415                         for j in $(echo ${ost_idx[@]}); do
2416                                 if [ $index -eq $j ]; then
2417                                         found=1
2418                                         break
2419                                 fi
2420                         done
2421                         [ $found = 1 ] ||
2422                                 error "Can not find $index in ${ost_idx[@]}"
2423                 done
2424         done
2425 }
2426 run_test 27Ca "check full striping across all OSTs"
2427
2428 test_27Cb() {
2429         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2430                 skip "server does not support overstriping"
2431         [[ $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
2432                 skip_env "too many osts, skipping"
2433
2434         test_mkdir -p $DIR/$tdir
2435         local setcount=$(($OSTCOUNT * 2))
2436         [ $setcount -lt 160 ] || large_xattr_enabled ||
2437                 skip_env "ea_inode feature disabled"
2438
2439         $LFS setstripe -C $setcount $DIR/$tdir/$tfile ||
2440                 error "setstripe failed"
2441
2442         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2443         [ $count -eq $setcount ] ||
2444                 error "stripe count $count, should be $setcount"
2445
2446         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" ||
2447                 error "overstriped should be set in pattern"
2448
2449         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2450                 error "dd failed"
2451 }
2452 run_test 27Cb "more stripes than OSTs with -C"
2453
2454 test_27Cc() {
2455         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2456                 skip "server does not support overstriping"
2457         [[ $OSTCOUNT -lt 2 ]] && skip_env "need > 1 OST"
2458
2459         test_mkdir -p $DIR/$tdir
2460         local setcount=$(($OSTCOUNT - 1))
2461
2462         [ $setcount -lt 160 ] || large_xattr_enabled ||
2463                 skip_env "ea_inode feature disabled"
2464
2465         $LFS setstripe -C $setcount $DIR/$tdir/$tfile ||
2466                 error "setstripe failed"
2467
2468         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2469         [ $count -eq $setcount ] ||
2470                 error "stripe count $count, should be $setcount"
2471
2472         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" &&
2473                 error "overstriped should not be set in pattern"
2474
2475         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2476                 error "dd failed"
2477 }
2478 run_test 27Cc "fewer stripes than OSTs does not set overstriping"
2479
2480 test_27Cd() {
2481         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2482                 skip "server does not support overstriping"
2483         [[ $OSTCOUNT -lt 2 ]] && skip_env "need > 1 OST"
2484         large_xattr_enabled || skip_env "ea_inode feature disabled"
2485
2486         test_mkdir -p $DIR/$tdir
2487         local setcount=$LOV_MAX_STRIPE_COUNT
2488
2489         $LFS setstripe -C $setcount $DIR/$tdir/$tfile ||
2490                 error "setstripe failed"
2491
2492         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2493         [ $count -eq $setcount ] ||
2494                 error "stripe count $count, should be $setcount"
2495
2496         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" ||
2497                 error "overstriped should be set in pattern"
2498
2499         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2500                 error "dd failed"
2501
2502         rm -f $DIR/$tdir/$tfile || error "Delete $tfile failed"
2503 }
2504 run_test 27Cd "test maximum stripe count"
2505
2506 test_27Ce() {
2507         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2508                 skip "server does not support overstriping"
2509         test_mkdir -p $DIR/$tdir
2510
2511         pool_add $TESTNAME || error "Pool creation failed"
2512         pool_add_targets $TESTNAME 0 || error "pool_add_targets failed"
2513
2514         local setcount=8
2515
2516         $LFS setstripe  -C $setcount -p "$TESTNAME" $DIR/$tdir/$tfile ||
2517                 error "setstripe failed"
2518
2519         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2520         [ $count -eq $setcount ] ||
2521                 error "stripe count $count, should be $setcount"
2522
2523         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" ||
2524                 error "overstriped should be set in pattern"
2525
2526         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2527                 error "dd failed"
2528
2529         rm -f $DIR/$tdir/$tfile || error "Delete $tfile failed"
2530 }
2531 run_test 27Ce "test pool with overstriping"
2532
2533 test_27Cf() {
2534         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2535                 skip "server does not support overstriping"
2536         [[ $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
2537                 skip_env "too many osts, skipping"
2538
2539         test_mkdir -p $DIR/$tdir
2540
2541         local setcount=$(($OSTCOUNT * 2))
2542         [ $setcount -lt 160 ] || large_xattr_enabled ||
2543                 skip_env "ea_inode feature disabled"
2544
2545         $LFS setstripe  -C $setcount $DIR/$tdir/ ||
2546                 error "setstripe failed"
2547
2548         echo 1 > $DIR/$tdir/$tfile
2549
2550         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2551         [ $count -eq $setcount ] ||
2552                 error "stripe count $count, should be $setcount"
2553
2554         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" ||
2555                 error "overstriped should be set in pattern"
2556
2557         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2558                 error "dd failed"
2559
2560         rm -f $DIR/$tdir/$tfile || error "Delete $tfile failed"
2561 }
2562 run_test 27Cf "test default inheritance with overstriping"
2563
2564 test_27D() {
2565         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
2566         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
2567         remote_mds_nodsh && skip "remote MDS with nodsh"
2568
2569         local POOL=${POOL:-testpool}
2570         local first_ost=0
2571         local last_ost=$(($OSTCOUNT - 1))
2572         local ost_step=1
2573         local ost_list=$(seq $first_ost $ost_step $last_ost)
2574         local ost_range="$first_ost $last_ost $ost_step"
2575
2576         test_mkdir $DIR/$tdir
2577         pool_add $POOL || error "pool_add failed"
2578         pool_add_targets $POOL $ost_range || error "pool_add_targets failed"
2579
2580         local skip27D
2581         [ $MDS1_VERSION -lt $(version_code 2.8.55) ] &&
2582                 skip27D+="-s 29"
2583         [ $MDS1_VERSION -lt $(version_code 2.9.55) ] ||
2584                 [ $CLIENT_VERSION -lt $(version_code 2.9.55) ] &&
2585                         skip27D+=" -s 30,31"
2586         [[ ! $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ||
2587           $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
2588                 skip27D+=" -s 32,33"
2589         [[ $MDS_VERSION -lt $(version_code $SEL_VER) ]] &&
2590                 skip27D+=" -s 34"
2591         llapi_layout_test -d$DIR/$tdir -p$POOL -o$OSTCOUNT $skip27D ||
2592                 error "llapi_layout_test failed"
2593
2594         destroy_test_pools || error "destroy test pools failed"
2595 }
2596 run_test 27D "validate llapi_layout API"
2597
2598 # Verify that default_easize is increased from its initial value after
2599 # accessing a widely striped file.
2600 test_27E() {
2601         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
2602         [ $CLIENT_VERSION -lt $(version_code 2.5.57) ] &&
2603                 skip "client does not have LU-3338 fix"
2604
2605         # 72 bytes is the minimum space required to store striping
2606         # information for a file striped across one OST:
2607         # (sizeof(struct lov_user_md_v3) +
2608         #  sizeof(struct lov_user_ost_data_v1))
2609         local min_easize=72
2610         $LCTL set_param -n llite.*.default_easize $min_easize ||
2611                 error "lctl set_param failed"
2612         local easize=$($LCTL get_param -n llite.*.default_easize)
2613
2614         [ $easize -eq $min_easize ] ||
2615                 error "failed to set default_easize"
2616
2617         $LFS setstripe -c $OSTCOUNT $DIR/$tfile ||
2618                 error "setstripe failed"
2619         # In order to ensure stat() call actually talks to MDS we need to
2620         # do something drastic to this file to shake off all lock, e.g.
2621         # rename it (kills lookup lock forcing cache cleaning)
2622         mv $DIR/$tfile $DIR/${tfile}-1
2623         ls -l $DIR/${tfile}-1
2624         rm $DIR/${tfile}-1
2625
2626         easize=$($LCTL get_param -n llite.*.default_easize)
2627
2628         [ $easize -gt $min_easize ] ||
2629                 error "default_easize not updated"
2630 }
2631 run_test 27E "check that default extended attribute size properly increases"
2632
2633 test_27F() { # LU-5346/LU-7975
2634         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2635         [[ $OSTCOUNT -lt 2 ]] && skip "needs >= 2 OSTs"
2636         [[ $MDS1_VERSION -lt $(version_code 2.8.51) ]] &&
2637                 skip "Need MDS version at least 2.8.51"
2638         remote_ost_nodsh && skip "remote OST with nodsh"
2639
2640         test_mkdir $DIR/$tdir
2641         rm -f $DIR/$tdir/f0
2642         $LFS setstripe -c 2 $DIR/$tdir
2643
2644         # stop all OSTs to reproduce situation for LU-7975 ticket
2645         for num in $(seq $OSTCOUNT); do
2646                 stop ost$num
2647         done
2648
2649         # open/create f0 with O_LOV_DELAY_CREATE
2650         # truncate f0 to a non-0 size
2651         # close
2652         multiop $DIR/$tdir/f0 oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:T1050000c
2653
2654         $CHECKSTAT -s 1050000 $DIR/$tdir/f0 || error "checkstat failed"
2655         # open/write it again to force delayed layout creation
2656         cat /etc/hosts > $DIR/$tdir/f0 &
2657         catpid=$!
2658
2659         # restart OSTs
2660         for num in $(seq $OSTCOUNT); do
2661                 start ost$num $(ostdevname $num) $OST_MOUNT_OPTS ||
2662                         error "ost$num failed to start"
2663         done
2664
2665         wait $catpid || error "cat failed"
2666
2667         cmp /etc/hosts $DIR/$tdir/f0 || error "cmp failed"
2668         [[ $($LFS getstripe -c $DIR/$tdir/f0) == 2 ]] ||
2669                 error "wrong stripecount"
2670
2671 }
2672 run_test 27F "Client resend delayed layout creation with non-zero size"
2673
2674 test_27G() { #LU-10629
2675         [ $MDS1_VERSION -lt $(version_code 2.11.51) ] &&
2676                 skip "Need MDS version at least 2.11.51"
2677         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
2678         remote_mds_nodsh && skip "remote MDS with nodsh"
2679         local POOL=${POOL:-testpool}
2680         local ostrange="0 0 1"
2681
2682         test_mkdir $DIR/$tdir
2683         touch $DIR/$tdir/$tfile.nopool
2684         pool_add $POOL || error "pool_add failed"
2685         pool_add_targets $POOL $ostrange || error "pool_add_targets failed"
2686         $LFS setstripe -p $POOL $DIR/$tdir
2687
2688         local pool=$($LFS getstripe -p $DIR/$tdir)
2689
2690         [ "$pool" = "$POOL" ] || error "Striping failed got '$pool' not '$POOL'"
2691         touch $DIR/$tdir/$tfile.default
2692         $LFS setstripe -E 1M --pool $POOL -c 1 -E eof -c 1 $DIR/$tdir/$tfile.pfl
2693         $LFS find $DIR/$tdir -type f --pool $POOL
2694         local found=$($LFS find $DIR/$tdir -type f --pool $POOL | wc -l)
2695         [[ "$found" == "2" ]] ||
2696                 error "found $found != 2 files in '$DIR/$tdir' in '$POOL'"
2697
2698         $LFS setstripe -d $DIR/$tdir
2699
2700         pool=$($LFS getstripe -p -d $DIR/$tdir)
2701
2702         [[ "$pool" != "$POOL" ]] || error "$DIR/$tdir is still '$pool'"
2703 }
2704 run_test 27G "Clear OST pool from stripe"
2705
2706 test_27H() {
2707         [[ $MDS1_VERSION -le $(version_code 2.11.54) ]] &&
2708                 skip "Need MDS version newer than 2.11.54"
2709         [[ $OSTCOUNT -lt 3 ]] && skip_env "needs >= 3 OSTs"
2710         test_mkdir $DIR/$tdir
2711         $LFS setstripe -o 0 -o 2 $DIR/$tdir || error "setstripe failed"
2712         touch $DIR/$tdir/$tfile
2713         $LFS getstripe -c $DIR/$tdir/$tfile
2714         [ $($LFS getstripe -c $DIR/$tdir/$tfile) -eq 2 ] ||
2715                 error "two-stripe file doesn't have two stripes"
2716
2717         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
2718         $LFS getstripe -y $DIR/$tdir/$tfile
2719         (( $($LFS getstripe -y $DIR/$tdir/$tfile |
2720              egrep -c "l_ost_idx: [02]$") == "2" )) ||
2721                 error "expected l_ost_idx: [02]$ not matched"
2722
2723         # make sure ost list has been cleared
2724         local stripesize=$($LFS getstripe -S $DIR/$tdir)
2725         $LFS setstripe -S $((stripesize * 4)) -i 1 \
2726                 -c $((OSTCOUNT - 1)) $DIR/$tdir || error "setstripe"
2727         touch $DIR/$tdir/f3
2728         $LVERIFY $DIR/$tdir $DIR/$tdir/f3 || error "lverify failed"
2729 }
2730 run_test 27H "Set specific OSTs stripe"
2731
2732 test_27I() {
2733         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2734         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2735         [[ $MDS1_VERSION -gt $(version_code 2.12.52) ]] ||
2736                 skip "Need MDS version newer than 2.12.52"
2737         local pool=$TESTNAME
2738         local ostrange="1 1 1"
2739
2740         save_layout_restore_at_exit $MOUNT
2741         $LFS setstripe -c 2 -i 0 $MOUNT
2742         pool_add $pool || error "pool_add failed"
2743         pool_add_targets $pool $ostrange ||
2744                 error "pool_add_targets failed"
2745         test_mkdir $DIR/$tdir
2746         $LFS setstripe -p $pool $DIR/$tdir
2747         $MULTIOP $DIR/$tdir/$tfile Oc || error "multiop failed"
2748         $LFS getstripe $DIR/$tdir/$tfile
2749 }
2750 run_test 27I "check that root dir striping does not break parent dir one"
2751
2752 test_27J() {
2753         [[ $MDS1_VERSION -le $(version_code 2.12.51) ]] &&
2754                 skip "Need MDS version newer than 2.12.51"
2755
2756         test_mkdir $DIR/$tdir
2757         local uuid1=$(cat /proc/sys/kernel/random/uuid)
2758         local uuid2=$(cat /proc/sys/kernel/random/uuid)
2759
2760         # create foreign file (raw way)
2761         ! $LFS setstripe --flags 0xda08 $DIR/$tdir/$tfile ||
2762                 error "creating $tfile w/ hex flags w/o --foreign should fail"
2763
2764         ! $LFS setstripe --foreign --flags foo \
2765                 --xattr ${uuid1}@${uuid2} $DIR/$tdir/$tfile ||
2766                         error "creating $tfile with '--flags foo' should fail"
2767
2768         ! $LFS setstripe --foreign --flags 0xffffffff \
2769                 --xattr ${uuid1}@${uuid2} $DIR/$tdir/$tfile ||
2770                         error "creating $tfile w/ 0xffffffff flags should fail"
2771
2772         create_foreign_file -f $DIR/$tdir/$tfile -x "${uuid1}@${uuid2}" \
2773                 -t 1 -F 0xda08 || error "create_foreign_file failed"
2774
2775         # verify foreign file (raw way)
2776         parse_foreign_file -f $DIR/$tdir/$tfile |
2777                 grep "lov_foreign_magic: 0x0BD70BD0" ||
2778                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign magic"
2779         parse_foreign_file -f $DIR/$tdir/$tfile | grep "lov_xattr_size: 89" ||
2780                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign size"
2781         parse_foreign_file -f $DIR/$tdir/$tfile |
2782                 grep "lov_foreign_size: 73" ||
2783                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign size"
2784         parse_foreign_file -f $DIR/$tdir/$tfile |
2785                 grep "lov_foreign_type: 1" ||
2786                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign type"
2787         parse_foreign_file -f $DIR/$tdir/$tfile |
2788                 grep "lov_foreign_flags: 0x0000DA08" ||
2789                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign flags"
2790         local lov=$(parse_foreign_file -f $DIR/$tdir/$tfile |
2791                 grep "lov_foreign_value: 0x" |
2792                 sed -e 's/lov_foreign_value: 0x//')
2793         local lov2=$(echo -n "${uuid1}@${uuid2}" | od -A n -t x1 -w160)
2794         [[ $lov = ${lov2// /} ]] ||
2795                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign value"
2796
2797         # create foreign file (lfs + API)
2798         $LFS setstripe --foreign=none --flags 0xda08 \
2799                 -x "${uuid1}@${uuid2}" $DIR/$tdir/${tfile}2 ||
2800                 error "$DIR/$tdir/${tfile}2: create failed"
2801
2802         $LFS getstripe -v $DIR/$tdir/${tfile}2 |
2803                 grep "lfm_magic:.*0x0BD70BD0" ||
2804                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign magic"
2805         # lfm_length is LOV EA size - sizeof(lfm_magic) - sizeof(lfm_length)
2806         $LFS getstripe -v $DIR/$tdir/${tfile}2 | grep "lfm_length:.*73" ||
2807                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign size"
2808         $LFS getstripe -v $DIR/$tdir/${tfile}2 | grep "lfm_type:.*none" ||
2809                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign type"
2810         $LFS getstripe -v $DIR/$tdir/${tfile}2 |
2811                 grep "lfm_flags:.*0x0000DA08" ||
2812                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign flags"
2813         $LFS getstripe $DIR/$tdir/${tfile}2 |
2814                 grep "lfm_value:.*${uuid1}@${uuid2}" ||
2815                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign value"
2816
2817         # modify striping should fail
2818         $LFS setstripe -c 2 $DIR/$tdir/$tfile &&
2819                 error "$DIR/$tdir/$tfile: setstripe should fail"
2820         $LFS setstripe -c 2 $DIR/$tdir/${tfile}2 &&
2821                 error "$DIR/$tdir/${tfile}2: setstripe should fail"
2822
2823         # R/W should fail
2824         cat $DIR/$tdir/$tfile && error "$DIR/$tdir/$tfile: read should fail"
2825         cat $DIR/$tdir/${tfile}2 &&
2826                 error "$DIR/$tdir/${tfile}2: read should fail"
2827         cat /etc/passwd > $DIR/$tdir/$tfile &&
2828                 error "$DIR/$tdir/$tfile: write should fail"
2829         cat /etc/passwd > $DIR/$tdir/${tfile}2 &&
2830                 error "$DIR/$tdir/${tfile}2: write should fail"
2831
2832         # chmod should work
2833         chmod 222 $DIR/$tdir/$tfile ||
2834                 error "$DIR/$tdir/$tfile: chmod failed"
2835         chmod 222 $DIR/$tdir/${tfile}2 ||
2836                 error "$DIR/$tdir/${tfile}2: chmod failed"
2837
2838         # chown should work
2839         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/$tfile ||
2840                 error "$DIR/$tdir/$tfile: chown failed"
2841         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/${tfile}2 ||
2842                 error "$DIR/$tdir/${tfile}2: chown failed"
2843
2844         # rename should work
2845         mv $DIR/$tdir/$tfile $DIR/$tdir/${tfile}.new ||
2846                 error "$DIR/$tdir/$tfile: rename of foreign file has failed"
2847         mv $DIR/$tdir/${tfile}2 $DIR/$tdir/${tfile}2.new ||
2848                 error "$DIR/$tdir/${tfile}2: rename of foreign file has failed"
2849
2850         #remove foreign file
2851         rm $DIR/$tdir/${tfile}.new ||
2852                 error "$DIR/$tdir/${tfile}.new: remove of foreign file has failed"
2853         rm $DIR/$tdir/${tfile}2.new ||
2854                 error "$DIR/$tdir/${tfile}2.new: remove of foreign file has failed"
2855 }
2856 run_test 27J "basic ops on file with foreign LOV"
2857
2858 test_27K() {
2859         [[ $MDS1_VERSION -le $(version_code 2.12.49) ]] &&
2860                 skip "Need MDS version newer than 2.12.49"
2861
2862         test_mkdir $DIR/$tdir
2863         local uuid1=$(cat /proc/sys/kernel/random/uuid)
2864         local uuid2=$(cat /proc/sys/kernel/random/uuid)
2865
2866         # create foreign dir (raw way)
2867         ! $LFS setdirstripe --flags 0xda08 $DIR/$tdir/$tdir ||
2868                 error "creating $tdir w/ hex flags w/o --foreign should fail"
2869
2870         ! $LFS setdirstripe --foreign --flags foo \
2871                 --xattr ${uuid1}@${uuid2} $DIR/$tdir/$tdir ||
2872                         error "creating $tdir with '--flags foo' should fail"
2873
2874         ! $LFS setdirstripe --foreign --flags 0xffffffff \
2875                 --xattr ${uuid1}@${uuid2} $DIR/$tdir/$tdir ||
2876                         error "creating $tdir w/ 0xffffffff flags should fail"
2877
2878         create_foreign_dir -d $DIR/$tdir/$tdir -x "${uuid1}@${uuid2}" -t 1 ||
2879                 error "create_foreign_dir FAILED"
2880
2881         # verify foreign dir (raw way)
2882         parse_foreign_dir -d $DIR/$tdir/$tdir |
2883                 grep "lmv_foreign_magic:.*0xcd50cd0" ||
2884                 error "$DIR/$tdir/$tfile: invalid LMV EA magic"
2885         parse_foreign_dir -d $DIR/$tdir/$tdir | grep "lmv_xattr_size:.*89$" ||
2886                 error "$DIR/$tdir/$tdir: invalid LMV EA size"
2887         parse_foreign_dir -d $DIR/$tdir/$tdir | grep "lmv_foreign_type: 1$" ||
2888                 error "$DIR/$tdir/$tdir: invalid LMV EA type"
2889         parse_foreign_dir -d $DIR/$tdir/$tdir |
2890                 grep "lmv_foreign_flags: 55813$" ||
2891                 error "$DIR/$tdir/$tdir: invalid LMV EA flags"
2892         local lmv=$(parse_foreign_dir -d $DIR/$tdir/$tdir |
2893                 grep "lmv_foreign_value: 0x" |
2894                 sed 's/lmv_foreign_value: 0x//')
2895         local lmv2=$(echo -n "${uuid1}@${uuid2}" | od -A n -t x1 -w160 |
2896                 sed 's/ //g')
2897         [[ $lmv == $lmv2 ]] || error "$DIR/$tdir/$tdir: invalid LMV EA value"
2898
2899         # create foreign dir (lfs + API)
2900         $LFS mkdir --foreign=none --xattr="${uuid1}@${uuid2}" --flags=0xda05 \
2901                 $DIR/$tdir/${tdir}2 ||
2902                 error "$DIR/$tdir/${tdir}2: create failed"
2903
2904         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 |
2905                 grep "lfm_magic:.*0x0CD50CD0" ||
2906                 error "$DIR/$tdir/${tdir}2: invalid LMV EA magic"
2907         # lfm_length is LMV EA size - sizeof(lfm_magic) - sizeof(lfm_length)
2908         # - sizeof(lfm_type) - sizeof(lfm_flags)
2909         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 | grep "lfm_length:.*73" ||
2910                 error "$DIR/$tdir/${tdir}2: invalid LMV EA size"
2911         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 | grep "lfm_type:.*none" ||
2912                 error "$DIR/$tdir/${tdir}2: invalid LMV EA type"
2913         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 |
2914                 grep "lfm_flags:.*0x0000DA05" ||
2915                 error "$DIR/$tdir/${tdir}2: invalid LMV EA flags"
2916         $LFS getdirstripe $DIR/$tdir/${tdir}2 |
2917                 grep "lfm_value.*${uuid1}@${uuid2}" ||
2918                 error "$DIR/$tdir/${tdir}2: invalid LMV EA value"
2919
2920         # file create in dir should fail
2921         touch $DIR/$tdir/$tdir/$tfile && "$DIR/$tdir: file create should fail"
2922         touch $DIR/$tdir/${tdir}2/$tfile &&
2923                 "$DIR/${tdir}2: file create should fail"
2924
2925         # chmod should work
2926         chmod 777 $DIR/$tdir/$tdir ||
2927                 error "$DIR/$tdir: chmod failed"
2928         chmod 777 $DIR/$tdir/${tdir}2 ||
2929                 error "$DIR/${tdir}2: chmod failed"
2930
2931         # chown should work
2932         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/$tdir ||
2933                 error "$DIR/$tdir: chown failed"
2934         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/${tdir}2 ||
2935                 error "$DIR/${tdir}2: chown failed"
2936
2937         # rename should work
2938         mv $DIR/$tdir/$tdir $DIR/$tdir/${tdir}.new ||
2939                 error "$DIR/$tdir/$tdir: rename of foreign dir has failed"
2940         mv $DIR/$tdir/${tdir}2 $DIR/$tdir/${tdir}2.new ||
2941                 error "$DIR/$tdir/${tdir}2: rename of foreign dir has failed"
2942
2943         #remove foreign dir
2944         rmdir $DIR/$tdir/${tdir}.new ||
2945                 error "$DIR/$tdir/${tdir}.new: remove of foreign dir has failed"
2946         rmdir $DIR/$tdir/${tdir}2.new ||
2947                 error "$DIR/$tdir/${tdir}2.new: remove of foreign dir has failed"
2948 }
2949 run_test 27K "basic ops on dir with foreign LMV"
2950
2951 test_27L() {
2952         remote_mds_nodsh && skip "remote MDS with nodsh"
2953
2954         local POOL=${POOL:-$TESTNAME}
2955
2956         pool_add $POOL || error "pool_add failed"
2957
2958         lfs pool_list $MOUNT | grep -Fx "${FSNAME}.${POOL}" ||
2959                  error "pool_list does not contain ${FSNAME}.${POOL}:" \
2960                        "$(lfs pool_list $MOUNT | grep -F "${POOL}")"
2961 }
2962 run_test 27L "lfs pool_list gives correct pool name"
2963
2964 test_27M() {
2965         [[ $(lustre_version_code $SINGLEMDS) -lt $(version_code 2.12.57) ]] &&
2966                 skip "Need MDS version >= than 2.12.57"
2967         remote_mds_nodsh && skip "remote MDS with nodsh"
2968         [[ $OSTCOUNT -lt 2 ]] && skip_env "need > 1 OST"
2969
2970         test_mkdir $DIR/$tdir
2971
2972         # Set default striping on directory
2973         local setcount=4
2974         local stripe_opt
2975
2976         # if we run against a 2.12 server which lacks overstring support
2977         # then the connect_flag will not report overstriping, even if client
2978         # is 2.14+
2979         if [[ $($LCTL get_param mdc.*.connect_flags) =~ overstriping ]]; then
2980                 stripe_opt="-C $setcount"
2981         elif (( $OSTCOUNT >= $setcount )); then
2982                 stripe_opt="-c $setcount"
2983         else
2984                 skip "server does not support overstriping"
2985         fi
2986         $LFS setstripe $stripe_opt $DIR/$tdir
2987
2988         echo 1 > $DIR/$tdir/${tfile}.1
2989         local count=$($LFS getstripe -c $DIR/$tdir/${tfile}.1)
2990         [ $count -eq $setcount ] ||
2991                 error "(1) stripe count $count, should be $setcount"
2992
2993         # Capture existing append_stripe_count setting for restore
2994         local orig_count=$(do_facet mds1 $LCTL get_param -n mdd.$FSNAME-MDT0000.append_stripe_count)
2995         local mdts=$(comma_list $(mdts_nodes))
2996         stack_trap "do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=$orig_count" EXIT
2997
2998         local appendcount=$orig_count
2999         echo 1 >> $DIR/$tdir/${tfile}.2_append
3000         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.2_append)
3001         [ $count -eq $appendcount ] ||
3002                 error "(2)stripe count $count, should be $appendcount for append"
3003
3004         # Disable O_APPEND striping, verify it works
3005         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=0
3006
3007         # Should now get the default striping, which is 4
3008         setcount=4
3009         echo 1 >> $DIR/$tdir/${tfile}.3_append
3010         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.3_append)
3011         [ $count -eq $setcount ] ||
3012                 error "(3) stripe count $count, should be $setcount"
3013
3014         # Try changing the stripe count for append files
3015         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=2
3016
3017         # Append striping is now 2 (directory default is still 4)
3018         appendcount=2
3019         echo 1 >> $DIR/$tdir/${tfile}.4_append
3020         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.4_append)
3021         [ $count -eq $appendcount ] ||
3022                 error "(4) stripe count $count, should be $appendcount for append"
3023
3024         # Test append stripe count of -1
3025         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=-1
3026         appendcount=$OSTCOUNT
3027         echo 1 >> $DIR/$tdir/${tfile}.5
3028         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.5)
3029         [ $count -eq $appendcount ] ||
3030                 error "(5) stripe count $count, should be $appendcount for append"
3031
3032         # Set append striping back to default of 1
3033         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=1
3034
3035         # Try a new default striping, PFL + DOM
3036         $LFS setstripe -L mdt -E 1M -E -1 -c 2 $DIR/$tdir
3037
3038         # Create normal DOM file, DOM returns stripe count == 0
3039         setcount=0
3040         touch $DIR/$tdir/${tfile}.6
3041         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.6)
3042         [ $count -eq $setcount ] ||
3043                 error "(6) stripe count $count, should be $setcount"
3044
3045         # Show
3046         appendcount=1
3047         echo 1 >> $DIR/$tdir/${tfile}.7_append
3048         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.7_append)
3049         [ $count -eq $appendcount ] ||
3050                 error "(7) stripe count $count, should be $appendcount for append"
3051
3052         # Clean up DOM layout
3053         $LFS setstripe -d $DIR/$tdir
3054
3055         save_layout_restore_at_exit $MOUNT
3056         # Now test that append striping works when layout is from root
3057         $LFS setstripe -c 2 $MOUNT
3058         # Make a special directory for this
3059         mkdir $DIR/${tdir}/${tdir}.2
3060
3061         # Verify for normal file
3062         setcount=2
3063         echo 1 > $DIR/${tdir}/${tdir}.2/${tfile}.8
3064         count=$($LFS getstripe -c $DIR/$tdir/${tdir}.2/${tfile}.8)
3065         [ $count -eq $setcount ] ||
3066                 error "(8) stripe count $count, should be $setcount"
3067
3068         appendcount=1
3069         echo 1 >> $DIR/${tdir}/${tdir}.2/${tfile}.9_append
3070         count=$($LFS getstripe -c $DIR/${tdir}/${tdir}.2/${tfile}.9_append)
3071         [ $count -eq $appendcount ] ||
3072                 error "(9) stripe count $count, should be $appendcount for append"
3073
3074         # Now test O_APPEND striping with pools
3075         do_nodes $mdts $LCTL set_param mdd.*.append_pool="$TESTNAME"
3076         stack_trap "do_nodes $mdts $LCTL set_param mdd.*.append_pool='none'" EXIT
3077
3078         # Create the pool
3079         pool_add $TESTNAME || error "pool creation failed"
3080         pool_add_targets $TESTNAME 0 1 || error "Pool add targets failed"
3081
3082         echo 1 >> $DIR/$tdir/${tfile}.10_append
3083
3084         pool=$($LFS getstripe -p $DIR/$tdir/${tfile}.10_append)
3085         [ "$pool" = "$TESTNAME" ] || error "(10) incorrect pool: $pool"
3086
3087         # Check that count is still correct
3088         appendcount=1
3089         echo 1 >> $DIR/$tdir/${tfile}.11_append
3090         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.11_append)
3091         [ $count -eq $appendcount ] ||
3092                 error "(11) stripe count $count, should be $appendcount for append"
3093
3094         # Disable O_APPEND stripe count, verify pool works separately
3095         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=0
3096
3097         echo 1 >> $DIR/$tdir/${tfile}.12_append
3098
3099         pool=$($LFS getstripe -p $DIR/$tdir/${tfile}.12_append)
3100         [ "$pool" = "$TESTNAME" ] || error "(12) incorrect pool: $pool"
3101
3102         # Remove pool setting, verify it's not applied
3103         do_nodes $mdts $LCTL set_param mdd.*.append_pool='none'
3104
3105         echo 1 >> $DIR/$tdir/${tfile}.13_append
3106
3107         pool=$($LFS getstripe -p $DIR/$tdir/${tfile}.13_append)
3108         [ "$pool" = "" ] || error "(13) pool found: $pool"
3109 }
3110 run_test 27M "test O_APPEND striping"
3111
3112 test_27N() {
3113         combined_mgs_mds && skip "needs separate MGS/MDT"
3114
3115         pool_add $TESTNAME || error "pool_add failed"
3116         do_facet mgs "$LCTL pool_list $FSNAME" |
3117                 grep -Fx "${FSNAME}.${TESTNAME}" ||
3118                 error "lctl pool_list on MGS failed"
3119 }
3120 run_test 27N "lctl pool_list on separate MGS gives correct pool name"
3121
3122 clean_foreign_symlink() {
3123         trap 0
3124         lctl set_param llite/$FSNAME-*/foreign_symlink_enable=0
3125         for i in $DIR/$tdir/* ; do
3126                 $LFS unlink_foreign $i || true
3127         done
3128 }
3129
3130 test_27O() {
3131         [[ $(lustre_version_code $SINGLEMDS) -le $(version_code 2.12.51) ]] &&
3132                 skip "Need MDS version newer than 2.12.51"
3133
3134         test_mkdir $DIR/$tdir
3135         local uuid1=$(cat /proc/sys/kernel/random/uuid)
3136         local uuid2=$(cat /proc/sys/kernel/random/uuid)
3137
3138         trap clean_foreign_symlink EXIT
3139
3140         # enable foreign_symlink behaviour
3141         $LCTL set_param llite/$FSNAME-*/foreign_symlink_enable=1
3142
3143         # foreign symlink LOV format is a partial path by default
3144
3145         # create foreign file (lfs + API)
3146         $LFS setstripe --foreign=symlink --flags 0xda05 \
3147                 -x "${uuid1}/${uuid2}" --mode 0600 $DIR/$tdir/${tfile} ||
3148                 error "$DIR/$tdir/${tfile}: create failed"
3149
3150         $LFS getstripe -v $DIR/$tdir/${tfile} |
3151                 grep "lfm_magic:.*0x0BD70BD0" ||
3152                 error "$DIR/$tdir/${tfile}: invalid LOV EA foreign magic"
3153         $LFS getstripe -v $DIR/$tdir/${tfile} | grep "lfm_type:.*symlink" ||
3154                 error "$DIR/$tdir/${tfile}: invalid LOV EA foreign type"
3155         $LFS getstripe -v $DIR/$tdir/${tfile} |
3156                 grep "lfm_flags:.*0x0000DA05" ||
3157                 error "$DIR/$tdir/${tfile}: invalid LOV EA foreign flags"
3158         $LFS getstripe $DIR/$tdir/${tfile} |
3159                 grep "lfm_value:.*${uuid1}/${uuid2}" ||
3160                 error "$DIR/$tdir/${tfile}: invalid LOV EA foreign value"
3161
3162         # modify striping should fail
3163         $LFS setstripe -c 2 $DIR/$tdir/$tfile &&
3164                 error "$DIR/$tdir/$tfile: setstripe should fail"
3165
3166         # R/W should fail ("/{foreign_symlink_prefix}/${uuid1}/" missing)
3167         cat $DIR/$tdir/$tfile && error "$DIR/$tdir/$tfile: read should fail"
3168         cat /etc/passwd > $DIR/$tdir/$tfile &&
3169                 error "$DIR/$tdir/$tfile: write should fail"
3170
3171         # rename should succeed
3172         mv $DIR/$tdir/$tfile $DIR/$tdir/${tfile}.new ||
3173                 error "$DIR/$tdir/$tfile: rename has failed"
3174
3175         #remove foreign_symlink file should fail
3176         rm $DIR/$tdir/${tfile}.new &&
3177                 error "$DIR/$tdir/${tfile}.new: remove of foreign_symlink file should fail"
3178
3179         #test fake symlink
3180         mkdir /tmp/${uuid1} ||
3181                 error "/tmp/${uuid1}: mkdir has failed"
3182         echo FOOFOO > /tmp/${uuid1}/${uuid2} ||
3183                 error "/tmp/${uuid1}/${uuid2}: echo has failed"
3184         $LCTL set_param llite/$FSNAME-*/foreign_symlink_prefix=/tmp/
3185         $CHECKSTAT -t link -l /tmp/${uuid1}/${uuid2} $DIR/$tdir/${tfile}.new ||
3186                 error "$DIR/$tdir/${tfile}.new: not seen as a symlink"
3187         #read should succeed now
3188         cat $DIR/$tdir/${tfile}.new | grep FOOFOO ||
3189                 error "$DIR/$tdir/${tfile}.new: symlink resolution has failed"
3190         #write should succeed now
3191         cat /etc/passwd > $DIR/$tdir/${tfile}.new ||
3192                 error "$DIR/$tdir/${tfile}.new: write should succeed"
3193         diff /etc/passwd $DIR/$tdir/${tfile}.new ||
3194                 error "$DIR/$tdir/${tfile}.new: diff has failed"
3195         diff /etc/passwd /tmp/${uuid1}/${uuid2} ||
3196                 error "/tmp/${uuid1}/${uuid2}: diff has failed"
3197
3198         #check that getstripe still works
3199         $LFS getstripe $DIR/$tdir/${tfile}.new ||
3200                 error "$DIR/$tdir/${tfile}.new: getstripe should still work with foreign_symlink enabled"
3201
3202         # chmod should still succeed
3203         chmod 644 $DIR/$tdir/${tfile}.new ||
3204                 error "$DIR/$tdir/${tfile}.new: chmod has failed"
3205
3206         # chown should still succeed
3207         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/${tfile}.new ||
3208                 error "$DIR/$tdir/${tfile}.new: chown has failed"
3209
3210         # rename should still succeed
3211         mv $DIR/$tdir/${tfile}.new $DIR/$tdir/${tfile} ||
3212                 error "$DIR/$tdir/${tfile}.new: rename has failed"
3213
3214         #remove foreign_symlink file should still fail
3215         rm $DIR/$tdir/${tfile} &&
3216                 error "$DIR/$tdir/${tfile}: remove of foreign_symlink file should fail"
3217
3218         #use special ioctl() to unlink foreign_symlink file
3219         $LFS unlink_foreign $DIR/$tdir/${tfile} ||
3220                 error "$DIR/$tdir/$tfile: unlink/ioctl failed"
3221
3222 }
3223 run_test 27O "basic ops on foreign file of symlink type"
3224
3225 test_27P() {
3226         [[ $(lustre_version_code $SINGLEMDS) -le $(version_code 2.12.49) ]] &&
3227                 skip "Need MDS version newer than 2.12.49"
3228
3229         test_mkdir $DIR/$tdir
3230         local uuid1=$(cat /proc/sys/kernel/random/uuid)
3231         local uuid2=$(cat /proc/sys/kernel/random/uuid)
3232
3233         trap clean_foreign_symlink EXIT
3234
3235         # enable foreign_symlink behaviour
3236         $LCTL set_param llite/$FSNAME-*/foreign_symlink_enable=1
3237
3238         # foreign symlink LMV format is a partial path by default
3239
3240         # create foreign dir (lfs + API)
3241         $LFS mkdir --foreign=symlink --xattr="${uuid1}/${uuid2}" \
3242                 --flags=0xda05 --mode 0750 $DIR/$tdir/${tdir} ||
3243                 error "$DIR/$tdir/${tdir}: create failed"
3244
3245         $LFS getdirstripe -v $DIR/$tdir/${tdir} |
3246                 grep "lfm_magic:.*0x0CD50CD0" ||
3247                 error "$DIR/$tdir/${tdir}: invalid LMV EA magic"
3248         $LFS getdirstripe -v $DIR/$tdir/${tdir} | grep "lfm_type:.*symlink" ||
3249                 error "$DIR/$tdir/${tdir}: invalid LMV EA type"
3250         $LFS getdirstripe -v $DIR/$tdir/${tdir} |
3251                 grep "lfm_flags:.*0x0000DA05" ||
3252                 error "$DIR/$tdir/${tdir}: invalid LMV EA flags"
3253         $LFS getdirstripe $DIR/$tdir/${tdir} |
3254                 grep "lfm_value.*${uuid1}/${uuid2}" ||
3255                 error "$DIR/$tdir/${tdir}: invalid LMV EA value"
3256
3257         # file create in dir should fail
3258         # ("/{foreign_symlink_prefix}/${uuid1}/${uuid2}/" missing)
3259         touch $DIR/$tdir/$tdir/$tfile && "$DIR/$tdir: file create should fail"
3260
3261         # rename should succeed
3262         mv $DIR/$tdir/$tdir $DIR/$tdir/${tdir}.new ||
3263                 error "$DIR/$tdir/$tdir: rename of foreign_symlink dir has failed"
3264
3265         #remove foreign_symlink dir should fail
3266         rmdir $DIR/$tdir/${tdir}.new &&
3267                 error "$DIR/$tdir/${tdir}.new: remove of foreign_symlink dir should fail"
3268
3269         #test fake symlink
3270         mkdir -p /tmp/${uuid1}/${uuid2} ||
3271                 error "/tmp/${uuid1}/${uuid2}: mkdir has failed"
3272         echo FOOFOO > /tmp/${uuid1}/${uuid2}/foo ||
3273                 error "/tmp/${uuid1}/${uuid2}/foo: echo has failed"
3274         $LCTL set_param llite/$FSNAME-*/foreign_symlink_prefix=/tmp/
3275         $CHECKSTAT -t link -l /tmp/${uuid1}/${uuid2} $DIR/$tdir/${tdir}.new ||
3276                 error "$DIR/$tdir/${tdir}.new: not seen as a symlink"
3277         cat $DIR/$tdir/${tdir}.new/foo | grep FOOFOO ||
3278                 error "$DIR/$tdir/${tdir}.new: symlink resolution has failed"
3279
3280         #check that getstripe fails now that foreign_symlink enabled
3281         $LFS getdirstripe $DIR/$tdir/${tdir}.new ||
3282                 error "$DIR/$tdir/${tdir}.new: getdirstripe should still work with foreign_symlink enabled"
3283
3284         # file create in dir should work now
3285         cp /etc/passwd $DIR/$tdir/${tdir}.new/$tfile ||
3286                 error "$DIR/$tdir/${tdir}.new/$tfile: file create should fail"
3287         diff /etc/passwd $DIR/$tdir/${tdir}.new/$tfile ||
3288                 error "$DIR/$tdir/${tdir}.new/$tfile: diff has failed"
3289         diff /etc/passwd /tmp/${uuid1}/${uuid2}/$tfile ||
3290                 error "/tmp/${uuid1}/${uuid2}/$tfile: diff has failed"
3291
3292         # chmod should still succeed
3293         chmod 755 $DIR/$tdir/${tdir}.new ||
3294                 error "$DIR/$tdir/${tdir}.new: chmod has failed"
3295
3296         # chown should still succeed
3297         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/${tdir}.new ||
3298                 error "$DIR/$tdir/${tdir}.new: chown has failed"
3299
3300         # rename should still succeed
3301         mv $DIR/$tdir/${tdir}.new $DIR/$tdir/${tdir} ||
3302                 error "$DIR/$tdir/${tdir}.new: rename of foreign_symlink dir has failed"
3303
3304         #remove foreign_symlink dir should still fail
3305         rmdir $DIR/$tdir/${tdir} &&
3306                 error "$DIR/$tdir/${tdir}: remove of foreign_symlink dir should fail"
3307
3308         #use special ioctl() to unlink foreign_symlink file
3309         $LFS unlink_foreign $DIR/$tdir/${tdir} ||
3310                 error "$DIR/$tdir/$tdir: unlink/ioctl failed"
3311
3312         #created file should still exist
3313         [[ -f /tmp/${uuid1}/${uuid2}/$tfile ]] ||
3314                 error "/tmp/${uuid1}/${uuid2}/$tfile has been removed"
3315         diff /etc/passwd /tmp/${uuid1}/${uuid2}/$tfile ||
3316                 error "/tmp/${uuid1}/${uuid2}/$tfile: diff has failed"
3317 }
3318 run_test 27P "basic ops on foreign dir of foreign_symlink type"
3319
3320 test_27Q() {
3321         rm -f $TMP/$tfile $TMP/$tfile.loop $TMP/$tfile.none $TMP/$tfile.broken
3322         stack_trap "rm -f $TMP/$tfile*"
3323
3324         test_mkdir $DIR/$tdir-1
3325         test_mkdir $DIR/$tdir-2
3326
3327         echo 'It is what it is' > $DIR/$tdir-1/$tfile
3328         lov_getstripe_old $DIR/$tdir-1/$tfile || error "$DIR/$tdir-1/$tfile: rc = $?"
3329
3330         ln -s $DIR/$tdir-1/$tfile $DIR/$tdir-2/$tfile
3331         lov_getstripe_old $DIR/$tdir-2/$tfile || error "$DIR/$tdir-2/$tfile: rc = $?"
3332
3333         ln -s $DIR/$tdir-1/$tfile $TMP/$tfile
3334         lov_getstripe_old $TMP/$tfile || error "$TMP/$tfile: rc = $?"
3335
3336         # Create some bad symlinks and ensure that we don't loop
3337         # forever or something. These should return ELOOP (40) and
3338         # ENOENT (2) but I don't want to test for that because there's
3339         # always some weirdo architecture that needs to ruin
3340         # everything by defining these error numbers differently.
3341
3342         ln -s $TMP/$tfile.loop $TMP/$tfile.loop
3343         lov_getstripe_old $TMP/$tfile.loop && error "$TMP/$tfile.loop: rc = $?"
3344
3345         ln -s $TMP/$tfile.none $TMP/$tfile.broken
3346         lov_getstripe_old $TMP/$tfile.broken && error "$TMP/$tfile.broken: rc = $?"
3347
3348         return 0
3349 }
3350 run_test 27Q "llapi_file_get_stripe() works on symlinks"
3351
3352 test_27R() {
3353         (( $MDS1_VERSION >= $(version_code 2.14.55) )) ||
3354                 skip "need MDS 2.14.55 or later"
3355         (( $OSTCOUNT >= 2 )) || skip_env "needs at least 2 OSTs"
3356
3357         local testdir="$DIR/$tdir"
3358         test_mkdir -p $testdir
3359         stack_trap "rm -rf $testdir"
3360         $LFS setstripe -c -1 $testdir || error "setstripe failed"
3361
3362         local f1="$testdir/f1"
3363         touch $f1 || error "failed to touch $f1"
3364         local count=$($LFS getstripe -c $f1)
3365         (( $count == $OSTCOUNT )) || error "wrong stripe count"
3366
3367         do_facet $SINGLEMDS $LCTL set_param lod.*.max_stripecount=-1
3368         (( $? == 34 )) || error "setting max_stripecount to -1 should fail and return ERANGE"
3369
3370         local maxcount=$(($OSTCOUNT - 1))
3371         local mdts=$(comma_list $(mdts_nodes))
3372         do_nodes $mdts $LCTL set_param lod.*.max_stripecount=$maxcount
3373         stack_trap "do_nodes $mdts $LCTL set_param lod.*.max_stripecount=0"
3374
3375         local f2="$testdir/f2"
3376         touch $f2 || error "failed to touch $f2"
3377         local count=$($LFS getstripe -c $f2)
3378         (( $count == $maxcount )) || error "wrong stripe count"
3379 }
3380 run_test 27R "test max_stripecount limitation when stripe count is set to -1"
3381
3382 # createtest also checks that device nodes are created and
3383 # then visible correctly (#2091)
3384 test_28() { # bug 2091
3385         test_mkdir $DIR/d28
3386         $CREATETEST $DIR/d28/ct || error "createtest failed"
3387 }
3388 run_test 28 "create/mknod/mkdir with bad file types ============"
3389
3390 test_29() {
3391         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3392
3393         sync; sleep 1; sync # flush out any dirty pages from previous tests
3394         cancel_lru_locks
3395         test_mkdir $DIR/d29
3396         touch $DIR/d29/foo
3397         log 'first d29'
3398         ls -l $DIR/d29
3399
3400         declare -i LOCKCOUNTORIG=0
3401         for lock_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_count); do
3402                 let LOCKCOUNTORIG=$LOCKCOUNTORIG+$lock_count
3403         done
3404         [ $LOCKCOUNTORIG -eq 0 ] && error "No mdc lock count" && return 1
3405
3406         declare -i LOCKUNUSEDCOUNTORIG=0
3407         for unused_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_unused_count); do
3408                 let LOCKUNUSEDCOUNTORIG=$LOCKUNUSEDCOUNTORIG+$unused_count
3409         done
3410
3411         log 'second d29'
3412         ls -l $DIR/d29
3413         log 'done'
3414
3415         declare -i LOCKCOUNTCURRENT=0
3416         for lock_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_count); do
3417                 let LOCKCOUNTCURRENT=$LOCKCOUNTCURRENT+$lock_count
3418         done
3419
3420         declare -i LOCKUNUSEDCOUNTCURRENT=0
3421         for unused_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_unused_count); do
3422                 let LOCKUNUSEDCOUNTCURRENT=$LOCKUNUSEDCOUNTCURRENT+$unused_count
3423         done
3424
3425         if [[ $LOCKCOUNTCURRENT -gt $LOCKCOUNTORIG ]]; then
3426                 $LCTL set_param -n ldlm.dump_namespaces ""
3427                 error "CURRENT: $LOCKCOUNTCURRENT > $LOCKCOUNTORIG"
3428                 $LCTL dk | sort -k4 -t: > $TMP/test_29.dk
3429                 log "dumped log to $TMP/test_29.dk (bug 5793)"
3430                 return 2
3431         fi
3432         if [[ $LOCKUNUSEDCOUNTCURRENT -gt $LOCKUNUSEDCOUNTORIG ]]; then
3433                 error "UNUSED: $LOCKUNUSEDCOUNTCURRENT > $LOCKUNUSEDCOUNTORIG"
3434                 $LCTL dk | sort -k4 -t: > $TMP/test_29.dk
3435                 log "dumped log to $TMP/test_29.dk (bug 5793)"
3436                 return 3
3437         fi
3438 }
3439 run_test 29 "IT_GETATTR regression  ============================"
3440
3441 test_30a() { # was test_30
3442         cp $(which ls) $DIR || cp /bin/ls $DIR
3443         $DIR/ls / || error "Can't execute binary from lustre"
3444         rm $DIR/ls
3445 }
3446 run_test 30a "execute binary from Lustre (execve) =============="
3447
3448 test_30b() {
3449         cp `which ls` $DIR || cp /bin/ls $DIR
3450         chmod go+rx $DIR/ls
3451         $RUNAS $DIR/ls / || error "Can't execute binary from lustre as non-root"
3452         rm $DIR/ls
3453 }
3454 run_test 30b "execute binary from Lustre as non-root ==========="
3455
3456 test_30c() { # b=22376
3457         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3458
3459         cp $(which ls) $DIR || cp /bin/ls $DIR
3460         chmod a-rw $DIR/ls
3461         cancel_lru_locks mdc
3462         cancel_lru_locks osc
3463         $RUNAS $DIR/ls / || error "Can't execute binary from lustre"
3464         rm -f $DIR/ls
3465 }
3466 run_test 30c "execute binary from Lustre without read perms ===="
3467
3468 test_30d() {
3469         cp $(which dd) $DIR || error "failed to copy dd to $DIR/dd"
3470
3471         for i in {1..10}; do
3472                 $DIR/dd bs=1M count=128 if=/dev/zero of=$DIR/$tfile &
3473                 local PID=$!
3474                 sleep 1
3475                 $LCTL set_param ldlm.namespaces.*MDT*.lru_size=clear
3476                 wait $PID || error "executing dd from Lustre failed"
3477                 rm -f $DIR/$tfile
3478         done
3479
3480         rm -f $DIR/dd
3481 }
3482 run_test 30d "execute binary from Lustre while clear locks"
3483
3484 test_31a() {
3485         $OPENUNLINK $DIR/f31 $DIR/f31 || error "openunlink failed"
3486         $CHECKSTAT -a $DIR/f31 || error "$DIR/f31 exists"
3487 }
3488 run_test 31a "open-unlink file =================================="
3489
3490 test_31b() {
3491         touch $DIR/f31 || error "touch $DIR/f31 failed"
3492         ln $DIR/f31 $DIR/f31b || error "ln failed"
3493         $MULTIOP $DIR/f31b Ouc || error "multiop failed"
3494         $CHECKSTAT -t file $DIR/f31 || error "$DIR/f31 not file type"
3495 }
3496 run_test 31b "unlink file with multiple links while open ======="
3497
3498 test_31c() {
3499         touch $DIR/f31 || error "touch $DIR/f31 failed"
3500         ln $DIR/f31 $DIR/f31c || error "ln failed"
3501         multiop_bg_pause $DIR/f31 O_uc ||
3502                 error "multiop_bg_pause for $DIR/f31 failed"
3503         MULTIPID=$!
3504         $MULTIOP $DIR/f31c Ouc
3505         kill -USR1 $MULTIPID
3506         wait $MULTIPID
3507 }
3508 run_test 31c "open-unlink file with multiple links ============="
3509
3510 test_31d() {
3511         opendirunlink $DIR/d31d $DIR/d31d || error "opendirunlink failed"
3512         $CHECKSTAT -a $DIR/d31d || error "$DIR/d31d exists"
3513 }
3514 run_test 31d "remove of open directory ========================="
3515
3516 test_31e() { # bug 2904
3517         openfilleddirunlink $DIR/d31e || error "openfilleddirunlink failed"
3518 }
3519 run_test 31e "remove of open non-empty directory ==============="
3520
3521 test_31f() { # bug 4554
3522         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3523
3524         set -vx
3525         test_mkdir $DIR/d31f
3526         $LFS setstripe -S 1048576 -c 1 $DIR/d31f
3527         cp /etc/hosts $DIR/d31f
3528         ls -l $DIR/d31f
3529         $LFS getstripe $DIR/d31f/hosts
3530         multiop_bg_pause $DIR/d31f D_c || return 1
3531         MULTIPID=$!
3532
3533         rm -rv $DIR/d31f || error "first of $DIR/d31f"
3534         test_mkdir $DIR/d31f
3535         $LFS setstripe -S 1048576 -c 1 $DIR/d31f
3536         cp /etc/hosts $DIR/d31f
3537         ls -l $DIR/d31f
3538         $LFS getstripe $DIR/d31f/hosts
3539         multiop_bg_pause $DIR/d31f D_c || return 1
3540         MULTIPID2=$!
3541
3542         kill -USR1 $MULTIPID || error "first opendir $MULTIPID not running"
3543         wait $MULTIPID || error "first opendir $MULTIPID failed"
3544
3545         sleep 6
3546
3547         kill -USR1 $MULTIPID2 || error "second opendir $MULTIPID not running"
3548         wait $MULTIPID2 || error "second opendir $MULTIPID2 failed"
3549         set +vx
3550 }
3551 run_test 31f "remove of open directory with open-unlink file ==="
3552
3553 test_31g() {
3554         echo "-- cross directory link --"
3555         test_mkdir -c1 $DIR/${tdir}ga
3556         test_mkdir -c1 $DIR/${tdir}gb
3557         touch $DIR/${tdir}ga/f
3558         ln $DIR/${tdir}ga/f $DIR/${tdir}gb/g
3559         $CHECKSTAT -t file $DIR/${tdir}ga/f || error "source"
3560         [ `stat -c%h $DIR/${tdir}ga/f` == '2' ] || error "source nlink"
3561         $CHECKSTAT -t file $DIR/${tdir}gb/g || error "target"
3562         [ `stat -c%h $DIR/${tdir}gb/g` == '2' ] || error "target nlink"
3563 }
3564 run_test 31g "cross directory link==============="
3565
3566 test_31h() {
3567         echo "-- cross directory link --"
3568         test_mkdir -c1 $DIR/${tdir}
3569         test_mkdir -c1 $DIR/${tdir}/dir
3570         touch $DIR/${tdir}/f
3571         ln $DIR/${tdir}/f $DIR/${tdir}/dir/g
3572         $CHECKSTAT -t file $DIR/${tdir}/f || error "source"
3573         [ `stat -c%h $DIR/${tdir}/f` == '2' ] || error "source nlink"
3574         $CHECKSTAT -t file $DIR/${tdir}/dir/g || error "target"
3575         [ `stat -c%h $DIR/${tdir}/dir/g` == '2' ] || error "target nlink"
3576 }
3577 run_test 31h "cross directory link under child==============="
3578
3579 test_31i() {
3580         echo "-- cross directory link --"
3581         test_mkdir -c1 $DIR/$tdir
3582         test_mkdir -c1 $DIR/$tdir/dir
3583         touch $DIR/$tdir/dir/f
3584         ln $DIR/$tdir/dir/f $DIR/$tdir/g
3585         $CHECKSTAT -t file $DIR/$tdir/dir/f || error "source"
3586         [ `stat -c%h $DIR/$tdir/dir/f` == '2' ] || error "source nlink"
3587         $CHECKSTAT -t file $DIR/$tdir/g || error "target"
3588         [ `stat -c%h $DIR/$tdir/g` == '2' ] || error "target nlink"
3589 }
3590 run_test 31i "cross directory link under parent==============="
3591
3592 test_31j() {
3593         test_mkdir -c1 -p $DIR/$tdir
3594         test_mkdir -c1 -p $DIR/$tdir/dir1
3595         ln $DIR/$tdir/dir1 $DIR/$tdir/dir2 && error "ln for dir"
3596         link $DIR/$tdir/dir1 $DIR/$tdir/dir3 && error "link for dir"
3597         mlink $DIR/$tdir/dir1 $DIR/$tdir/dir4 && error "mlink for dir"
3598         mlink $DIR/$tdir/dir1 $DIR/$tdir/dir1 && error "mlink to the same dir"
3599         return 0
3600 }
3601 run_test 31j "link for directory==============="
3602
3603 test_31k() {
3604         test_mkdir -c1 -p $DIR/$tdir
3605         touch $DIR/$tdir/s
3606         touch $DIR/$tdir/exist
3607         mlink $DIR/$tdir/s $DIR/$tdir/t || error "mlink"
3608         mlink $DIR/$tdir/s $DIR/$tdir/exist && error "mlink to exist file"
3609         mlink $DIR/$tdir/s $DIR/$tdir/s && error "mlink to the same file"
3610         mlink $DIR/$tdir/s $DIR/$tdir && error "mlink to parent dir"
3611         mlink $DIR/$tdir $DIR/$tdir/s && error "mlink parent dir to target"
3612         mlink $DIR/$tdir/not-exist $DIR/$tdir/foo && error "mlink non-existing to new"
3613         mlink $DIR/$tdir/not-exist $DIR/$tdir/s && error "mlink non-existing to exist"
3614         return 0
3615 }
3616 run_test 31k "link to file: the same, non-existing, dir==============="
3617
3618 test_31m() {
3619         mkdir $DIR/d31m
3620         touch $DIR/d31m/s
3621         mkdir $DIR/d31m2
3622         touch $DIR/d31m2/exist
3623         mlink $DIR/d31m/s $DIR/d31m2/t || error "mlink"
3624         mlink $DIR/d31m/s $DIR/d31m2/exist && error "mlink to exist file"
3625         mlink $DIR/d31m/s $DIR/d31m2 && error "mlink to parent dir"
3626         mlink $DIR/d31m2 $DIR/d31m/s && error "mlink parent dir to target"
3627         mlink $DIR/d31m/not-exist $DIR/d31m2/foo && error "mlink non-existing to new"
3628         mlink $DIR/d31m/not-exist $DIR/d31m2/s && error "mlink non-existing to exist"
3629         return 0
3630 }
3631 run_test 31m "link to file: the same, non-existing, dir==============="
3632
3633 test_31n() {
3634         touch $DIR/$tfile || error "cannot create '$DIR/$tfile'"
3635         nlink=$(stat --format=%h $DIR/$tfile)
3636         [ ${nlink:--1} -eq 1 ] || error "nlink is $nlink, expected 1"
3637         local fd=$(free_fd)
3638         local cmd="exec $fd<$DIR/$tfile"
3639         eval $cmd
3640         cmd="exec $fd<&-"
3641         trap "eval $cmd" EXIT
3642         nlink=$(stat --dereference --format=%h /proc/self/fd/$fd)
3643         [ ${nlink:--1} -eq 1 ] || error "nlink is $nlink, expected 1"
3644         rm $DIR/$tfile || error "cannot remove '$DIR/$tfile'"
3645         nlink=$(stat --dereference --format=%h /proc/self/fd/$fd)
3646         [ ${nlink:--1} -eq 0 ] || error "nlink is $nlink, expected 0"
3647         eval $cmd
3648 }
3649 run_test 31n "check link count of unlinked file"
3650
3651 link_one() {
3652         local tempfile=$(mktemp $1_XXXXXX)
3653         mlink $tempfile $1 2> /dev/null &&
3654                 echo "$BASHPID: link $tempfile to $1 succeeded"
3655         munlink $tempfile
3656 }
3657
3658 test_31o() { # LU-2901
3659         test_mkdir $DIR/$tdir
3660         for LOOP in $(seq 100); do
3661                 rm -f $DIR/$tdir/$tfile*
3662                 for THREAD in $(seq 8); do
3663                         link_one $DIR/$tdir/$tfile.$LOOP &
3664                 done
3665                 wait
3666                 local LINKS=$(ls -1 $DIR/$tdir | grep -c $tfile.$LOOP)
3667                 [[ $LINKS -gt 1 ]] && ls $DIR/$tdir &&
3668                         error "$LINKS duplicate links to $tfile.$LOOP" &&
3669                         break || true
3670         done
3671 }
3672 run_test 31o "duplicate hard links with same filename"
3673
3674 test_31p() {
3675         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
3676
3677         test_mkdir $DIR/$tdir
3678         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
3679         $LFS setdirstripe -D -c2 -H all_char $DIR/$tdir/striped_dir
3680
3681         opendirunlink $DIR/$tdir/striped_dir/test1 ||
3682                 error "open unlink test1 failed"
3683         opendirunlink $DIR/$tdir/striped_dir/test2 ||
3684                 error "open unlink test2 failed"
3685
3686         $CHECKSTAT -a $DIR/$tdir/striped_dir/test1 ||
3687                 error "test1 still exists"
3688         $CHECKSTAT -a $DIR/$tdir/striped_dir/test2 ||
3689                 error "test2 still exists"
3690 }
3691 run_test 31p "remove of open striped directory"
3692
3693 test_31q() {
3694         [ $MDSCOUNT -lt 3 ] && skip_env "needs >= 3 MDTs"
3695
3696         $LFS mkdir -i 3,1 $DIR/$tdir || error "mkdir failed"
3697         index=$($LFS getdirstripe -i $DIR/$tdir)
3698         [ $index -eq 3 ] || error "first stripe index $index != 3"
3699         index=$($LFS getdirstripe $DIR/$tdir | tail -1 | awk '{print $1}')
3700         [ $index -eq 1 ] || error "second stripe index $index != 1"
3701
3702         # when "-c <stripe_count>" is set, the number of MDTs specified after
3703         # "-i" should equal to the stripe count
3704         $LFS mkdir -i 3,1 -c 3 $DIR/$tdir.2 && error "mkdir should fail" || true
3705 }
3706 run_test 31q "create striped directory on specific MDTs"
3707
3708 #LU-14949
3709 test_31r() {
3710         touch $DIR/$tfile.target
3711         touch $DIR/$tfile.source
3712
3713         #OBD_FAIL_LLITE_OPEN_DELAY 0x1419
3714         $LCTL set_param fail_loc=0x1419 fail_val=3
3715         cat $DIR/$tfile.target &
3716         CATPID=$!
3717
3718         # Guarantee open is waiting before we get here
3719         sleep 1
3720         mv $DIR/$tfile.source $DIR/$tfile.target
3721
3722         wait $CATPID
3723         RC=$?
3724         if [[ $RC -ne 0 ]]; then
3725                 error "open with cat failed, rc=$RC"
3726         fi
3727 }
3728 run_test 31r "open-rename(replace) race"
3729
3730 cleanup_test32_mount() {
3731         local rc=0
3732         trap 0
3733         local loopdev=$(losetup -a | grep $EXT2_DEV | sed -ne 's/:.*$//p')
3734         $UMOUNT $DIR/$tdir/ext2-mountpoint || rc=$?
3735         losetup -d $loopdev || true
3736         rm -rf $DIR/$tdir
3737         return $rc
3738 }
3739
3740 test_32a() {
3741         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3742
3743         echo "== more mountpoints and symlinks ================="
3744         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3745         trap cleanup_test32_mount EXIT
3746         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3747         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3748                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3749         $CHECKSTAT -t dir $DIR/$tdir/ext2-mountpoint/.. ||
3750                 error "$DIR/$tdir/ext2-mountpoint/.. not dir type"
3751         cleanup_test32_mount
3752 }
3753 run_test 32a "stat d32a/ext2-mountpoint/.. ====================="
3754
3755 test_32b() {
3756         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3757
3758         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3759         trap cleanup_test32_mount EXIT
3760         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3761         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3762                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3763         ls -al $DIR/$tdir/ext2-mountpoint/.. ||
3764                 error "Can't list $DIR/$tdir/ext2-mountpoint/.."
3765         cleanup_test32_mount
3766 }
3767 run_test 32b "open d32b/ext2-mountpoint/.. ====================="
3768
3769 test_32c() {
3770         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3771
3772         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3773         trap cleanup_test32_mount EXIT
3774         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3775         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3776                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3777         test_mkdir -p $DIR/$tdir/d2/test_dir
3778         $CHECKSTAT -t dir $DIR/$tdir/ext2-mountpoint/../d2/test_dir ||
3779                 error "$DIR/$tdir/ext2-mountpoint/../d2/test_dir not dir type"
3780         cleanup_test32_mount
3781 }
3782 run_test 32c "stat d32c/ext2-mountpoint/../d2/test_dir ========="
3783
3784 test_32d() {
3785         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3786
3787         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3788         trap cleanup_test32_mount EXIT
3789         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3790         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3791                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3792         test_mkdir -p $DIR/$tdir/d2/test_dir
3793         ls -al $DIR/$tdir/ext2-mountpoint/../d2/test_dir ||
3794                 error "Can't list $DIR/$tdir/ext2-mountpoint/../d2/test_dir"
3795         cleanup_test32_mount
3796 }
3797 run_test 32d "open d32d/ext2-mountpoint/../d2/test_dir"
3798
3799 test_32e() {
3800         rm -fr $DIR/$tdir
3801         test_mkdir -p $DIR/$tdir/tmp
3802         local tmp_dir=$DIR/$tdir/tmp
3803         ln -s $DIR/$tdir $tmp_dir/symlink11
3804         ln -s $tmp_dir/symlink11 $tmp_dir/../symlink01
3805         $CHECKSTAT -t link $DIR/$tdir/tmp/symlink11 || error "symlink11 bad"
3806         $CHECKSTAT -t link $DIR/$tdir/symlink01 || error "symlink01 bad"
3807 }
3808 run_test 32e "stat d32e/symlink->tmp/symlink->lustre-subdir"
3809
3810 test_32f() {
3811         rm -fr $DIR/$tdir
3812         test_mkdir -p $DIR/$tdir/tmp
3813         local tmp_dir=$DIR/$tdir/tmp
3814         ln -s $DIR/$tdir $tmp_dir/symlink11
3815         ln -s $tmp_dir/symlink11 $tmp_dir/../symlink01
3816         ls $DIR/$tdir/tmp/symlink11  || error "symlink11 bad"
3817         ls $DIR/$tdir/symlink01 || error "symlink01 bad"
3818 }
3819 run_test 32f "open d32f/symlink->tmp/symlink->lustre-subdir"
3820
3821 test_32g() {
3822         local tmp_dir=$DIR/$tdir/tmp
3823         test_mkdir -p $tmp_dir
3824         test_mkdir $DIR/${tdir}2
3825         ln -s $DIR/${tdir}2 $tmp_dir/symlink12
3826         ln -s $tmp_dir/symlink12 $tmp_dir/../symlink02
3827         $CHECKSTAT -t link $tmp_dir/symlink12 || error "symlink12 not a link"
3828         $CHECKSTAT -t link $DIR/$tdir/symlink02 || error "symlink02 not a link"
3829         $CHECKSTAT -t dir -f $tmp_dir/symlink12 || error "symlink12 not a dir"
3830         $CHECKSTAT -t dir -f $DIR/$tdir/symlink02 || error "symlink12 not a dir"
3831 }
3832 run_test 32g "stat d32g/symlink->tmp/symlink->lustre-subdir/${tdir}2"
3833
3834 test_32h() {
3835         rm -fr $DIR/$tdir $DIR/${tdir}2
3836         tmp_dir=$DIR/$tdir/tmp
3837         test_mkdir -p $tmp_dir
3838         test_mkdir $DIR/${tdir}2
3839         ln -s $DIR/${tdir}2 $tmp_dir/symlink12
3840         ln -s $tmp_dir/symlink12 $tmp_dir/../symlink02
3841         ls $tmp_dir/symlink12 || error "listing symlink12"
3842         ls $DIR/$tdir/symlink02  || error "listing symlink02"
3843 }
3844 run_test 32h "open d32h/symlink->tmp/symlink->lustre-subdir/${tdir}2"
3845
3846 test_32i() {
3847         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3848
3849         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3850         trap cleanup_test32_mount EXIT
3851         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3852         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3853                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3854         touch $DIR/$tdir/test_file
3855         $CHECKSTAT -t file $DIR/$tdir/ext2-mountpoint/../test_file ||
3856                 error "$DIR/$tdir/ext2-mountpoint/../test_file not file type"
3857         cleanup_test32_mount
3858 }
3859 run_test 32i "stat d32i/ext2-mountpoint/../test_file ==========="
3860
3861 test_32j() {
3862         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3863
3864         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3865         trap cleanup_test32_mount EXIT
3866         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3867         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3868                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3869         touch $DIR/$tdir/test_file
3870         cat $DIR/$tdir/ext2-mountpoint/../test_file ||
3871                 error "Can't open $DIR/$tdir/ext2-mountpoint/../test_file"
3872         cleanup_test32_mount
3873 }
3874 run_test 32j "open d32j/ext2-mountpoint/../test_file ==========="
3875
3876 test_32k() {
3877         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3878
3879         rm -fr $DIR/$tdir
3880         trap cleanup_test32_mount EXIT
3881         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3882         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3883                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3884         test_mkdir -p $DIR/$tdir/d2
3885         touch $DIR/$tdir/d2/test_file || error "touch failed"
3886         $CHECKSTAT -t file $DIR/$tdir/ext2-mountpoint/../d2/test_file ||
3887                 error "$DIR/$tdir/ext2-mountpoint/../d2/test_file not file type"
3888         cleanup_test32_mount
3889 }
3890 run_test 32k "stat d32k/ext2-mountpoint/../d2/test_file ========"
3891
3892 test_32l() {
3893         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3894
3895         rm -fr $DIR/$tdir
3896         trap cleanup_test32_mount EXIT
3897         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3898         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3899                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3900         test_mkdir -p $DIR/$tdir/d2
3901         touch $DIR/$tdir/d2/test_file || error "touch failed"
3902         cat  $DIR/$tdir/ext2-mountpoint/../d2/test_file ||
3903                 error "Can't open $DIR/$tdir/ext2-mountpoint/../d2/test_file"
3904         cleanup_test32_mount
3905 }
3906 run_test 32l "open d32l/ext2-mountpoint/../d2/test_file ========"
3907
3908 test_32m() {
3909         rm -fr $DIR/d32m
3910         test_mkdir -p $DIR/d32m/tmp
3911         TMP_DIR=$DIR/d32m/tmp
3912         ln -s $DIR $TMP_DIR/symlink11
3913         ln -s $TMP_DIR/symlink11 $TMP_DIR/../symlink01
3914         $CHECKSTAT -t link $DIR/d32m/tmp/symlink11 ||
3915                 error "symlink11 not a link"
3916         $CHECKSTAT -t link $DIR/d32m/symlink01 ||
3917                 error "symlink01 not a link"
3918 }
3919 run_test 32m "stat d32m/symlink->tmp/symlink->lustre-root ======"
3920
3921 test_32n() {
3922         rm -fr $DIR/d32n
3923         test_mkdir -p $DIR/d32n/tmp
3924         TMP_DIR=$DIR/d32n/tmp
3925         ln -s $DIR $TMP_DIR/symlink11
3926         ln -s $TMP_DIR/symlink11 $TMP_DIR/../symlink01
3927         ls -l $DIR/d32n/tmp/symlink11  || error "listing symlink11"
3928         ls -l $DIR/d32n/symlink01 || error "listing symlink01"
3929 }
3930 run_test 32n "open d32n/symlink->tmp/symlink->lustre-root ======"
3931
3932 test_32o() {
3933         touch $DIR/$tfile
3934         test_mkdir -p $DIR/d32o/tmp
3935         TMP_DIR=$DIR/d32o/tmp
3936         ln -s $DIR/$tfile $TMP_DIR/symlink12
3937         ln -s $TMP_DIR/symlink12 $TMP_DIR/../symlink02
3938         $CHECKSTAT -t link $DIR/d32o/tmp/symlink12 ||
3939                 error "symlink12 not a link"
3940         $CHECKSTAT -t link $DIR/d32o/symlink02 || error "symlink02 not a link"
3941         $CHECKSTAT -t file -f $DIR/d32o/tmp/symlink12 ||
3942                 error "$DIR/d32o/tmp/symlink12 not file type"
3943         $CHECKSTAT -t file -f $DIR/d32o/symlink02 ||
3944                 error "$DIR/d32o/symlink02 not file type"
3945 }
3946 run_test 32o "stat d32o/symlink->tmp/symlink->lustre-root/$tfile"
3947
3948 test_32p() {
3949         log 32p_1
3950         rm -fr $DIR/d32p
3951         log 32p_2
3952         rm -f $DIR/$tfile
3953         log 32p_3
3954         touch $DIR/$tfile
3955         log 32p_4
3956         test_mkdir -p $DIR/d32p/tmp
3957         log 32p_5
3958         TMP_DIR=$DIR/d32p/tmp
3959         log 32p_6
3960         ln -s $DIR/$tfile $TMP_DIR/symlink12
3961         log 32p_7
3962         ln -s $TMP_DIR/symlink12 $TMP_DIR/../symlink02
3963         log 32p_8
3964         cat $DIR/d32p/tmp/symlink12 ||
3965                 error "Can't open $DIR/d32p/tmp/symlink12"
3966         log 32p_9
3967         cat $DIR/d32p/symlink02 || error "Can't open $DIR/d32p/symlink02"
3968         log 32p_10
3969 }
3970 run_test 32p "open d32p/symlink->tmp/symlink->lustre-root/$tfile"
3971
3972 test_32q() {
3973         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3974
3975         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3976         trap cleanup_test32_mount EXIT
3977         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3978         touch $DIR/$tdir/ext2-mountpoint/under_the_mount || error "touch failed"
3979         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3980                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3981         ls $DIR/$tdir/ext2-mountpoint | grep "\<under_the_mount\>" && error
3982         cleanup_test32_mount
3983 }
3984 run_test 32q "stat follows mountpoints in Lustre (should return error)"
3985
3986 test_32r() {
3987         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3988
3989         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3990         trap cleanup_test32_mount EXIT
3991         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3992         touch $DIR/$tdir/ext2-mountpoint/under_the_mount || error "touch failed"
3993         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3994                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3995         ls $DIR/$tdir/ext2-mountpoint | grep -q under_the_mount && error || true
3996         cleanup_test32_mount
3997 }
3998 run_test 32r "opendir follows mountpoints in Lustre (should return error)"
3999
4000 test_33aa() {
4001         rm -f $DIR/$tfile
4002         touch $DIR/$tfile
4003         chmod 444 $DIR/$tfile
4004         chown $RUNAS_ID $DIR/$tfile
4005         log 33_1
4006         $RUNAS $OPENFILE -f O_RDWR $DIR/$tfile && error || true
4007         log 33_2
4008 }
4009 run_test 33aa "write file with mode 444 (should return error)"
4010
4011 test_33a() {
4012         rm -fr $DIR/$tdir
4013         test_mkdir $DIR/$tdir
4014         chown $RUNAS_ID $DIR/$tdir
4015         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $DIR/$tdir/$tfile ||
4016                 error "$RUNAS create $tdir/$tfile failed"
4017         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $DIR/$tdir/$tfile &&
4018                 error "open RDWR" || true
4019 }
4020 run_test 33a "test open file(mode=0444) with O_RDWR (should return error)"
4021
4022 test_33b() {
4023         rm -fr $DIR/$tdir
4024         test_mkdir $DIR/$tdir
4025         chown $RUNAS_ID $DIR/$tdir
4026         $RUNAS $OPENFILE -f 1286739555 $DIR/$tdir/$tfile || true
4027 }
4028 run_test 33b "test open file with malformed flags (No panic)"
4029
4030 test_33c() {
4031         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4032         remote_ost_nodsh && skip "remote OST with nodsh"
4033
4034         local ostnum
4035         local ostname
4036         local write_bytes
4037         local all_zeros
4038
4039         all_zeros=true
4040         test_mkdir $DIR/$tdir
4041         # Read: 0, Write: 4, create/destroy: 2/0, stat: 1, punch: 0
4042
4043         sync
4044         for ostnum in $(seq $OSTCOUNT); do
4045                 # test-framework's OST numbering is one-based, while Lustre's
4046                 # is zero-based
4047                 ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
4048                 # check if at least some write_bytes stats are counted
4049                 write_bytes=$(do_facet ost$ostnum lctl get_param -n \
4050                               obdfilter.$ostname.stats |
4051                               awk '/^write_bytes/ {print $7}' )
4052                 echo "baseline_write_bytes@ost$ostnum/$ostname=$write_bytes"
4053                 if (( ${write_bytes:-0} > 0 )); then
4054                         all_zeros=false
4055                         break
4056                 fi
4057         done
4058
4059         $all_zeros || return 0
4060
4061         # Write four bytes
4062         echo foo > $DIR/$tdir/bar
4063         # Really write them
4064         sync
4065
4066         # Total up write_bytes after writing.  We'd better find non-zeros.
4067         for ostnum in $(seq $OSTCOUNT); do
4068                 ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
4069                 write_bytes=$(do_facet ost$ostnum lctl get_param -n \
4070                               obdfilter/$ostname/stats |
4071                               awk '/^write_bytes/ {print $7}' )
4072                 echo "write_bytes@ost$ostnum/$ostname=$write_bytes"
4073                 if (( ${write_bytes:-0} > 0 )); then
4074                         all_zeros=false
4075                         break
4076                 fi
4077         done
4078
4079         if $all_zeros; then
4080                 for ostnum in $(seq $OSTCOUNT); do
4081                         ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
4082                         echo "Check write_bytes is in obdfilter.*.stats:"
4083                         do_facet ost$ostnum lctl get_param -n \
4084                                 obdfilter.$ostname.stats
4085                 done
4086                 error "OST not keeping write_bytes stats (b=22312)"
4087         fi
4088 }
4089 run_test 33c "test write_bytes stats"
4090
4091 test_33d() {
4092         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
4093         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4094
4095         local MDTIDX=1
4096         local remote_dir=$DIR/$tdir/remote_dir
4097
4098         test_mkdir $DIR/$tdir
4099         $LFS mkdir -i $MDTIDX $remote_dir ||
4100                 error "create remote directory failed"
4101
4102         touch $remote_dir/$tfile
4103         chmod 444 $remote_dir/$tfile
4104         chown $RUNAS_ID $remote_dir/$tfile
4105
4106         $RUNAS $OPENFILE -f O_RDWR $DIR/$tfile && error || true
4107
4108         chown $RUNAS_ID $remote_dir
4109         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $remote_dir/f33 ||
4110                                         error "create" || true
4111         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $remote_dir/f33 &&
4112                                     error "open RDWR" || true
4113         $RUNAS $OPENFILE -f 1286739555 $remote_dir/f33 || true
4114 }
4115 run_test 33d "openfile with 444 modes and malformed flags under remote dir"
4116
4117 test_33e() {
4118         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
4119
4120         mkdir $DIR/$tdir
4121
4122         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
4123         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
4124         mkdir $DIR/$tdir/local_dir
4125
4126         local s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
4127         local s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
4128         local l_mode=$(stat -c%f $DIR/$tdir/local_dir)
4129
4130         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
4131                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode"
4132
4133         rmdir $DIR/$tdir/* || error "rmdir failed"
4134
4135         umask 777
4136         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
4137         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
4138         mkdir $DIR/$tdir/local_dir
4139
4140         s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
4141         s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
4142         l_mode=$(stat -c%f $DIR/$tdir/local_dir)
4143
4144         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
4145                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode 777"
4146
4147         rmdir $DIR/$tdir/* || error "rmdir(umask 777) failed"
4148
4149         umask 000
4150         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
4151         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
4152         mkdir $DIR/$tdir/local_dir
4153
4154         s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
4155         s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
4156         l_mode=$(stat -c%f $DIR/$tdir/local_dir)
4157
4158         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
4159                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode 0"
4160 }
4161 run_test 33e "mkdir and striped directory should have same mode"
4162
4163 cleanup_33f() {
4164         trap 0
4165         do_facet $SINGLEMDS $LCTL set_param mdt.*.enable_remote_dir_gid=0
4166 }
4167
4168 test_33f() {
4169         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
4170         remote_mds_nodsh && skip "remote MDS with nodsh"
4171
4172         mkdir $DIR/$tdir
4173         chmod go+rwx $DIR/$tdir
4174         do_facet $SINGLEMDS $LCTL set_param mdt.*.enable_remote_dir_gid=-1
4175         trap cleanup_33f EXIT
4176
4177         $RUNAS lfs mkdir -i 0 -c$MDSCOUNT $DIR/$tdir/striped_dir ||
4178                 error "cannot create striped directory"
4179
4180         $RUNAS touch $DIR/$tdir/striped_dir/{0..16} ||
4181                 error "cannot create files in striped directory"
4182
4183         $RUNAS rm $DIR/$tdir/striped_dir/{0..16} ||
4184                 error "cannot remove files in striped directory"
4185
4186         $RUNAS rmdir $DIR/$tdir/striped_dir ||
4187                 error "cannot remove striped directory"
4188
4189         cleanup_33f
4190 }
4191 run_test 33f "nonroot user can create, access, and remove a striped directory"
4192
4193 test_33g() {
4194         mkdir -p $DIR/$tdir/dir2
4195
4196         local err=$($RUNAS mkdir $DIR/$tdir/dir2 2>&1)
4197         echo $err
4198         [[ $err =~ "exists" ]] || error "Not exists error"
4199 }
4200 run_test 33g "nonroot user create already existing root created file"
4201
4202 test_33h() {
4203         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
4204         [ $MDS1_VERSION -lt $(version_code 2.13.50) ] &&
4205                 skip "Need MDS version at least 2.13.50"
4206
4207         test_mkdir -c $MDSCOUNT -H crush $DIR/$tdir ||
4208                 error "mkdir $tdir failed"
4209         touch $DIR/$tdir/$tfile || error "touch $tfile failed"
4210
4211         local index=$($LFS getstripe -m $DIR/$tdir/$tfile)
4212         local index2
4213
4214         for fname in $DIR/$tdir/$tfile.bak \
4215                      $DIR/$tdir/$tfile.SAV \
4216                      $DIR/$tdir/$tfile.orig \
4217                      $DIR/$tdir/$tfile~; do
4218                 touch $fname  || error "touch $fname failed"
4219                 index2=$($LFS getstripe -m $fname)
4220                 [ $index -eq $index2 ] ||
4221                         error "$fname MDT index mismatch $index != $index2"
4222         done
4223
4224         local failed=0
4225         for i in {1..250}; do
4226                 for fname in $(mktemp -u $DIR/$tdir/.$tfile.XXXXXX) \
4227                              $(mktemp $DIR/$tdir/$tfile.XXXXXXXX); do
4228                         touch $fname  || error "touch $fname failed"
4229                         index2=$($LFS getstripe -m $fname)
4230                         if [[ $index != $index2 ]]; then
4231                                 failed=$((failed + 1))
4232                                 echo "$fname MDT index mismatch $index != $index2"
4233                         fi
4234                 done
4235         done
4236         echo "$failed MDT index mismatches"
4237         (( failed < 20 )) || error "MDT index mismatch $failed times"
4238
4239 }
4240 run_test 33h "temp file is located on the same MDT as target"
4241
4242 TEST_34_SIZE=${TEST_34_SIZE:-2000000000000}
4243 test_34a() {
4244         rm -f $DIR/f34
4245         $MCREATE $DIR/f34 || error "mcreate failed"
4246         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
4247                 error "getstripe failed"
4248         $TRUNCATE $DIR/f34 $TEST_34_SIZE || error "truncate failed"
4249         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
4250                 error "getstripe failed"
4251         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4252                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4253 }
4254 run_test 34a "truncate file that has not been opened ==========="
4255
4256 test_34b() {
4257         [ ! -f $DIR/f34 ] && test_34a
4258         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4259                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4260         $OPENFILE -f O_RDONLY $DIR/f34
4261         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
4262                 error "getstripe failed"
4263         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4264                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4265 }
4266 run_test 34b "O_RDONLY opening file doesn't create objects ====="
4267
4268 test_34c() {
4269         [ ! -f $DIR/f34 ] && test_34a
4270         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4271                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4272         $OPENFILE -f O_RDWR $DIR/f34
4273         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" &&
4274                 error "$LFS getstripe failed"
4275         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4276                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4277 }
4278 run_test 34c "O_RDWR opening file-with-size works =============="
4279
4280 test_34d() {
4281         [ ! -f $DIR/f34 ] && test_34a
4282         dd if=/dev/zero of=$DIR/f34 conv=notrunc bs=4k count=1 ||
4283                 error "dd failed"
4284         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4285                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4286         rm $DIR/f34
4287 }
4288 run_test 34d "write to sparse file ============================="
4289
4290 test_34e() {
4291         rm -f $DIR/f34e
4292         $MCREATE $DIR/f34e || error "mcreate failed"
4293         $TRUNCATE $DIR/f34e 1000 || error "truncate failed"
4294         $CHECKSTAT -s 1000 $DIR/f34e ||
4295                 error "Size of $DIR/f34e not equal to 1000 bytes"
4296         $OPENFILE -f O_RDWR $DIR/f34e
4297         $CHECKSTAT -s 1000 $DIR/f34e ||
4298                 error "Size of $DIR/f34e not equal to 1000 bytes"
4299 }
4300 run_test 34e "create objects, some with size and some without =="
4301
4302 test_34f() { # bug 6242, 6243
4303         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4304
4305         SIZE34F=48000
4306         rm -f $DIR/f34f
4307         $MCREATE $DIR/f34f || error "mcreate failed"
4308         $TRUNCATE $DIR/f34f $SIZE34F || error "truncating $DIR/f3f to $SIZE34F"
4309         dd if=$DIR/f34f of=$TMP/f34f
4310         $CHECKSTAT -s $SIZE34F $TMP/f34f || error "$TMP/f34f not $SIZE34F bytes"
4311         dd if=/dev/zero of=$TMP/f34fzero bs=$SIZE34F count=1
4312         cmp $DIR/f34f $TMP/f34fzero || error "$DIR/f34f not all zero"
4313         cmp $TMP/f34f $TMP/f34fzero || error "$TMP/f34f not all zero"
4314         rm $TMP/f34f $TMP/f34fzero $DIR/f34f
4315 }
4316 run_test 34f "read from a file with no objects until EOF ======="
4317
4318 test_34g() {
4319         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4320
4321         dd if=/dev/zero of=$DIR/$tfile bs=1 count=100 seek=$TEST_34_SIZE ||
4322                 error "dd failed"
4323         $TRUNCATE $DIR/$tfile $((TEST_34_SIZE / 2))|| error "truncate failed"
4324         $CHECKSTAT -s $((TEST_34_SIZE / 2)) $DIR/$tfile ||
4325                 error "Size of $DIR/$tfile not equal to $((TEST_34_SIZE / 2))"
4326         cancel_lru_locks osc
4327         $CHECKSTAT -s $((TEST_34_SIZE / 2)) $DIR/$tfile ||
4328                 error "wrong size after lock cancel"
4329
4330         $TRUNCATE $DIR/$tfile $TEST_34_SIZE || error "truncate failed"
4331         $CHECKSTAT -s $TEST_34_SIZE $DIR/$tfile ||
4332                 error "expanding truncate failed"
4333         cancel_lru_locks osc
4334         $CHECKSTAT -s $TEST_34_SIZE $DIR/$tfile ||
4335                 error "wrong expanded size after lock cancel"
4336 }
4337 run_test 34g "truncate long file ==============================="
4338
4339 test_34h() {
4340         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4341
4342         local gid=10
4343         local sz=1000
4344
4345         dd if=/dev/zero of=$DIR/$tfile bs=1M count=10 || error "dd failed"
4346         sync # Flush the cache so that multiop below does not block on cache
4347              # flush when getting the group lock
4348         $MULTIOP $DIR/$tfile OG${gid}T${sz}g${gid}c &
4349         MULTIPID=$!
4350
4351         # Since just timed wait is not good enough, let's do a sync write
4352         # that way we are sure enough time for a roundtrip + processing
4353         # passed + 2 seconds of extra margin.
4354         dd if=/dev/zero of=$DIR/${tfile}-1 bs=$PAGE_SIZE oflag=direct count=1
4355         rm $DIR/${tfile}-1
4356         sleep 2
4357
4358         if [[ `ps h -o comm -p $MULTIPID` == "multiop" ]]; then
4359                 error "Multiop blocked on ftruncate, pid=$MULTIPID"
4360                 kill -9 $MULTIPID
4361         fi
4362         wait $MULTIPID
4363         local nsz=`stat -c %s $DIR/$tfile`
4364         [[ $nsz == $sz ]] || error "New size wrong $nsz != $sz"
4365 }
4366 run_test 34h "ftruncate file under grouplock should not block"
4367
4368 test_35a() {
4369         cp /bin/sh $DIR/f35a
4370         chmod 444 $DIR/f35a
4371         chown $RUNAS_ID $DIR/f35a
4372         $RUNAS $DIR/f35a && error || true
4373         rm $DIR/f35a
4374 }
4375 run_test 35a "exec file with mode 444 (should return and not leak)"
4376
4377 test_36a() {
4378         rm -f $DIR/f36
4379         utime $DIR/f36 || error "utime failed for MDS"
4380 }
4381 run_test 36a "MDS utime check (mknod, utime)"
4382
4383 test_36b() {
4384         echo "" > $DIR/f36
4385         utime $DIR/f36 || error "utime failed for OST"
4386 }
4387 run_test 36b "OST utime check (open, utime)"
4388
4389 test_36c() {
4390         rm -f $DIR/d36/f36
4391         test_mkdir $DIR/d36
4392         chown $RUNAS_ID $DIR/d36
4393         $RUNAS utime $DIR/d36/f36 || error "utime failed for MDS as non-root"
4394 }
4395 run_test 36c "non-root MDS utime check (mknod, utime)"
4396
4397 test_36d() {
4398         [ ! -d $DIR/d36 ] && test_36c
4399         echo "" > $DIR/d36/f36
4400         $RUNAS utime $DIR/d36/f36 || error "utime failed for OST as non-root"
4401 }
4402 run_test 36d "non-root OST utime check (open, utime)"
4403
4404 test_36e() {
4405         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID -- skipping"
4406
4407         test_mkdir $DIR/$tdir
4408         touch $DIR/$tdir/$tfile
4409         $RUNAS utime $DIR/$tdir/$tfile &&
4410                 error "utime worked, expected failure" || true
4411 }
4412 run_test 36e "utime on non-owned file (should return error)"
4413
4414 subr_36fh() {
4415         local fl="$1"
4416         local LANG_SAVE=$LANG
4417         local LC_LANG_SAVE=$LC_LANG
4418         export LANG=C LC_LANG=C # for date language
4419
4420         DATESTR="Dec 20  2000"
4421         test_mkdir $DIR/$tdir
4422         lctl set_param fail_loc=$fl
4423         date; date +%s
4424         cp /etc/hosts $DIR/$tdir/$tfile
4425         sync & # write RPC generated with "current" inode timestamp, but delayed
4426         sleep 1
4427         touch --date="$DATESTR" $DIR/$tdir/$tfile # setattr timestamp in past
4428         LS_BEFORE="`ls -l $DIR/$tdir/$tfile`" # old timestamp from client cache
4429         cancel_lru_locks $OSC
4430         LS_AFTER="`ls -l $DIR/$tdir/$tfile`"  # timestamp from OST object
4431         date; date +%s
4432         [ "$LS_BEFORE" != "$LS_AFTER" ] && \
4433                 echo "BEFORE: $LS_BEFORE" && \
4434                 echo "AFTER : $LS_AFTER" && \
4435                 echo "WANT  : $DATESTR" && \
4436                 error "$DIR/$tdir/$tfile timestamps changed" || true
4437
4438         export LANG=$LANG_SAVE LC_LANG=$LC_LANG_SAVE
4439 }
4440
4441 test_36f() {
4442         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4443
4444         #define OBD_FAIL_OST_BRW_PAUSE_BULK 0x214
4445         subr_36fh "0x80000214"
4446 }
4447 run_test 36f "utime on file racing with OST BRW write =========="
4448
4449 test_36g() {
4450         remote_ost_nodsh && skip "remote OST with nodsh"
4451         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4452         [ $MDS1_VERSION -lt $(version_code 2.12.51) ] &&
4453                 skip "Need MDS version at least 2.12.51"
4454
4455         local fmd_max_age
4456         local fmd
4457         local facet="ost1"
4458         local tgt="obdfilter"
4459
4460         [[ $OSC == "mdc" ]] && tgt="mdt" && facet="mds1"
4461
4462         test_mkdir $DIR/$tdir
4463         fmd_max_age=$(do_facet $facet \
4464                 "lctl get_param -n $tgt.*.tgt_fmd_seconds 2> /dev/null | \
4465                 head -n 1")
4466
4467         echo "FMD max age: ${fmd_max_age}s"
4468         touch $DIR/$tdir/$tfile
4469         fmd=$(do_facet $facet "lctl get_param -n $tgt.*.exports.*.fmd_count" |
4470                 gawk '{cnt=cnt+$1}  END{print cnt}')
4471         echo "FMD before: $fmd"
4472         [[ $fmd == 0 ]] &&
4473                 error "FMD wasn't create by touch"
4474         sleep $((fmd_max_age + 12))
4475         fmd=$(do_facet $facet "lctl get_param -n $tgt.*.exports.*.fmd_count" |
4476                 gawk '{cnt=cnt+$1}  END{print cnt}')
4477         echo "FMD after: $fmd"
4478         [[ $fmd == 0 ]] ||
4479                 error "FMD wasn't expired by ping"
4480 }
4481 run_test 36g "FMD cache expiry ====================="
4482
4483 test_36h() {
4484         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4485
4486         #define OBD_FAIL_OST_BRW_PAUSE_BULK2 0x227
4487         subr_36fh "0x80000227"
4488 }
4489 run_test 36h "utime on file racing with OST BRW write =========="
4490
4491 test_36i() {
4492         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
4493
4494         test_mkdir $DIR/$tdir
4495         $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir
4496
4497         local mtime=$(stat -c%Y $DIR/$tdir/striped_dir)
4498         local new_mtime=$((mtime + 200))
4499
4500         #change Modify time of striped dir
4501         touch -m -d @$new_mtime $DIR/$tdir/striped_dir ||
4502                         error "change mtime failed"
4503
4504         local got=$(stat -c%Y $DIR/$tdir/striped_dir)
4505
4506         [ "$new_mtime" = "$got" ] || error "expect $new_mtime got $got"
4507 }
4508 run_test 36i "change mtime on striped directory"
4509
4510 # test_37 - duplicate with tests 32q 32r
4511
4512 test_38() {
4513         local file=$DIR/$tfile
4514         touch $file
4515         openfile -f O_DIRECTORY $file
4516         local RC=$?
4517         local ENOTDIR=20
4518         [ $RC -eq 0 ] && error "opened file $file with O_DIRECTORY" || true
4519         [ $RC -eq $ENOTDIR ] || error "error $RC should be ENOTDIR ($ENOTDIR)"
4520 }
4521 run_test 38 "open a regular file with O_DIRECTORY should return -ENOTDIR ==="
4522
4523 test_39a() { # was test_39
4524         touch $DIR/$tfile
4525         touch $DIR/${tfile}2
4526 #       ls -l  $DIR/$tfile $DIR/${tfile}2
4527 #       ls -lu  $DIR/$tfile $DIR/${tfile}2
4528 #       ls -lc  $DIR/$tfile $DIR/${tfile}2
4529         sleep 2
4530         $OPENFILE -f O_CREAT:O_TRUNC:O_WRONLY $DIR/${tfile}2
4531         if [ ! $DIR/${tfile}2 -nt $DIR/$tfile ]; then
4532                 echo "mtime"
4533                 ls -l --full-time $DIR/$tfile $DIR/${tfile}2
4534                 echo "atime"
4535                 ls -lu --full-time $DIR/$tfile $DIR/${tfile}2
4536                 echo "ctime"
4537                 ls -lc --full-time $DIR/$tfile $DIR/${tfile}2
4538                 error "O_TRUNC didn't change timestamps"
4539         fi
4540 }
4541 run_test 39a "mtime changed on create"
4542
4543 test_39b() {
4544         test_mkdir -c1 $DIR/$tdir
4545         cp -p /etc/passwd $DIR/$tdir/fopen
4546         cp -p /etc/passwd $DIR/$tdir/flink
4547         cp -p /etc/passwd $DIR/$tdir/funlink
4548         cp -p /etc/passwd $DIR/$tdir/frename
4549         ln $DIR/$tdir/funlink $DIR/$tdir/funlink2
4550
4551         sleep 1
4552         echo "aaaaaa" >> $DIR/$tdir/fopen
4553         echo "aaaaaa" >> $DIR/$tdir/flink
4554         echo "aaaaaa" >> $DIR/$tdir/funlink
4555         echo "aaaaaa" >> $DIR/$tdir/frename
4556
4557         local open_new=`stat -c %Y $DIR/$tdir/fopen`
4558         local link_new=`stat -c %Y $DIR/$tdir/flink`
4559         local unlink_new=`stat -c %Y $DIR/$tdir/funlink`
4560         local rename_new=`stat -c %Y $DIR/$tdir/frename`
4561
4562         cat $DIR/$tdir/fopen > /dev/null
4563         ln $DIR/$tdir/flink $DIR/$tdir/flink2
4564         rm -f $DIR/$tdir/funlink2
4565         mv -f $DIR/$tdir/frename $DIR/$tdir/frename2
4566
4567         for (( i=0; i < 2; i++ )) ; do
4568                 local open_new2=`stat -c %Y $DIR/$tdir/fopen`
4569                 local link_new2=`stat -c %Y $DIR/$tdir/flink`
4570                 local unlink_new2=`stat -c %Y $DIR/$tdir/funlink`
4571                 local rename_new2=`stat -c %Y $DIR/$tdir/frename2`
4572
4573                 [ $open_new2 -eq $open_new ] || error "open file reverses mtime"
4574                 [ $link_new2 -eq $link_new ] || error "link file reverses mtime"
4575                 [ $unlink_new2 -eq $unlink_new ] || error "unlink file reverses mtime"
4576                 [ $rename_new2 -eq $rename_new ] || error "rename file reverses mtime"
4577
4578                 cancel_lru_locks $OSC
4579                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4580         done
4581 }
4582 run_test 39b "mtime change on open, link, unlink, rename  ======"
4583
4584 # this should be set to past
4585 TEST_39_MTIME=`date -d "1 year ago" +%s`
4586
4587 # bug 11063
4588 test_39c() {
4589         touch $DIR1/$tfile
4590         sleep 2
4591         local mtime0=`stat -c %Y $DIR1/$tfile`
4592
4593         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4594         local mtime1=`stat -c %Y $DIR1/$tfile`
4595         [ "$mtime1" = $TEST_39_MTIME ] || \
4596                 error "mtime is not set to past: $mtime1, should be $TEST_39_MTIME"
4597
4598         local d1=`date +%s`
4599         echo hello >> $DIR1/$tfile
4600         local d2=`date +%s`
4601         local mtime2=`stat -c %Y $DIR1/$tfile`
4602         [ "$mtime2" -ge "$d1" ] && [ "$mtime2" -le "$d2" ] || \
4603                 error "mtime is not updated on write: $d1 <= $mtime2 <= $d2"
4604
4605         mv $DIR1/$tfile $DIR1/$tfile-1
4606
4607         for (( i=0; i < 2; i++ )) ; do
4608                 local mtime3=`stat -c %Y $DIR1/$tfile-1`
4609                 [ "$mtime2" = "$mtime3" ] || \
4610                         error "mtime ($mtime2) changed (to $mtime3) on rename"
4611
4612                 cancel_lru_locks $OSC
4613                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4614         done
4615 }
4616 run_test 39c "mtime change on rename ==========================="
4617
4618 # bug 21114
4619 test_39d() {
4620         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4621
4622         touch $DIR1/$tfile
4623         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4624
4625         for (( i=0; i < 2; i++ )) ; do
4626                 local mtime=`stat -c %Y $DIR1/$tfile`
4627                 [ $mtime = $TEST_39_MTIME ] || \
4628                         error "mtime($mtime) is not set to $TEST_39_MTIME"
4629
4630                 cancel_lru_locks $OSC
4631                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4632         done
4633 }
4634 run_test 39d "create, utime, stat =============================="
4635
4636 # bug 21114
4637 test_39e() {
4638         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4639
4640         touch $DIR1/$tfile
4641         local mtime1=`stat -c %Y $DIR1/$tfile`
4642
4643         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4644
4645         for (( i=0; i < 2; i++ )) ; do
4646                 local mtime2=`stat -c %Y $DIR1/$tfile`
4647                 [ $mtime2 = $TEST_39_MTIME ] || \
4648                         error "mtime($mtime2) is not set to $TEST_39_MTIME"
4649
4650                 cancel_lru_locks $OSC
4651                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4652         done
4653 }
4654 run_test 39e "create, stat, utime, stat ========================"
4655
4656 # bug 21114
4657 test_39f() {
4658         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4659
4660         touch $DIR1/$tfile
4661         mtime1=`stat -c %Y $DIR1/$tfile`
4662
4663         sleep 2
4664         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4665
4666         for (( i=0; i < 2; i++ )) ; do
4667                 local mtime2=`stat -c %Y $DIR1/$tfile`
4668                 [ $mtime2 = $TEST_39_MTIME ] || \
4669                         error "mtime($mtime2) is not set to $TEST_39_MTIME"
4670
4671                 cancel_lru_locks $OSC
4672                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4673         done
4674 }
4675 run_test 39f "create, stat, sleep, utime, stat ================="
4676
4677 # bug 11063
4678 test_39g() {
4679         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4680
4681         echo hello >> $DIR1/$tfile
4682         local mtime1=`stat -c %Y $DIR1/$tfile`
4683
4684         sleep 2
4685         chmod o+r $DIR1/$tfile
4686
4687         for (( i=0; i < 2; i++ )) ; do
4688                 local mtime2=`stat -c %Y $DIR1/$tfile`
4689                 [ "$mtime1" = "$mtime2" ] || \
4690                         error "lost mtime: $mtime2, should be $mtime1"
4691
4692                 cancel_lru_locks $OSC
4693                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4694         done
4695 }
4696 run_test 39g "write, chmod, stat ==============================="
4697
4698 # bug 11063
4699 test_39h() {
4700         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4701
4702         touch $DIR1/$tfile
4703         sleep 1
4704
4705         local d1=`date`
4706         echo hello >> $DIR1/$tfile
4707         local mtime1=`stat -c %Y $DIR1/$tfile`
4708
4709         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4710         local d2=`date`
4711         if [ "$d1" != "$d2" ]; then
4712                 echo "write and touch not within one second"
4713         else
4714                 for (( i=0; i < 2; i++ )) ; do
4715                         local mtime2=`stat -c %Y $DIR1/$tfile`
4716                         [ "$mtime2" = $TEST_39_MTIME ] || \
4717                                 error "lost mtime: $mtime2, should be $TEST_39_MTIME"
4718
4719                         cancel_lru_locks $OSC
4720                         if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4721                 done
4722         fi
4723 }
4724 run_test 39h "write, utime within one second, stat ============="
4725
4726 test_39i() {
4727         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4728
4729         touch $DIR1/$tfile
4730         sleep 1
4731
4732         echo hello >> $DIR1/$tfile
4733         local mtime1=`stat -c %Y $DIR1/$tfile`
4734
4735         mv $DIR1/$tfile $DIR1/$tfile-1
4736
4737         for (( i=0; i < 2; i++ )) ; do
4738                 local mtime2=`stat -c %Y $DIR1/$tfile-1`
4739
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 39i "write, rename, stat =============================="
4748
4749 test_39j() {
4750         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4751
4752         start_full_debug_logging
4753         touch $DIR1/$tfile
4754         sleep 1
4755
4756         #define OBD_FAIL_OSC_DELAY_SETTIME       0x412
4757         lctl set_param fail_loc=0x80000412
4758         multiop_bg_pause $DIR1/$tfile oO_RDWR:w2097152_c ||
4759                 error "multiop failed"
4760         local multipid=$!
4761         local mtime1=`stat -c %Y $DIR1/$tfile`
4762
4763         mv $DIR1/$tfile $DIR1/$tfile-1
4764
4765         kill -USR1 $multipid
4766         wait $multipid || error "multiop close failed"
4767
4768         for (( i=0; i < 2; i++ )) ; do
4769                 local mtime2=`stat -c %Y $DIR1/$tfile-1`
4770                 [ "$mtime1" = "$mtime2" ] ||
4771                         error "mtime is lost on close: $mtime2, " \
4772                               "should be $mtime1"
4773
4774                 cancel_lru_locks
4775                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4776         done
4777         lctl set_param fail_loc=0
4778         stop_full_debug_logging
4779 }
4780 run_test 39j "write, rename, close, stat ======================="
4781
4782 test_39k() {
4783         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4784
4785         touch $DIR1/$tfile
4786         sleep 1
4787
4788         multiop_bg_pause $DIR1/$tfile oO_RDWR:w2097152_c || error "multiop failed"
4789         local multipid=$!
4790         local mtime1=`stat -c %Y $DIR1/$tfile`
4791
4792         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4793
4794         kill -USR1 $multipid
4795         wait $multipid || error "multiop close failed"
4796
4797         for (( i=0; i < 2; i++ )) ; do
4798                 local mtime2=`stat -c %Y $DIR1/$tfile`
4799
4800                 [ "$mtime2" = $TEST_39_MTIME ] || \
4801                         error "mtime is lost on close: $mtime2, should be $TEST_39_MTIME"
4802
4803                 cancel_lru_locks
4804                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4805         done
4806 }
4807 run_test 39k "write, utime, close, stat ========================"
4808
4809 # this should be set to future
4810 TEST_39_ATIME=`date -d "1 year" +%s`
4811
4812 test_39l() {
4813         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4814         remote_mds_nodsh && skip "remote MDS with nodsh"
4815
4816         local atime_diff=$(do_facet $SINGLEMDS \
4817                                 lctl get_param -n mdd.*MDT0000*.atime_diff)
4818         rm -rf $DIR/$tdir
4819         mkdir_on_mdt0 $DIR/$tdir
4820
4821         # test setting directory atime to future
4822         touch -a -d @$TEST_39_ATIME $DIR/$tdir
4823         local atime=$(stat -c %X $DIR/$tdir)
4824         [ "$atime" = $TEST_39_ATIME ] ||
4825                 error "atime is not set to future: $atime, $TEST_39_ATIME"
4826
4827         # test setting directory atime from future to now
4828         local now=$(date +%s)
4829         touch -a -d @$now $DIR/$tdir
4830
4831         atime=$(stat -c %X $DIR/$tdir)
4832         [ "$atime" -eq "$now"  ] ||
4833                 error "atime is not updated from future: $atime, $now"
4834
4835         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=2
4836         sleep 3
4837
4838         # test setting directory atime when now > dir atime + atime_diff
4839         local d1=$(date +%s)
4840         ls $DIR/$tdir
4841         local d2=$(date +%s)
4842         cancel_lru_locks mdc
4843         atime=$(stat -c %X $DIR/$tdir)
4844         [ "$atime" -ge "$d1" -a "$atime" -le "$d2" ] ||
4845                 error "atime is not updated  : $atime, should be $d2"
4846
4847         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=60
4848         sleep 3
4849
4850         # test not setting directory atime when now < dir atime + atime_diff
4851         ls $DIR/$tdir
4852         cancel_lru_locks mdc
4853         atime=$(stat -c %X $DIR/$tdir)
4854         [ "$atime" -ge "$d1" -a "$atime" -le "$d2" ] ||
4855                 error "atime is updated to $atime, should remain $d1<atime<$d2"
4856
4857         do_facet $SINGLEMDS \
4858                 lctl set_param -n mdd.*MDT0000*.atime_diff=$atime_diff
4859 }
4860 run_test 39l "directory atime update ==========================="
4861
4862 test_39m() {
4863         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4864
4865         touch $DIR1/$tfile
4866         sleep 2
4867         local far_past_mtime=$(date -d "May 29 1953" +%s)
4868         local far_past_atime=$(date -d "Dec 17 1903" +%s)
4869
4870         touch -m -d @$far_past_mtime $DIR1/$tfile
4871         touch -a -d @$far_past_atime $DIR1/$tfile
4872
4873         for (( i=0; i < 2; i++ )) ; do
4874                 local timestamps=$(stat -c "%X %Y" $DIR1/$tfile)
4875                 [ "$timestamps" = "$far_past_atime $far_past_mtime" ] || \
4876                         error "atime or mtime set incorrectly"
4877
4878                 cancel_lru_locks $OSC
4879                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4880         done
4881 }
4882 run_test 39m "test atime and mtime before 1970"
4883
4884 test_39n() { # LU-3832
4885         remote_mds_nodsh && skip "remote MDS with nodsh"
4886
4887         local atime_diff=$(do_facet $SINGLEMDS \
4888                 lctl get_param -n mdd.*MDT0000*.atime_diff)
4889         local atime0
4890         local atime1
4891         local atime2
4892
4893         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=1
4894
4895         rm -rf $DIR/$tfile
4896         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 status=noxfer
4897         atime0=$(stat -c %X $DIR/$tfile)
4898
4899         sleep 5
4900         $MULTIOP $DIR/$tfile oO_RDONLY:O_NOATIME:r4096c
4901         atime1=$(stat -c %X $DIR/$tfile)
4902
4903         sleep 5
4904         cancel_lru_locks mdc
4905         cancel_lru_locks osc
4906         $MULTIOP $DIR/$tfile oO_RDONLY:O_NOATIME:r4096c
4907         atime2=$(stat -c %X $DIR/$tfile)
4908
4909         do_facet $SINGLEMDS \
4910                 lctl set_param -n mdd.*MDT0000*.atime_diff=$atime_diff
4911
4912         [ "$atime0" -eq "$atime1" ] || error "atime0 $atime0 != atime1 $atime1"
4913         [ "$atime1" -eq "$atime2" ] || error "atime0 $atime0 != atime1 $atime1"
4914 }
4915 run_test 39n "check that O_NOATIME is honored"
4916
4917 test_39o() {
4918         TESTDIR=$DIR/$tdir/$tfile
4919         [ -e $TESTDIR ] && rm -rf $TESTDIR
4920         mkdir -p $TESTDIR
4921         cd $TESTDIR
4922         links1=2
4923         ls
4924         mkdir a b
4925         ls
4926         links2=$(stat -c %h .)
4927         [ $(($links1 + 2)) != $links2 ] &&
4928                 error "wrong links count $(($links1 + 2)) != $links2"
4929         rmdir b
4930         links3=$(stat -c %h .)
4931         [ $(($links1 + 1)) != $links3 ] &&
4932                 error "wrong links count $links1 != $links3"
4933         return 0
4934 }
4935 run_test 39o "directory cached attributes updated after create"
4936
4937 test_39p() {
4938         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
4939
4940         local MDTIDX=1
4941         TESTDIR=$DIR/$tdir/$tdir
4942         [ -e $TESTDIR ] && rm -rf $TESTDIR
4943         test_mkdir -p $TESTDIR
4944         cd $TESTDIR
4945         links1=2
4946         ls
4947         test_mkdir -i $MDTIDX $TESTDIR/remote_dir1
4948         test_mkdir -i $MDTIDX $TESTDIR/remote_dir2
4949         ls
4950         links2=$(stat -c %h .)
4951         [ $(($links1 + 2)) != $links2 ] &&
4952                 error "wrong links count $(($links1 + 2)) != $links2"
4953         rmdir remote_dir2
4954         links3=$(stat -c %h .)
4955         [ $(($links1 + 1)) != $links3 ] &&
4956                 error "wrong links count $links1 != $links3"
4957         return 0
4958 }
4959 run_test 39p "remote directory cached attributes updated after create ========"
4960
4961 test_39r() {
4962         [ $OST1_VERSION -ge $(version_code 2.13.52) ] ||
4963                 skip "no atime update on old OST"
4964         if [ "$ost1_FSTYPE" != ldiskfs ]; then
4965                 skip_env "ldiskfs only test"
4966         fi
4967
4968         local saved_adiff
4969         saved_adiff=$(do_facet ost1 \
4970                 lctl get_param -n obdfilter.*OST0000.atime_diff)
4971         stack_trap "do_facet ost1 \
4972                 lctl set_param obdfilter.*.atime_diff=$saved_adiff"
4973
4974         do_facet ost1 "lctl set_param obdfilter.*.atime_diff=5"
4975
4976         $LFS setstripe -i 0 $DIR/$tfile
4977         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 ||
4978                 error "can't write initial file"
4979         cancel_lru_locks osc
4980
4981         # exceed atime_diff and access file
4982         sleep 6
4983         dd if=$DIR/$tfile of=/dev/null bs=4k count=1 ||
4984                 error "can't udpate atime"
4985
4986         local atime_cli=$(stat -c %X $DIR/$tfile)
4987         echo "client atime: $atime_cli"
4988         # allow atime update to be written to device
4989         do_facet ost1 "$LCTL set_param -n osd*.*OST*.force_sync 1"
4990         sleep 5
4991
4992         local ostdev=$(ostdevname 1)
4993         local fid=($(lfs getstripe -y $DIR/$tfile |
4994                         awk '/l_fid:/ { print $2 }' | tr ':' ' '))
4995         local objpath="O/0/d$((${fid[1]} % 32))/$((${fid[1]}))"
4996         local cmd="debugfs -c -R \\\"stat $objpath\\\" $ostdev"
4997
4998         echo "OST atime: $(do_facet ost1 "$cmd" |& grep atime)"
4999         local atime_ost=$(do_facet ost1 "$cmd" |&
5000                           awk -F'[: ]' '/atime:/ { print $4 }')
5001         (( atime_cli == atime_ost )) ||
5002                 error "atime on client $atime_cli != ost $atime_ost"
5003 }
5004 run_test 39r "lazy atime update on OST"
5005
5006 test_39q() { # LU-8041
5007         local testdir=$DIR/$tdir
5008         mkdir -p $testdir
5009         multiop_bg_pause $testdir D_c || error "multiop failed"
5010         local multipid=$!
5011         cancel_lru_locks mdc
5012         kill -USR1 $multipid
5013         local atime=$(stat -c %X $testdir)
5014         [ "$atime" -ne 0 ] || error "atime is zero"
5015 }
5016 run_test 39q "close won't zero out atime"
5017
5018 test_40() {
5019         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1
5020         $RUNAS $OPENFILE -f O_WRONLY:O_TRUNC $DIR/$tfile &&
5021                 error "openfile O_WRONLY:O_TRUNC $tfile failed"
5022         $CHECKSTAT -t file -s 4096 $DIR/$tfile ||
5023                 error "$tfile is not 4096 bytes in size"
5024 }
5025 run_test 40 "failed open(O_TRUNC) doesn't truncate ============="
5026
5027 test_41() {
5028         # bug 1553
5029         small_write $DIR/f41 18
5030 }
5031 run_test 41 "test small file write + fstat ====================="
5032
5033 count_ost_writes() {
5034         lctl get_param -n ${OSC}.*.stats |
5035                 awk -vwrites=0 '/ost_write/ { writes += $2 } \
5036                         END { printf("%0.0f", writes) }'
5037 }
5038
5039 # decent default
5040 WRITEBACK_SAVE=500
5041 DIRTY_RATIO_SAVE=40
5042 MAX_DIRTY_RATIO=50
5043 BG_DIRTY_RATIO_SAVE=10
5044 MAX_BG_DIRTY_RATIO=25
5045
5046 start_writeback() {
5047         trap 0
5048         # in 2.6, restore /proc/sys/vm/dirty_writeback_centisecs,
5049         # dirty_ratio, dirty_background_ratio
5050         if [ -f /proc/sys/vm/dirty_writeback_centisecs ]; then
5051                 sysctl -w vm.dirty_writeback_centisecs=$WRITEBACK_SAVE
5052                 sysctl -w vm.dirty_background_ratio=$BG_DIRTY_RATIO_SAVE
5053                 sysctl -w vm.dirty_ratio=$DIRTY_RATIO_SAVE
5054         else
5055                 # if file not here, we are a 2.4 kernel
5056                 kill -CONT `pidof kupdated`
5057         fi
5058 }
5059
5060 stop_writeback() {
5061         # setup the trap first, so someone cannot exit the test at the
5062         # exact wrong time and mess up a machine
5063         trap start_writeback EXIT
5064         # in 2.6, save and 0 /proc/sys/vm/dirty_writeback_centisecs
5065         if [ -f /proc/sys/vm/dirty_writeback_centisecs ]; then
5066                 WRITEBACK_SAVE=`sysctl -n vm.dirty_writeback_centisecs`
5067                 sysctl -w vm.dirty_writeback_centisecs=0
5068                 sysctl -w vm.dirty_writeback_centisecs=0
5069                 # save and increase /proc/sys/vm/dirty_ratio
5070                 DIRTY_RATIO_SAVE=`sysctl -n vm.dirty_ratio`
5071                 sysctl -w vm.dirty_ratio=$MAX_DIRTY_RATIO
5072                 # save and increase /proc/sys/vm/dirty_background_ratio
5073                 BG_DIRTY_RATIO_SAVE=`sysctl -n vm.dirty_background_ratio`
5074                 sysctl -w vm.dirty_background_ratio=$MAX_BG_DIRTY_RATIO
5075         else
5076                 # if file not here, we are a 2.4 kernel
5077                 kill -STOP `pidof kupdated`
5078         fi
5079 }
5080
5081 # ensure that all stripes have some grant before we test client-side cache
5082 setup_test42() {
5083         for i in `seq -f $DIR/f42-%g 1 $OSTCOUNT`; do
5084                 dd if=/dev/zero of=$i bs=4k count=1
5085                 rm $i
5086         done
5087 }
5088
5089 # Tests 42* verify that our behaviour is correct WRT caching, file closure,
5090 # file truncation, and file removal.
5091 test_42a() {
5092         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5093
5094         setup_test42
5095         cancel_lru_locks $OSC
5096         stop_writeback
5097         sync; sleep 1; sync # just to be safe
5098         BEFOREWRITES=`count_ost_writes`
5099         lctl get_param -n osc.*[oO][sS][cC][_-]*.cur_grant_bytes | grep "[0-9]"
5100         dd if=/dev/zero of=$DIR/f42a bs=1024 count=100
5101         AFTERWRITES=`count_ost_writes`
5102         [ $BEFOREWRITES -eq $AFTERWRITES ] || \
5103                 error "$BEFOREWRITES < $AFTERWRITES"
5104         start_writeback
5105 }
5106 run_test 42a "ensure that we don't flush on close"
5107
5108 test_42b() {
5109         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5110
5111         setup_test42
5112         cancel_lru_locks $OSC
5113         stop_writeback
5114         sync
5115         dd if=/dev/zero of=$DIR/f42b bs=1024 count=100
5116         BEFOREWRITES=$(count_ost_writes)
5117         $MUNLINK $DIR/f42b || error "$MUNLINK $DIR/f42b: $?"
5118         AFTERWRITES=$(count_ost_writes)
5119         if [[ $BEFOREWRITES -lt $AFTERWRITES ]]; then
5120                 error "$BEFOREWRITES < $AFTERWRITES on unlink"
5121         fi
5122         BEFOREWRITES=$(count_ost_writes)
5123         sync || error "sync: $?"
5124         AFTERWRITES=$(count_ost_writes)
5125         if [[ $BEFOREWRITES -lt $AFTERWRITES ]]; then
5126                 error "$BEFOREWRITES < $AFTERWRITES on sync"
5127         fi
5128         dmesg | grep 'error from obd_brw_async' && error 'error writing back'
5129         start_writeback
5130         return 0
5131 }
5132 run_test 42b "test destroy of file with cached dirty data ======"
5133
5134 # if these tests just want to test the effect of truncation,
5135 # they have to be very careful.  consider:
5136 # - the first open gets a {0,EOF}PR lock
5137 # - the first write conflicts and gets a {0, count-1}PW
5138 # - the rest of the writes are under {count,EOF}PW
5139 # - the open for truncate tries to match a {0,EOF}PR
5140 #   for the filesize and cancels the PWs.
5141 # any number of fixes (don't get {0,EOF} on open, match
5142 # composite locks, do smarter file size management) fix
5143 # this, but for now we want these tests to verify that
5144 # the cancellation with truncate intent works, so we
5145 # start the file with a full-file pw lock to match against
5146 # until the truncate.
5147 trunc_test() {
5148         test=$1
5149         file=$DIR/$test
5150         offset=$2
5151         cancel_lru_locks $OSC
5152         stop_writeback
5153         # prime the file with 0,EOF PW to match
5154         touch $file
5155         $TRUNCATE $file 0
5156         sync; sync
5157         # now the real test..
5158         dd if=/dev/zero of=$file bs=1024 count=100
5159         BEFOREWRITES=`count_ost_writes`
5160         $TRUNCATE $file $offset
5161         cancel_lru_locks $OSC
5162         AFTERWRITES=`count_ost_writes`
5163         start_writeback
5164 }
5165
5166 test_42c() {
5167         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5168
5169         trunc_test 42c 1024
5170         [ $BEFOREWRITES -eq $AFTERWRITES ] &&
5171                 error "beforewrites $BEFOREWRITES == afterwrites $AFTERWRITES on truncate"
5172         rm $file
5173 }
5174 run_test 42c "test partial truncate of file with cached dirty data"
5175
5176 test_42d() {
5177         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5178
5179         trunc_test 42d 0
5180         [ $BEFOREWRITES -eq $AFTERWRITES ] ||
5181                 error "beforewrites $BEFOREWRITES != afterwrites $AFTERWRITES on truncate"
5182         rm $file
5183 }
5184 run_test 42d "test complete truncate of file with cached dirty data"
5185
5186 test_42e() { # bug22074
5187         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5188
5189         local TDIR=$DIR/${tdir}e
5190         local pages=16 # hardcoded 16 pages, don't change it.
5191         local files=$((OSTCOUNT * 500)) # hopefully 500 files on each OST
5192         local proc_osc0="osc.${FSNAME}-OST0000-osc-[^MDT]*"
5193         local max_dirty_mb
5194         local warmup_files
5195
5196         test_mkdir $DIR/${tdir}e
5197         $LFS setstripe -c 1 $TDIR
5198         createmany -o $TDIR/f $files
5199
5200         max_dirty_mb=$($LCTL get_param -n $proc_osc0/max_dirty_mb)
5201
5202         # we assume that with $OSTCOUNT files, at least one of them will
5203         # be allocated on OST0.
5204         warmup_files=$((OSTCOUNT * max_dirty_mb))
5205         createmany -o $TDIR/w $warmup_files
5206
5207         # write a large amount of data into one file and sync, to get good
5208         # avail_grant number from OST.
5209         for ((i=0; i<$warmup_files; i++)); do
5210                 idx=$($LFS getstripe -i $TDIR/w$i)
5211                 [ $idx -ne 0 ] && continue
5212                 dd if=/dev/zero of=$TDIR/w$i bs="$max_dirty_mb"M count=1
5213                 break
5214         done
5215         [[ $i -gt $warmup_files ]] && error "OST0 is still cold"
5216         sync
5217         $LCTL get_param $proc_osc0/cur_dirty_bytes
5218         $LCTL get_param $proc_osc0/cur_grant_bytes
5219
5220         # create as much dirty pages as we can while not to trigger the actual
5221         # RPCs directly. but depends on the env, VFS may trigger flush during this
5222         # period, hopefully we are good.
5223         for ((i=0; i<$warmup_files; i++)); do
5224                 idx=$($LFS getstripe -i $TDIR/w$i)
5225                 [ $idx -ne 0 ] && continue
5226                 dd if=/dev/zero of=$TDIR/w$i bs=1M count=1 2>/dev/null
5227         done
5228         $LCTL get_param $proc_osc0/cur_dirty_bytes
5229         $LCTL get_param $proc_osc0/cur_grant_bytes
5230
5231         # perform the real test
5232         $LCTL set_param $proc_osc0/rpc_stats 0
5233         for ((;i<$files; i++)); do
5234                 [ $($LFS getstripe -i $TDIR/f$i) -eq 0 ] || continue
5235                 dd if=/dev/zero of=$TDIR/f$i bs=$PAGE_SIZE count=$pages 2>/dev/null
5236         done
5237         sync
5238         $LCTL get_param $proc_osc0/rpc_stats
5239
5240         local percent=0
5241         local have_ppr=false
5242         $LCTL get_param $proc_osc0/rpc_stats |
5243                 while read PPR RRPC RPCT RCUM BAR WRPC WPCT WCUM; do
5244                         # skip lines until we are at the RPC histogram data
5245                         [ "$PPR" == "pages" ] && have_ppr=true && continue
5246                         $have_ppr || continue
5247
5248                         # we only want the percent stat for < 16 pages
5249                         [[ $(echo $PPR | tr -d ':') -ge $pages ]] && break
5250
5251                         percent=$((percent + WPCT))
5252                         if [[ $percent -gt 15 ]]; then
5253                                 error "less than 16-pages write RPCs" \
5254                                       "$percent% > 15%"
5255                                 break
5256                         fi
5257                 done
5258         rm -rf $TDIR
5259 }
5260 run_test 42e "verify sub-RPC writes are not done synchronously"
5261
5262 test_43A() { # was test_43
5263         test_mkdir $DIR/$tdir
5264         cp -p /bin/ls $DIR/$tdir/$tfile
5265         $MULTIOP $DIR/$tdir/$tfile Ow_c &
5266         pid=$!
5267         # give multiop a chance to open
5268         sleep 1
5269
5270         $DIR/$tdir/$tfile && error "execute $DIR/$tdir/$tfile succeeded" || true
5271         kill -USR1 $pid
5272         # Wait for multiop to exit
5273         wait $pid
5274 }
5275 run_test 43A "execution of file opened for write should return -ETXTBSY"
5276
5277 test_43a() {
5278         test_mkdir $DIR/$tdir
5279         cp -p $(which sleep) $DIR/$tdir/sleep || error "can't copy"
5280         $DIR/$tdir/sleep 60 &
5281         SLEEP_PID=$!
5282         # Make sure exec of $tdir/sleep wins race with truncate
5283         sleep 1
5284         $MULTIOP $DIR/$tdir/sleep Oc && error "expected error, got success"
5285         kill $SLEEP_PID
5286 }
5287 run_test 43a "open(RDWR) of file being executed should return -ETXTBSY"
5288
5289 test_43b() {
5290         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5291
5292         test_mkdir $DIR/$tdir
5293         cp -p $(which sleep) $DIR/$tdir/sleep || error "can't copy"
5294         $DIR/$tdir/sleep 60 &
5295         SLEEP_PID=$!
5296         # Make sure exec of $tdir/sleep wins race with truncate
5297         sleep 1
5298         $TRUNCATE $DIR/$tdir/sleep 0 && error "expected error, got success"
5299         kill $SLEEP_PID
5300 }
5301 run_test 43b "truncate of file being executed should return -ETXTBSY"
5302
5303 test_43c() {
5304         local testdir="$DIR/$tdir"
5305         test_mkdir $testdir
5306         cp $SHELL $testdir/
5307         ( cd $(dirname $SHELL) && md5sum $(basename $SHELL) ) |
5308                 ( cd $testdir && md5sum -c )
5309 }
5310 run_test 43c "md5sum of copy into lustre"
5311
5312 test_44A() { # was test_44
5313         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
5314
5315         dd if=/dev/zero of=$DIR/f1 bs=4k count=1 seek=1023
5316         dd if=$DIR/f1 bs=4k count=1 > /dev/null
5317 }
5318 run_test 44A "zero length read from a sparse stripe"
5319
5320 test_44a() {
5321         local nstripe=$($LFS getstripe -c -d $DIR)
5322         [ -z "$nstripe" ] && skip "can't get stripe info"
5323         [[ $nstripe -gt $OSTCOUNT ]] &&
5324                 skip "Wrong default stripe_count: $nstripe OSTCOUNT: $OSTCOUNT"
5325
5326         local stride=$($LFS getstripe -S -d $DIR)
5327         if [[ $nstripe -eq 0 || $nstripe -eq -1 ]]; then
5328                 nstripe=$($LFS df $DIR | grep OST: | wc -l)
5329         fi
5330
5331         OFFSETS="0 $((stride/2)) $((stride-1))"
5332         for offset in $OFFSETS; do
5333                 for i in $(seq 0 $((nstripe-1))); do
5334                         local GLOBALOFFSETS=""
5335                         # size in Bytes
5336                         local size=$((((i + 2 * $nstripe )*$stride + $offset)))
5337                         local myfn=$DIR/d44a-$size
5338                         echo "--------writing $myfn at $size"
5339                         ll_sparseness_write $myfn $size ||
5340                                 error "ll_sparseness_write"
5341                         GLOBALOFFSETS="$GLOBALOFFSETS $size"
5342                         ll_sparseness_verify $myfn $GLOBALOFFSETS ||
5343                                 error "ll_sparseness_verify $GLOBALOFFSETS"
5344
5345                         for j in $(seq 0 $((nstripe-1))); do
5346                                 # size in Bytes
5347                                 size=$((((j + $nstripe )*$stride + $offset)))
5348                                 ll_sparseness_write $myfn $size ||
5349                                         error "ll_sparseness_write"
5350                                 GLOBALOFFSETS="$GLOBALOFFSETS $size"
5351                         done
5352                         ll_sparseness_verify $myfn $GLOBALOFFSETS ||
5353                                 error "ll_sparseness_verify $GLOBALOFFSETS"
5354                         rm -f $myfn
5355                 done
5356         done
5357 }
5358 run_test 44a "test sparse pwrite ==============================="
5359
5360 dirty_osc_total() {
5361         tot=0
5362         for d in `lctl get_param -n ${OSC}.*.cur_dirty_bytes`; do
5363                 tot=$(($tot + $d))
5364         done
5365         echo $tot
5366 }
5367 do_dirty_record() {
5368         before=`dirty_osc_total`
5369         echo executing "\"$*\""
5370         eval $*
5371         after=`dirty_osc_total`
5372         echo before $before, after $after
5373 }
5374 test_45() {
5375         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5376
5377         f="$DIR/f45"
5378         # Obtain grants from OST if it supports it
5379         echo blah > ${f}_grant
5380         stop_writeback
5381         sync
5382         do_dirty_record "echo blah > $f"
5383         [[ $before -eq $after ]] && error "write wasn't cached"
5384         do_dirty_record "> $f"
5385         [[ $before -gt $after ]] || error "truncate didn't lower dirty count"
5386         do_dirty_record "echo blah > $f"
5387         [[ $before -eq $after ]] && error "write wasn't cached"
5388         do_dirty_record "sync"
5389         [[ $before -gt $after ]] || error "writeback didn't lower dirty count"
5390         do_dirty_record "echo blah > $f"
5391         [[ $before -eq $after ]] && error "write wasn't cached"
5392         do_dirty_record "cancel_lru_locks osc"
5393         [[ $before -gt $after ]] ||
5394                 error "lock cancellation didn't lower dirty count"
5395         start_writeback
5396 }
5397 run_test 45 "osc io page accounting ============================"
5398
5399 # in a 2 stripe file (lov.sh), page 1023 maps to page 511 in its object.  this
5400 # test tickles a bug where re-dirtying a page was failing to be mapped to the
5401 # objects offset and an assert hit when an rpc was built with 1023's mapped
5402 # offset 511 and 511's raw 511 offset. it also found general redirtying bugs.
5403 test_46() {
5404         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5405
5406         f="$DIR/f46"
5407         stop_writeback
5408         sync
5409         dd if=/dev/zero of=$f bs=$PAGE_SIZE seek=511 count=1
5410         sync
5411         dd conv=notrunc if=/dev/zero of=$f bs=$PAGE_SIZE seek=1023 count=1
5412         dd conv=notrunc if=/dev/zero of=$f bs=$PAGE_SIZE seek=511 count=1
5413         sync
5414         start_writeback
5415 }
5416 run_test 46 "dirtying a previously written page ================"
5417
5418 # test_47 is removed "Device nodes check" is moved to test_28
5419
5420 test_48a() { # bug 2399
5421         [ "$mds1_FSTYPE" = "zfs" ] &&
5422         [ $MDS1_VERSION -lt $(version_code 2.3.63) ] &&
5423                 skip "MDS prior to 2.3.63 handle ZFS dir .. incorrectly"
5424
5425         test_mkdir $DIR/$tdir
5426         cd $DIR/$tdir
5427         mv $DIR/$tdir $DIR/$tdir.new || error "move directory failed"
5428         test_mkdir $DIR/$tdir
5429         touch foo || error "'touch foo' failed after recreating cwd"
5430         test_mkdir bar
5431         touch .foo || error "'touch .foo' failed after recreating cwd"
5432         test_mkdir .bar
5433         ls . > /dev/null || error "'ls .' failed after recreating cwd"
5434         ls .. > /dev/null || error "'ls ..' failed after removing cwd"
5435         cd . || error "'cd .' failed after recreating cwd"
5436         mkdir . && error "'mkdir .' worked after recreating cwd"
5437         rmdir . && error "'rmdir .' worked after recreating cwd"
5438         ln -s . baz || error "'ln -s .' failed after recreating cwd"
5439         cd .. || error "'cd ..' failed after recreating cwd"
5440 }
5441 run_test 48a "Access renamed working dir (should return errors)="
5442
5443 test_48b() { # bug 2399
5444         rm -rf $DIR/$tdir
5445         test_mkdir $DIR/$tdir
5446         cd $DIR/$tdir
5447         rmdir $DIR/$tdir || error "remove cwd $DIR/$tdir failed"
5448         touch foo && error "'touch foo' worked after removing cwd"
5449         mkdir foo && error "'mkdir foo' worked after removing cwd"
5450         touch .foo && error "'touch .foo' worked after removing cwd"
5451         mkdir .foo && error "'mkdir .foo' worked after removing cwd"
5452         ls . > /dev/null && error "'ls .' worked after removing cwd"
5453         ls .. > /dev/null || error "'ls ..' failed after removing cwd"
5454         mkdir . && error "'mkdir .' worked after removing cwd"
5455         rmdir . && error "'rmdir .' worked after removing cwd"
5456         ln -s . foo && error "'ln -s .' worked after removing cwd"
5457         cd .. || echo "'cd ..' failed after removing cwd `pwd`"  #bug 3517
5458 }
5459 run_test 48b "Access removed working dir (should return errors)="
5460
5461 test_48c() { # bug 2350
5462         #lctl set_param debug=-1
5463         #set -vx
5464         rm -rf $DIR/$tdir
5465         test_mkdir -p $DIR/$tdir/dir
5466         cd $DIR/$tdir/dir
5467         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
5468         $TRACE touch foo && error "touch foo worked after removing cwd"
5469         $TRACE mkdir foo && error "'mkdir foo' worked after removing cwd"
5470         touch .foo && error "touch .foo worked after removing cwd"
5471         mkdir .foo && error "mkdir .foo worked after removing cwd"
5472         $TRACE ls . && error "'ls .' worked after removing cwd"
5473         $TRACE ls .. || error "'ls ..' failed after removing cwd"
5474         $TRACE mkdir . && error "'mkdir .' worked after removing cwd"
5475         $TRACE rmdir . && error "'rmdir .' worked after removing cwd"
5476         $TRACE ln -s . foo && error "'ln -s .' worked after removing cwd"
5477         $TRACE cd .. || echo "'cd ..' failed after removing cwd `pwd`" #bug 3415
5478 }
5479 run_test 48c "Access removed working subdir (should return errors)"
5480
5481 test_48d() { # bug 2350
5482         #lctl set_param debug=-1
5483         #set -vx
5484         rm -rf $DIR/$tdir
5485         test_mkdir -p $DIR/$tdir/dir
5486         cd $DIR/$tdir/dir
5487         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
5488         $TRACE rmdir $DIR/$tdir || error "remove parent $DIR/$tdir failed"
5489         $TRACE touch foo && error "'touch foo' worked after removing parent"
5490         $TRACE mkdir foo && error "mkdir foo worked after removing parent"
5491         touch .foo && error "'touch .foo' worked after removing parent"
5492         mkdir .foo && error "mkdir .foo worked after removing parent"
5493         $TRACE ls . && error "'ls .' worked after removing parent"
5494         $TRACE ls .. && error "'ls ..' worked after removing parent"
5495         $TRACE mkdir . && error "'mkdir .' worked after removing parent"
5496         $TRACE rmdir . && error "'rmdir .' worked after removing parent"
5497         $TRACE ln -s . foo && error "'ln -s .' worked after removing parent"
5498         true
5499 }
5500 run_test 48d "Access removed parent subdir (should return errors)"
5501
5502 test_48e() { # bug 4134
5503         #lctl set_param debug=-1
5504         #set -vx
5505         rm -rf $DIR/$tdir
5506         test_mkdir -p $DIR/$tdir/dir
5507         cd $DIR/$tdir/dir
5508         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
5509         $TRACE rmdir $DIR/$tdir || error "remove parent $DIR/$tdir failed"
5510         $TRACE touch $DIR/$tdir || error "'touch $DIR/$tdir' failed"
5511         $TRACE chmod +x $DIR/$tdir || error "'chmod +x $DIR/$tdir' failed"
5512         # On a buggy kernel addition of "touch foo" after cd .. will
5513         # produce kernel oops in lookup_hash_it
5514         touch ../foo && error "'cd ..' worked after recreate parent"
5515         cd $DIR
5516         $TRACE rm $DIR/$tdir || error "rm '$DIR/$tdir' failed"
5517 }
5518 run_test 48e "Access to recreated parent subdir (should return errors)"
5519
5520 test_48f() {
5521         [[ $MDS1_VERSION -ge $(version_code 2.13.55) ]] ||
5522                 skip "need MDS >= 2.13.55"
5523         [[ $MDSCOUNT -ge 2 ]] || skip "needs >= 2 MDTs"
5524         [[ "$(facet_host mds1)" != "$(facet_host mds2)" ]] ||
5525                 skip "needs different host for mdt1 mdt2"
5526         [[ $(facet_fstype mds1) == ldiskfs ]] || skip "ldiskfs only"
5527
5528         $LFS mkdir -i0 $DIR/$tdir
5529         $LFS mkdir -i 1 $DIR/$tdir/sub1 $DIR/$tdir/sub2 $DIR/$tdir/sub3
5530
5531         for d in sub1 sub2 sub3; do
5532                 #define OBD_FAIL_OSD_REF_DEL    0x19c
5533                 do_facet mds1 $LCTL set_param fail_loc=0x8000019c
5534                 rm -rf $DIR/$tdir/$d && error "rm $d should fail"
5535         done
5536
5537         rm -d --interactive=never $DIR/$tdir || error "rm $tdir fail"
5538 }
5539 run_test 48f "non-zero nlink dir unlink won't LBUG()"
5540
5541 test_49() { # LU-1030
5542         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5543         remote_ost_nodsh && skip "remote OST with nodsh"
5544
5545         # get ost1 size - $FSNAME-OST0000
5546         ost1_size=$(do_facet ost1 $LFS df | grep ${ost1_svc} |
5547                 awk '{ print $4 }')
5548         # write 800M at maximum
5549         [[ $ost1_size -lt 2 ]] && ost1_size=2
5550         [[ $ost1_size -gt 819200 ]] && ost1_size=819200
5551
5552         $LFS setstripe -c 1 -i 0 $DIR/$tfile
5553         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((ost1_size >> 2)) &
5554         local dd_pid=$!
5555
5556         # change max_pages_per_rpc while writing the file
5557         local osc1_mppc=osc.$(get_osc_import_name client ost1).max_pages_per_rpc
5558         local orig_mppc=$($LCTL get_param -n $osc1_mppc)
5559         # loop until dd process exits
5560         while ps ax -opid | grep -wq $dd_pid; do
5561                 $LCTL set_param $osc1_mppc=$((RANDOM % 256 + 1))
5562                 sleep $((RANDOM % 5 + 1))
5563         done
5564         # restore original max_pages_per_rpc
5565         $LCTL set_param $osc1_mppc=$orig_mppc
5566         rm $DIR/$tfile || error "rm $DIR/$tfile failed"
5567 }
5568 run_test 49 "Change max_pages_per_rpc won't break osc extent"
5569
5570 test_50() {
5571         # bug 1485
5572         test_mkdir $DIR/$tdir
5573         cd $DIR/$tdir
5574         ls /proc/$$/cwd || error "ls /proc/$$/cwd failed"
5575 }
5576 run_test 50 "special situations: /proc symlinks  ==============="
5577
5578 test_51a() {    # was test_51
5579         # bug 1516 - create an empty entry right after ".." then split dir
5580         test_mkdir -c1 $DIR/$tdir
5581         touch $DIR/$tdir/foo
5582         $MCREATE $DIR/$tdir/bar
5583         rm $DIR/$tdir/foo
5584         createmany -m $DIR/$tdir/longfile 201
5585         FNUM=202
5586         while [[ $(ls -sd $DIR/$tdir | awk '{ print $1 }') -eq 4 ]]; do
5587                 $MCREATE $DIR/$tdir/longfile$FNUM
5588                 FNUM=$(($FNUM + 1))
5589                 echo -n "+"
5590         done
5591         echo
5592         ls -l $DIR/$tdir > /dev/null || error "ls -l $DIR/$tdir failed"
5593 }
5594 run_test 51a "special situations: split htree with empty entry =="
5595
5596 cleanup_print_lfs_df () {
5597         trap 0
5598         $LFS df
5599         $LFS df -i
5600 }
5601
5602 test_51b() {
5603         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5604
5605         local dir=$DIR/$tdir
5606         local nrdirs=$((65536 + 100))
5607
5608         # cleanup the directory
5609         rm -fr $dir
5610
5611         mkdir_on_mdt -i $((RANDOM % MDSCOUNT)) $dir
5612
5613         $LFS df
5614         $LFS df -i
5615         local mdtidx=$(printf "%04x" $($LFS getstripe -m $dir))
5616         local numfree=$(lctl get_param -n mdc.$FSNAME-MDT$mdtidx*.filesfree)
5617         [[ $numfree -lt $nrdirs ]] &&
5618                 skip "not enough free inodes ($numfree) on MDT$mdtidx"
5619
5620         # need to check free space for the directories as well
5621         local blkfree=$(lctl get_param -n mdc.$FSNAME-MDT$mdtidx*.kbytesavail)
5622         numfree=$(( blkfree / $(fs_inode_ksize) ))
5623         [[ $numfree -lt $nrdirs ]] && skip "not enough blocks ($numfree)"
5624
5625         trap cleanup_print_lfs_df EXIT
5626
5627         # create files
5628         createmany -d $dir/d $nrdirs || {
5629                 unlinkmany $dir/d $nrdirs
5630                 error "failed to create $nrdirs subdirs in MDT$mdtidx:$dir"
5631         }
5632
5633         # really created :
5634         nrdirs=$(ls -U $dir | wc -l)
5635
5636         # unlink all but 100 subdirectories, then check it still works
5637         local left=100
5638         local delete=$((nrdirs - left))
5639
5640         $LFS df
5641         $LFS df -i
5642
5643         # for ldiskfs the nlink count should be 1, but this is OSD specific
5644         # and so this is listed for informational purposes only
5645         echo "nlink before: $(stat -c %h $dir), created before: $nrdirs"
5646         unlinkmany -d $dir/d $delete ||
5647                 error "unlink of first $delete subdirs failed"
5648
5649         echo "nlink between: $(stat -c %h $dir)"
5650         local found=$(ls -U $dir | wc -l)
5651         [ $found -ne $left ] &&
5652                 error "can't find subdirs: found only $found, expected $left"
5653
5654         unlinkmany -d $dir/d $delete $left ||
5655                 error "unlink of second $left subdirs failed"
5656         # regardless of whether the backing filesystem tracks nlink accurately
5657         # or not, the nlink count shouldn't be more than "." and ".." here
5658         local after=$(stat -c %h $dir)
5659         [[ $after -gt 2 ]] && error "nlink after: $after > 2" ||
5660                 echo "nlink after: $after"
5661
5662         cleanup_print_lfs_df
5663 }
5664 run_test 51b "exceed 64k subdirectory nlink limit on create, verify unlink"
5665
5666 test_51d() {
5667         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5668         [[ $OSTCOUNT -lt 3 ]] && skip_env "needs >= 3 OSTs"
5669         local qos_old
5670
5671         test_mkdir $DIR/$tdir
5672         $LFS setstripe -c $OSTCOUNT $DIR/$tdir
5673
5674         qos_old=$(do_facet mds1 \
5675                 "$LCTL get_param -n lod.$FSNAME-*.qos_threshold_rr" | head -n 1)
5676         do_nodes $(comma_list $(mdts_nodes)) \
5677                 "$LCTL set_param lod.$FSNAME-*.qos_threshold_rr=100"
5678         stack_trap "do_nodes $(comma_list $(mdts_nodes)) \
5679                 '$LCTL set_param lod.$FSNAME-*.qos_threshold_rr=${qos_old%%%}'"
5680
5681         createmany -o $DIR/$tdir/t- 1000
5682         $LFS getstripe $DIR/$tdir > $TMP/$tfile
5683         for ((n = 0; n < $OSTCOUNT; n++)); do
5684                 objs[$n]=$(awk -vobjs=0 '($1 == '$n') { objs += 1 } \
5685                            END { printf("%0.0f", objs) }' $TMP/$tfile)
5686                 objs0[$n]=$(grep -A 1 idx $TMP/$tfile | awk -vobjs=0 \
5687                             '($1 == '$n') { objs += 1 } \
5688                             END { printf("%0.0f", objs) }')
5689                 log "OST$n has ${objs[$n]} objects, ${objs0[$n]} are index 0"
5690         done
5691         unlinkmany $DIR/$tdir/t- 1000
5692
5693         nlast=0
5694         for ((n = 0; n < $OSTCOUNT; n++)); do
5695                 (( ${objs[$n]} > ${objs[$nlast]} * 4 / 5 )) ||
5696                         { $LFS df && $LFS df -i &&
5697                         error "OST $n has fewer objects vs. OST $nlast" \
5698                               " (${objs[$n]} < ${objs[$nlast]}"; }
5699                 (( ${objs[$n]} < ${objs[$nlast]} * 5 / 4 )) ||
5700                         { $LFS df && $LFS df -i &&
5701                         error "OST $n has fewer objects vs. OST $nlast" \
5702                               " (${objs[$n]} < ${objs[$nlast]}"; }
5703
5704                 (( ${objs0[$n]} > ${objs0[$nlast]} * 4 / 5 )) ||
5705                         { $LFS df && $LFS df -i &&
5706                         error "OST $n has fewer #0 objects vs. OST $nlast" \
5707                               " (${objs0[$n]} < ${objs0[$nlast]}"; }
5708                 (( ${objs0[$n]} < ${objs0[$nlast]} * 5 / 4 )) ||
5709                         { $LFS df && $LFS df -i &&
5710                         error "OST $n has fewer #0 objects vs. OST $nlast" \
5711                               " (${objs0[$n]} < ${objs0[$nlast]}"; }
5712                 nlast=$n
5713         done
5714 }
5715 run_test 51d "check object distribution"
5716
5717 test_51e() {
5718         if [ "$mds1_FSTYPE" != ldiskfs ]; then
5719                 skip_env "ldiskfs only test"
5720         fi
5721
5722         test_mkdir -c1 $DIR/$tdir
5723         test_mkdir -c1 $DIR/$tdir/d0
5724
5725         touch $DIR/$tdir/d0/foo
5726         createmany -l $DIR/$tdir/d0/foo $DIR/$tdir/d0/f- 65001 &&
5727                 error "file exceed 65000 nlink limit!"
5728         unlinkmany $DIR/$tdir/d0/f- 65001
5729         return 0
5730 }
5731 run_test 51e "check file nlink limit"
5732
5733 test_51f() {
5734         test_mkdir $DIR/$tdir
5735
5736         local max=100000
5737         local ulimit_old=$(ulimit -n)
5738         local spare=20 # number of spare fd's for scripts/libraries, etc.
5739         local mdt=$($LFS getstripe -m $DIR/$tdir)
5740         local numfree=$($LFS df -i $DIR/$tdir | awk '/MDT:'$mdt'/ { print $4 }')
5741
5742         echo "MDT$mdt numfree=$numfree, max=$max"
5743         [[ $numfree -gt $max ]] && numfree=$max || numfree=$((numfree * 7 / 8))
5744         if [ $((numfree + spare)) -gt $ulimit_old ]; then
5745                 while ! ulimit -n $((numfree + spare)); do
5746                         numfree=$((numfree * 3 / 4))
5747                 done
5748                 echo "changed ulimit from $ulimit_old to $((numfree + spare))"
5749         else
5750                 echo "left ulimit at $ulimit_old"
5751         fi
5752
5753         createmany -o -k -t 120 $DIR/$tdir/f $numfree || {
5754                 unlinkmany $DIR/$tdir/f $numfree
5755                 error "create+open $numfree files in $DIR/$tdir failed"
5756         }
5757         ulimit -n $ulimit_old
5758
5759         # if createmany exits at 120s there will be fewer than $numfree files
5760         unlinkmany $DIR/$tdir/f $numfree || true
5761 }
5762 run_test 51f "check many open files limit"
5763
5764 test_52a() {
5765         [ -f $DIR/$tdir/foo ] && chattr -a $DIR/$tdir/foo
5766         test_mkdir $DIR/$tdir
5767         touch $DIR/$tdir/foo
5768         chattr +a $DIR/$tdir/foo || error "chattr +a failed"
5769         echo bar >> $DIR/$tdir/foo || error "append bar failed"
5770         cp /etc/hosts $DIR/$tdir/foo && error "cp worked"
5771         rm -f $DIR/$tdir/foo 2>/dev/null && error "rm worked"
5772         link $DIR/$tdir/foo $DIR/$tdir/foo_link 2>/dev/null &&
5773                                         error "link worked"
5774         echo foo >> $DIR/$tdir/foo || error "append foo failed"
5775         mrename $DIR/$tdir/foo $DIR/$tdir/foo_ren && error "rename worked"
5776         lsattr $DIR/$tdir/foo | egrep -q "^-+a[-e]+ $DIR/$tdir/foo" ||
5777                                                      error "lsattr"
5778         chattr -a $DIR/$tdir/foo || error "chattr -a failed"
5779         cp -r $DIR/$tdir $TMP/
5780         rm -fr $DIR/$tdir $TMP/$tdir || error "cleanup rm failed"
5781 }
5782 run_test 52a "append-only flag test (should return errors)"
5783
5784 test_52b() {
5785         [ -f $DIR/$tdir/foo ] && chattr -i $DIR/$tdir/foo
5786         test_mkdir $DIR/$tdir
5787         touch $DIR/$tdir/foo
5788         chattr +i $DIR/$tdir/foo || error "chattr +i failed"
5789         cat test > $DIR/$tdir/foo && error "cat test worked"
5790         cp /etc/hosts $DIR/$tdir/foo && error "cp worked"
5791         rm -f $DIR/$tdir/foo 2>/dev/null && error "rm worked"
5792         link $DIR/$tdir/foo $DIR/$tdir/foo_link 2>/dev/null &&
5793                                         error "link worked"
5794         echo foo >> $DIR/$tdir/foo && error "echo worked"
5795         mrename $DIR/$tdir/foo $DIR/$tdir/foo_ren && error "rename worked"
5796         [ -f $DIR/$tdir/foo ] || error "$tdir/foo is not a file"
5797         [ -f $DIR/$tdir/foo_ren ] && error "$tdir/foo_ren is not a file"
5798         lsattr $DIR/$tdir/foo | egrep -q "^-+i[-e]+ $DIR/$tdir/foo" ||
5799                                                         error "lsattr"
5800         chattr -i $DIR/$tdir/foo || error "chattr failed"
5801
5802         rm -fr $DIR/$tdir || error "unable to remove $DIR/$tdir"
5803 }
5804 run_test 52b "immutable flag test (should return errors) ======="
5805
5806 test_53() {
5807         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5808         remote_mds_nodsh && skip "remote MDS with nodsh"
5809         remote_ost_nodsh && skip "remote OST with nodsh"
5810
5811         local param
5812         local param_seq
5813         local ostname
5814         local mds_last
5815         local mds_last_seq
5816         local ost_last
5817         local ost_last_seq
5818         local ost_last_id
5819         local ostnum
5820         local node
5821         local found=false
5822         local support_last_seq=true
5823
5824         [[ $MDS1_VERSION -ge $(version_code 2.3.60) ]] ||
5825                 support_last_seq=false
5826
5827         # only test MDT0000
5828         local mdtosc=$(get_mdtosc_proc_path $SINGLEMDS)
5829         local value
5830         for value in $(do_facet $SINGLEMDS \
5831                        $LCTL get_param osp.$mdtosc.prealloc_last_id) ; do
5832                 param=$(echo ${value[0]} | cut -d "=" -f1)
5833                 ostname=$(echo $param | cut -d "." -f2 | cut -d - -f 1-2)
5834
5835                 if $support_last_seq; then
5836                         param_seq=$(echo $param |
5837                                 sed -e s/prealloc_last_id/prealloc_last_seq/g)
5838                         mds_last_seq=$(do_facet $SINGLEMDS \
5839                                        $LCTL get_param -n $param_seq)
5840                 fi
5841                 mds_last=$(do_facet $SINGLEMDS $LCTL get_param -n $param)
5842
5843                 ostnum=$(index_from_ostuuid ${ostname}_UUID)
5844                 node=$(facet_active_host ost$((ostnum+1)))
5845                 param="obdfilter.$ostname.last_id"
5846                 for ost_last in $(do_node $node $LCTL get_param -n $param) ; do
5847                         echo "$ostname.last_id=$ost_last; MDS.last_id=$mds_last"
5848                         ost_last_id=$ost_last
5849
5850                         if $support_last_seq; then
5851                                 ost_last_id=$(echo $ost_last |
5852                                               awk -F':' '{print $2}' |
5853                                               sed -e "s/^0x//g")
5854                                 ost_last_seq=$(echo $ost_last |
5855                                                awk -F':' '{print $1}')
5856                                 [[ $ost_last_seq = $mds_last_seq ]] || continue
5857                         fi
5858
5859                         if [[ $ost_last_id != $mds_last ]]; then
5860                                 error "$ost_last_id != $mds_last"
5861                         else
5862                                 found=true
5863                                 break
5864                         fi
5865                 done
5866         done
5867         $found || error "can not match last_seq/last_id for $mdtosc"
5868         return 0
5869 }
5870 run_test 53 "verify that MDS and OSTs agree on pre-creation ===="
5871
5872 test_54a() {
5873         perl -MSocket -e ';' || skip "no Socket perl module installed"
5874
5875         $SOCKETSERVER $DIR/socket ||
5876                 error "$SOCKETSERVER $DIR/socket failed: $?"
5877         $SOCKETCLIENT $DIR/socket ||
5878                 error "$SOCKETCLIENT $DIR/socket failed: $?"
5879         $MUNLINK $DIR/socket || error "$MUNLINK $DIR/socket failed: $?"
5880 }
5881 run_test 54a "unix domain socket test =========================="
5882
5883 test_54b() {
5884         f="$DIR/f54b"
5885         mknod $f c 1 3
5886         chmod 0666 $f
5887         dd if=/dev/zero of=$f bs=$PAGE_SIZE count=1
5888 }
5889 run_test 54b "char device works in lustre ======================"
5890
5891 find_loop_dev() {
5892         [ -b /dev/loop/0 ] && LOOPBASE=/dev/loop/
5893         [ -b /dev/loop0 ] && LOOPBASE=/dev/loop
5894         [ -z "$LOOPBASE" ] && echo "/dev/loop/0 and /dev/loop0 gone?" && return
5895
5896         for i in $(seq 3 7); do
5897                 losetup $LOOPBASE$i > /dev/null 2>&1 && continue
5898                 LOOPDEV=$LOOPBASE$i
5899                 LOOPNUM=$i
5900                 break
5901         done
5902 }
5903
5904 cleanup_54c() {
5905         local rc=0
5906         loopdev="$DIR/loop54c"
5907
5908         trap 0
5909         $UMOUNT $DIR/$tdir || rc=$?
5910         losetup -d $loopdev || true
5911         losetup -d $LOOPDEV || true
5912         rm -rf $loopdev $DIR/$tfile $DIR/$tdir
5913         return $rc
5914 }
5915
5916 test_54c() {
5917         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5918
5919         loopdev="$DIR/loop54c"
5920
5921         find_loop_dev
5922         [ -z "$LOOPNUM" ] && skip_env "couldn't find empty loop device"
5923         trap cleanup_54c EXIT
5924         mknod $loopdev b 7 $LOOPNUM
5925         echo "make a loop file system with $DIR/$tfile on $loopdev ($LOOPNUM)."
5926         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE seek=1024 count=1 > /dev/null
5927         losetup $loopdev $DIR/$tfile ||
5928                 error "can't set up $loopdev for $DIR/$tfile"
5929         mkfs.ext2 $loopdev || error "mke2fs on $loopdev"
5930         test_mkdir $DIR/$tdir
5931         mount -t ext2 $loopdev $DIR/$tdir ||
5932                 error "error mounting $loopdev on $DIR/$tdir"
5933         dd if=/dev/zero of=$DIR/$tdir/tmp bs=$PAGE_SIZE count=30 ||
5934                 error "dd write"
5935         df $DIR/$tdir
5936         dd if=$DIR/$tdir/tmp of=/dev/zero bs=$PAGE_SIZE count=30 ||
5937                 error "dd read"
5938         cleanup_54c
5939 }
5940 run_test 54c "block device works in lustre ====================="
5941
5942 test_54d() {
5943         f="$DIR/f54d"
5944         string="aaaaaa"
5945         mknod $f p
5946         [ "$string" = $(echo $string > $f | cat $f) ] || error "$f != $string"
5947 }
5948 run_test 54d "fifo device works in lustre ======================"
5949
5950 test_54e() {
5951         f="$DIR/f54e"
5952         string="aaaaaa"
5953         cp -aL /dev/console $f
5954         echo $string > $f || error "echo $string to $f failed"
5955 }
5956 run_test 54e "console/tty device works in lustre ======================"
5957
5958 test_56a() {
5959         local numfiles=3
5960         local numdirs=2
5961         local dir=$DIR/$tdir
5962
5963         rm -rf $dir
5964         test_mkdir -p $dir/dir
5965         for i in $(seq $numfiles); do
5966                 touch $dir/file$i
5967                 touch $dir/dir/file$i
5968         done
5969
5970         local numcomp=$($LFS getstripe --component-count $dir)
5971
5972         [[ $numcomp == 0 ]] && numcomp=1
5973
5974         # test lfs getstripe with --recursive
5975         local filenum=$($LFS getstripe -r $dir | egrep -c "obdidx|l_ost_idx")
5976
5977         [[ $filenum -eq $((numfiles * 2)) ]] ||
5978                 error "$LFS getstripe -r: found $filenum != $((numfiles * 2))"
5979         filenum=$($LFS getstripe $dir | egrep -c "obdidx|l_ost_idx")
5980         [[ $filenum -eq $numfiles ]] ||
5981                 error "$LFS getstripe $dir: found $filenum, not $numfiles"
5982         echo "$LFS getstripe showed obdidx or l_ost_idx"
5983
5984         # test lfs getstripe with file instead of dir
5985         filenum=$($LFS getstripe $dir/file1 | egrep -c "obdidx|l_ost_idx")
5986         [[ $filenum -eq 1 ]] ||
5987                 error "$LFS getstripe $dir/file1: found $filenum, not 1"
5988         echo "$LFS getstripe file1 passed"
5989
5990         #test lfs getstripe with --verbose
5991         filenum=$($LFS getstripe --verbose $dir | grep -c lmm_magic)
5992         [[ $filenum -eq $((numfiles * numcomp)) ]] ||
5993                 error "$LFS getstripe --verbose $dir: "\
5994                       "got $filenum want $((numfiles * numcomp)) lmm_magic"
5995         [[ $($LFS getstripe $dir | grep -c lmm_magic) -eq 0 ]] ||
5996                 error "$LFS getstripe $dir: showed lmm_magic"
5997
5998         #test lfs getstripe with -v prints lmm_fid
5999         filenum=$($LFS getstripe -v $dir | grep -c lmm_fid)
6000         local countfids=$((numdirs + numfiles * numcomp))
6001         [[ $filenum -eq $countfids ]] ||
6002                 error "$LFS getstripe -v $dir: "\
6003                       "got $filenum want $countfids lmm_fid"
6004         [[ $($LFS getstripe $dir | grep -c lmm_fid) -eq 0 ]] ||
6005                 error "$LFS getstripe $dir: showed lmm_fid by default"
6006         echo "$LFS getstripe --verbose passed"
6007
6008         #check for FID information
6009         local fid1=$($LFS getstripe --fid $dir/file1)
6010         local fid2=$($LFS getstripe --verbose $dir/file1 |
6011                      awk '/lmm_fid: / { print $2; exit; }')
6012         local fid3=$($LFS path2fid $dir/file1)
6013
6014         [ "$fid1" != "$fid2" ] &&
6015                 error "getstripe --fid '$fid1' != getstripe --verbose '$fid2'"
6016         [ "$fid1" != "$fid3" ] &&
6017                 error "getstripe --fid '$fid1' != lfs path2fid '$fid3'"
6018         echo "$LFS getstripe --fid passed"
6019
6020         #test lfs getstripe with --obd
6021         $LFS getstripe --obd wrong_uuid $dir 2>&1 | grep -q "unknown obduuid" ||
6022                 error "$LFS getstripe --obd wrong_uuid: should return error"
6023
6024         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
6025
6026         local ostidx=1
6027         local obduuid=$(ostuuid_from_index $ostidx)
6028         local found=$($LFS getstripe -r --obd $obduuid $dir |
6029                 grep 'lmm_stripe_offset:' | grep -c " $ostidx\$")
6030
6031         filenum=$($LFS getstripe -ir $dir | grep -c "^$ostidx\$")
6032         [[ $($LFS getstripe -id $dir) -ne $ostidx ]] ||
6033                 ((filenum--))
6034         [[ $($LFS getstripe -id $dir/dir) -ne $ostidx ]] ||
6035                 ((filenum--))
6036
6037         [[ $found -eq $filenum ]] ||
6038                 error "$LFS getstripe --obd: found $found expect $filenum"
6039         [[ $($LFS getstripe -r -v --obd $obduuid $dir |
6040                 sed '/^[         ]*'${ostidx}'[  ]/d' |
6041                 sed -n '/^[      ]*[0-9][0-9]*[  ]/p' | wc -l) -eq 0 ]] ||
6042                 error "$LFS getstripe --obd: should not show file on other obd"
6043         echo "$LFS getstripe --obd passed"
6044 }
6045 run_test 56a "check $LFS getstripe"
6046
6047 test_56b() {
6048         local dir=$DIR/$tdir
6049         local numdirs=3
6050
6051         test_mkdir $dir
6052         for i in $(seq $numdirs); do
6053                 test_mkdir $dir/dir$i
6054         done
6055
6056         # test lfs getdirstripe default mode is non-recursion, which is
6057         # different from lfs getstripe
6058         local dircnt=$($LFS getdirstripe $dir | grep -c lmv_stripe_count)
6059
6060         [[ $dircnt -eq 1 ]] ||
6061                 error "$LFS getdirstripe: found $dircnt, not 1"
6062         dircnt=$($LFS getdirstripe --recursive $dir |
6063                 grep -c lmv_stripe_count)
6064         [[ $dircnt -eq $((numdirs + 1)) ]] ||
6065                 error "$LFS getdirstripe -r: $dircnt, != $((numdirs + 1))"
6066 }
6067 run_test 56b "check $LFS getdirstripe"
6068
6069 test_56c() {
6070         remote_ost_nodsh && skip "remote OST with nodsh"
6071
6072         local ost_idx=0
6073         local ost_name=$(ostname_from_index $ost_idx)
6074         local old_status=$(ost_dev_status $ost_idx)
6075         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
6076
6077         [[ -z "$old_status" ]] ||
6078                 skip_env "OST $ost_name is in $old_status status"
6079
6080         do_facet ost1 $LCTL set_param -n obdfilter.$ost_name.degraded=1
6081         [[ $OST1_VERSION -lt $(version_code 2.12.55) ]] || do_facet ost1 \
6082                 $LCTL set_param -n obdfilter.$ost_name.no_precreate=1
6083         if [[ $OST1_VERSION -ge $(version_code 2.12.57) ]]; then
6084                 save_lustre_params ost1 osd-*.$ost_name.nonrotational > $p
6085                 do_facet ost1 $LCTL set_param -n osd-*.$ost_name.nonrotational=1
6086         fi
6087
6088         [[ $($LFS df -v $MOUNT |& grep -c "inactive device") -eq 0 ]] ||
6089                 error "$LFS df -v showing inactive devices"
6090         sleep_maxage
6091
6092         local new_status=$(ost_dev_status $ost_idx $MOUNT -v)
6093
6094         [[ "$new_status" =~ "D" ]] ||
6095                 error "$ost_name status is '$new_status', missing 'D'"
6096         if [[ $OST1_VERSION -ge $(version_code 2.12.55) ]]; then
6097                 [[ "$new_status" =~ "N" ]] ||
6098                         error "$ost_name status is '$new_status', missing 'N'"
6099         fi
6100         if [[ $OST1_VERSION -ge $(version_code 2.12.57) ]]; then
6101                 [[ "$new_status" =~ "f" ]] ||
6102                         error "$ost_name status is '$new_status', missing 'f'"
6103         fi
6104
6105         do_facet ost1 $LCTL set_param -n obdfilter.$ost_name.degraded=0
6106         [[ $OST1_VERSION -lt $(version_code 2.12.55) ]] || do_facet ost1 \
6107                 $LCTL set_param -n obdfilter.$ost_name.no_precreate=0
6108         [[ -z "$p" ]] && restore_lustre_params < $p || true
6109         sleep_maxage
6110
6111         new_status=$(ost_dev_status $ost_idx)
6112         [[ ! "$new_status" =~ "D" && ! "$new_status" =~ "N" ]] ||
6113                 error "$ost_name status is '$new_status', has 'D' and/or 'N'"
6114         # can't check 'f' as devices may actually be on flash
6115 }
6116 run_test 56c "check 'lfs df' showing device status"
6117
6118 test_56d() {
6119         local mdts=$($LFS df -v $MOUNT | grep -c MDT)
6120         local osts=$($LFS df -v $MOUNT | grep -c OST)
6121
6122         $LFS df $MOUNT
6123
6124         (( mdts == MDSCOUNT )) ||
6125                 error "lfs df -v showed $mdts MDTs, not $MDSCOUNT"
6126         (( osts == OSTCOUNT )) ||
6127                 error "lfs df -v showed $osts OSTs, not $OSTCOUNT"
6128 }
6129 run_test 56d "'lfs df -v' prints only configured devices"
6130
6131 test_56e() {
6132         err_enoent=2 # No such file or directory
6133         err_eopnotsupp=95 # Operation not supported
6134
6135         enoent_mnt=/pmt1 # Invalid dentry. Path not present
6136         notsup_mnt=/tmp  # Valid dentry, but Not a lustreFS
6137
6138         # Check for handling of path not exists
6139         output=$($LFS df $enoent_mnt 2>&1)
6140         ret=$?
6141
6142         fs=$(echo $output | awk -F: '{print $2}' | awk '{print $3}' | tr -d \')
6143         [[ $fs = $enoent_mnt && $ret -eq $err_enoent ]] ||
6144                 error "expect failure $err_enoent, not $ret"
6145
6146         # Check for handling of non-Lustre FS
6147         output=$($LFS df $notsup_mnt)
6148         ret=$?
6149
6150         fs=$(echo $output | awk '{print $1}' | awk -F: '{print $2}')
6151         [[ $fs = $notsup_mnt && $ret -eq $err_eopnotsupp ]] ||
6152                 error "expect success $err_eopnotsupp, not $ret"
6153
6154         # Check for multiple LustreFS argument
6155         output=$($LFS df $MOUNT $MOUNT $MOUNT | grep -c "filesystem_summary:")
6156         ret=$?
6157
6158         [[ $output -eq 3 && $ret -eq 0 ]] ||
6159                 error "expect success 3, not $output, rc = $ret"
6160
6161         # Check for correct non-Lustre FS handling among multiple
6162         # LustreFS argument
6163         output=$($LFS df $MOUNT $notsup_mnt $MOUNT |
6164                 grep -c "filesystem_summary:"; exit ${PIPESTATUS[0]})
6165         ret=$?
6166
6167         [[ $output -eq 2 && $ret -eq $err_eopnotsupp ]] ||
6168                 error "expect success 2, not $output, rc = $ret"
6169 }
6170 run_test 56e "'lfs df' Handle non LustreFS & multiple LustreFS"
6171
6172 NUMFILES=3
6173 NUMDIRS=3
6174 setup_56() {
6175         local local_tdir="$1"
6176         local local_numfiles="$2"
6177         local local_numdirs="$3"
6178         local dir_params="$4"
6179         local dir_stripe_params="$5"
6180
6181         if [ ! -d "$local_tdir" ] ; then
6182                 test_mkdir -p $dir_stripe_params $local_tdir
6183                 [ "$dir_params" ] && $LFS setstripe $dir_params $local_tdir
6184                 for i in $(seq $local_numfiles) ; do
6185                         touch $local_tdir/file$i
6186                 done
6187                 for i in $(seq $local_numdirs) ; do
6188                         test_mkdir $dir_stripe_params $local_tdir/dir$i
6189                         for j in $(seq $local_numfiles) ; do
6190                                 touch $local_tdir/dir$i/file$j
6191                         done
6192                 done
6193         fi
6194 }
6195
6196 setup_56_special() {
6197         local local_tdir=$1
6198         local local_numfiles=$2
6199         local local_numdirs=$3
6200
6201         setup_56 $local_tdir $local_numfiles $local_numdirs
6202
6203         if [ ! -e "$local_tdir/loop${local_numfiles}b" ] ; then
6204                 for i in $(seq $local_numfiles) ; do
6205                         mknod $local_tdir/loop${i}b b 7 $i
6206                         mknod $local_tdir/null${i}c c 1 3
6207                         ln -s $local_tdir/file1 $local_tdir/link${i}
6208                 done
6209                 for i in $(seq $local_numdirs) ; do
6210                         mknod $local_tdir/dir$i/loop${i}b b 7 $i
6211                         mknod $local_tdir/dir$i/null${i}c c 1 3
6212                         ln -s $local_tdir/dir$i/file1 $local_tdir/dir$i/link${i}
6213                 done
6214         fi
6215 }
6216
6217 test_56g() {
6218         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6219         local expected=$(($NUMDIRS + 2))
6220
6221         setup_56 $dir $NUMFILES $NUMDIRS
6222
6223         # test lfs find with -name
6224         for i in $(seq $NUMFILES) ; do
6225                 local nums=$($LFS find -name "*$i" $dir | wc -l)
6226
6227                 [ $nums -eq $expected ] ||
6228                         error "lfs find -name '*$i' $dir wrong: "\
6229                               "found $nums, expected $expected"
6230         done
6231 }
6232 run_test 56g "check lfs find -name"
6233
6234 test_56h() {
6235         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6236         local expected=$(((NUMDIRS + 1) * (NUMFILES - 1) + NUMFILES))
6237
6238         setup_56 $dir $NUMFILES $NUMDIRS
6239
6240         # test lfs find with ! -name
6241         for i in $(seq $NUMFILES) ; do
6242                 local nums=$($LFS find ! -name "*$i" $dir | wc -l)
6243
6244                 [ $nums -eq $expected ] ||
6245                         error "lfs find ! -name '*$i' $dir wrong: "\
6246                               "found $nums, expected $expected"
6247         done
6248 }
6249 run_test 56h "check lfs find ! -name"
6250
6251 test_56i() {
6252         local dir=$DIR/$tdir
6253
6254         test_mkdir $dir
6255
6256         local cmd="$LFS find -ost $(ostuuid_from_index 0 $dir) $dir"
6257         local out=$($cmd)
6258
6259         [ -z "$out" ] || error "'$cmd' returned directory '$out'"
6260 }
6261 run_test 56i "check 'lfs find -ost UUID' skips directories"
6262
6263 test_56j() {
6264         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6265
6266         setup_56_special $dir $NUMFILES $NUMDIRS
6267
6268         local expected=$((NUMDIRS + 1))
6269         local cmd="$LFS find -type d $dir"
6270         local nums=$($cmd | wc -l)
6271
6272         [ $nums -eq $expected ] ||
6273                 error "'$cmd' wrong: found $nums, expected $expected"
6274 }
6275 run_test 56j "check lfs find -type d"
6276
6277 test_56k() {
6278         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6279
6280         setup_56_special $dir $NUMFILES $NUMDIRS
6281
6282         local expected=$(((NUMDIRS + 1) * NUMFILES))
6283         local cmd="$LFS find -type f $dir"
6284         local nums=$($cmd | wc -l)
6285
6286         [ $nums -eq $expected ] ||
6287                 error "'$cmd' wrong: found $nums, expected $expected"
6288 }
6289 run_test 56k "check lfs find -type f"
6290
6291 test_56l() {
6292         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6293
6294         setup_56_special $dir $NUMFILES $NUMDIRS
6295
6296         local expected=$((NUMDIRS + NUMFILES))
6297         local cmd="$LFS find -type b $dir"
6298         local nums=$($cmd | wc -l)
6299
6300         [ $nums -eq $expected ] ||
6301                 error "'$cmd' wrong: found $nums, expected $expected"
6302 }
6303 run_test 56l "check lfs find -type b"
6304
6305 test_56m() {
6306         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6307
6308         setup_56_special $dir $NUMFILES $NUMDIRS
6309
6310         local expected=$((NUMDIRS + NUMFILES))
6311         local cmd="$LFS find -type c $dir"
6312         local nums=$($cmd | wc -l)
6313         [ $nums -eq $expected ] ||
6314                 error "'$cmd' wrong: found $nums, expected $expected"
6315 }
6316 run_test 56m "check lfs find -type c"
6317
6318 test_56n() {
6319         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6320         setup_56_special $dir $NUMFILES $NUMDIRS
6321
6322         local expected=$((NUMDIRS + NUMFILES))
6323         local cmd="$LFS find -type l $dir"
6324         local nums=$($cmd | wc -l)
6325
6326         [ $nums -eq $expected ] ||
6327                 error "'$cmd' wrong: found $nums, expected $expected"
6328 }
6329 run_test 56n "check lfs find -type l"
6330
6331 test_56o() {
6332         local dir=$DIR/$tdir
6333
6334         setup_56 $dir $NUMFILES $NUMDIRS
6335         utime $dir/file1 > /dev/null || error "utime (1)"
6336         utime $dir/file2 > /dev/null || error "utime (2)"
6337         utime $dir/dir1 > /dev/null || error "utime (3)"
6338         utime $dir/dir2 > /dev/null || error "utime (4)"
6339         utime $dir/dir1/file1 > /dev/null || error "utime (5)"
6340         dd if=/dev/zero count=1 >> $dir/dir1/file1 && sync
6341
6342         local expected=4
6343         local nums=$($LFS find -mtime +0 $dir | wc -l)
6344
6345         [ $nums -eq $expected ] ||
6346                 error "lfs find -mtime +0 $dir: found $nums expect $expected"
6347
6348         expected=12
6349         cmd="$LFS find -mtime 0 $dir"
6350         nums=$($cmd | wc -l)
6351         [ $nums -eq $expected ] ||
6352                 error "'$cmd' wrong: found $nums, expected $expected"
6353 }
6354 run_test 56o "check lfs find -mtime for old files"
6355
6356 test_56ob() {
6357         local dir=$DIR/$tdir
6358         local expected=1
6359         local count=0
6360
6361         # just to make sure there is something that won't be found
6362         test_mkdir $dir
6363         touch $dir/$tfile.now
6364
6365         for age in year week day hour min; do
6366                 count=$((count + 1))
6367
6368                 touch $dir/$tfile-a.$age $dir/$tfile-m.$age
6369                 touch --date="$count $age ago" -a $dir/$tfile-a.$age
6370                 touch --date="$count $age ago" -m $dir/$tfile-m.$age
6371
6372                 local cmd="$LFS find $dir -mtime $count${age:0:1}"
6373                 local nums=$($cmd | wc -l)
6374                 [ $nums -eq $expected ] ||
6375                         error "'$cmd' wrong: found $nums, expected $expected"
6376
6377                 cmd="$LFS find $dir -atime $count${age:0:1}"
6378                 nums=$($cmd | wc -l)
6379                 [ $nums -eq $expected ] ||
6380                         error "'$cmd' wrong: found $nums, expected $expected"
6381         done
6382
6383         sleep 2
6384         cmd="$LFS find $dir -ctime +1s -type f"
6385         nums=$($cmd | wc -l)
6386         (( $nums == $count * 2 + 1)) ||
6387                 error "'$cmd' wrong: found $nums, expected $((count * 2 + 1))"
6388 }
6389 run_test 56ob "check lfs find -atime -mtime -ctime with units"
6390
6391 test_newerXY_base() {
6392         local x=$1
6393         local y=$2
6394         local dir=$DIR/$tdir
6395         local ref
6396         local negref
6397
6398         if [ $y == "t" ]; then
6399                 if [ $x == "b" ]; then
6400                         ref=\"$(do_facet mds1 date +"%Y-%m-%d\ %H:%M:%S")\"
6401                 else
6402                         ref=\"$(date +"%Y-%m-%d %H:%M:%S")\"
6403                 fi
6404         else
6405                 ref=$DIR/$tfile.newer.$x$y
6406                 touch $ref || error "touch $ref failed"
6407         fi
6408
6409         echo "before = $ref"
6410         sleep 2
6411         setup_56 $dir $NUMFILES $NUMDIRS "-i0 -c1" "-i0 -c1"
6412         sleep 2
6413         if [ $y == "t" ]; then
6414                 if [ $x == "b" ]; then
6415                         negref=\"$(do_facet mds1 date +"%Y-%m-%d\ %H:%M:%S")\"
6416                 else
6417                         negref=\"$(date +"%Y-%m-%d %H:%M:%S")\"
6418                 fi
6419         else
6420                 negref=$DIR/$tfile.negnewer.$x$y
6421                 touch $negref || error "touch $negref failed"
6422         fi
6423
6424         echo "after = $negref"
6425         local cmd="$LFS find $dir -newer$x$y $ref"
6426         local nums=$(eval $cmd | wc -l)
6427         local expected=$(((NUMFILES + 2) * NUMDIRS + 1))
6428
6429         [ $nums -eq $expected ] || { ls -lauR --full-time $dir ;
6430                 error "'$cmd' wrong: found $nums newer, expected $expected"  ; }
6431
6432         cmd="$LFS find $dir ! -newer$x$y $negref"
6433         nums=$(eval $cmd | wc -l)
6434         [ $nums -eq $expected ] || { ls -lauR --full-time $dir ;
6435                 error "'$cmd' wrong: found $nums older, expected $expected"  ; }
6436
6437         cmd="$LFS find $dir -newer$x$y $ref ! -newer$x$y $negref"
6438         nums=$(eval $cmd | wc -l)
6439         [ $nums -eq $expected ] || { ls -lauR --full-time $dir ;
6440                 error "'$cmd' wrong: found $nums between, expected $expected"; }
6441
6442         rm -rf $DIR/*
6443 }
6444
6445 test_56oc() {
6446         test_newerXY_base "a" "a"
6447         test_newerXY_base "a" "m"
6448         test_newerXY_base "a" "c"
6449         test_newerXY_base "m" "a"
6450         test_newerXY_base "m" "m"
6451         test_newerXY_base "m" "c"
6452         test_newerXY_base "c" "a"
6453         test_newerXY_base "c" "m"
6454         test_newerXY_base "c" "c"
6455
6456         [[ -n "$sles_version" ]] &&
6457                 echo "skip timestamp tests on SLES, LU-13665" && return 0
6458
6459         test_newerXY_base "a" "t"
6460         test_newerXY_base "m" "t"
6461         test_newerXY_base "c" "t"
6462
6463         [[ $MDS1_VERSION -lt $(version_code 2.13.54) ||
6464            $CLIENT_VERSION -lt $(version_code 2.13.54) ]] &&
6465                 ! btime_supported && echo "btime unsupported" && return 0
6466
6467         test_newerXY_base "b" "b"
6468         test_newerXY_base "b" "t"
6469 }
6470 run_test 56oc "check lfs find -newerXY work"
6471
6472 btime_supported() {
6473         local dir=$DIR/$tdir
6474         local rc
6475
6476         mkdir -p $dir
6477         touch $dir/$tfile
6478         $LFS find $dir -btime -1d -type f
6479         rc=$?
6480         rm -rf $dir
6481         return $rc
6482 }
6483
6484 test_56od() {
6485         [ $MDS1_VERSION -lt $(version_code 2.13.53) ] &&
6486                 ! btime_supported && skip "btime unsupported on MDS"
6487
6488         [ $CLIENT_VERSION -lt $(version_code 2.13.53) ] &&
6489                 ! btime_supported && skip "btime unsupported on clients"
6490
6491         local dir=$DIR/$tdir
6492         local ref=$DIR/$tfile.ref
6493         local negref=$DIR/$tfile.negref
6494
6495         mkdir $dir || error "mkdir $dir failed"
6496         touch $dir/$tfile.n1 || error "touch $dir/$tfile.n1 failed"
6497         touch $dir/$tfile.n2 || error "touch $dir/$tfile.n2 failed"
6498         mkdir $dir/$tdir.n1 || error "mkdir $dir/$tdir.n1 failed"
6499         mkdir $dir/$tdir.n2 || error "mkdir $dir/$tdir.n2 failed"
6500         touch $ref || error "touch $ref failed"
6501         # sleep 3 seconds at least
6502         sleep 3
6503
6504         local before=$(do_facet mds1 date +%s)
6505         local skew=$(($(date +%s) - before + 1))
6506
6507         if (( skew < 0 && skew > -5 )); then
6508                 sleep $((0 - skew + 1))
6509                 skew=0
6510         fi
6511
6512         # Set the dir stripe params to limit files all on MDT0,
6513         # otherwise we need to calc the max clock skew between
6514         # the client and MDTs.
6515         setup_56 $dir/d.btime $NUMFILES $NUMDIRS "-i0 -c1" "-i0 -c1"
6516         sleep 2
6517         touch $negref || error "touch $negref failed"
6518
6519         local cmd="$LFS find $dir -newerbb $ref ! -newerbb $negref -type f"
6520         local nums=$($cmd | wc -l)
6521         local expected=$(((NUMFILES + 1) * NUMDIRS))
6522
6523         [ $nums -eq $expected ] ||
6524                 error "'$cmd' wrong: found $nums, expected $expected"
6525
6526         cmd="$LFS find $dir -newerbb $ref ! -newerbb $negref -type d"
6527         nums=$($cmd | wc -l)
6528         expected=$((NUMFILES + 1))
6529         [ $nums -eq $expected ] ||
6530                 error "'$cmd' wrong: found $nums, expected $expected"
6531
6532         [ $skew -lt 0 ] && return
6533
6534         local after=$(do_facet mds1 date +%s)
6535         local age=$((after - before + 1 + skew))
6536
6537         cmd="$LFS find $dir -btime -${age}s -type f"
6538         nums=$($cmd | wc -l)
6539         expected=$(((NUMFILES + 1) * NUMDIRS))
6540
6541         echo "Clock skew between client and server: $skew, age:$age"
6542         [ $nums -eq $expected ] ||
6543                 error "'$cmd' wrong: found $nums, expected $expected"
6544
6545         expected=$(($NUMDIRS + 1))
6546         cmd="$LFS find $dir -btime -${age}s -type d"
6547         nums=$($cmd | wc -l)
6548         [ $nums -eq $expected ] ||
6549                 error "'$cmd' wrong: found $nums, expected $expected"
6550         rm -f $ref $negref || error "Failed to remove $ref $negref"
6551 }
6552 run_test 56od "check lfs find -btime with units"
6553
6554 test_56p() {
6555         [ $RUNAS_ID -eq $UID ] &&
6556                 skip_env "RUNAS_ID = UID = $UID -- skipping"
6557
6558         local dir=$DIR/$tdir
6559
6560         setup_56 $dir $NUMFILES $NUMDIRS
6561         chown $RUNAS_ID $dir/file* || error "chown $DIR/${tdir}g/file$i failed"
6562
6563         local expected=$NUMFILES
6564         local cmd="$LFS find -uid $RUNAS_ID $dir"
6565         local nums=$($cmd | wc -l)
6566
6567         [ $nums -eq $expected ] ||
6568                 error "'$cmd' wrong: found $nums, expected $expected"
6569
6570         expected=$(((NUMFILES + 1) * NUMDIRS + 1))
6571         cmd="$LFS find ! -uid $RUNAS_ID $dir"
6572         nums=$($cmd | wc -l)
6573         [ $nums -eq $expected ] ||
6574                 error "'$cmd' wrong: found $nums, expected $expected"
6575 }
6576 run_test 56p "check lfs find -uid and ! -uid"
6577
6578 test_56q() {
6579         [ $RUNAS_ID -eq $UID ] &&
6580                 skip_env "RUNAS_ID = UID = $UID -- skipping"
6581
6582         local dir=$DIR/$tdir
6583
6584         setup_56 $dir $NUMFILES $NUMDIRS
6585         chgrp $RUNAS_GID $dir/file* || error "chown $dir/file$i failed"
6586
6587         local expected=$NUMFILES
6588         local cmd="$LFS find -gid $RUNAS_GID $dir"
6589         local nums=$($cmd | wc -l)
6590
6591         [ $nums -eq $expected ] ||
6592                 error "'$cmd' wrong: found $nums, expected $expected"
6593
6594         expected=$(( ($NUMFILES+1) * $NUMDIRS + 1))
6595         cmd="$LFS find ! -gid $RUNAS_GID $dir"
6596         nums=$($cmd | wc -l)
6597         [ $nums -eq $expected ] ||
6598                 error "'$cmd' wrong: found $nums, expected $expected"
6599 }
6600 run_test 56q "check lfs find -gid and ! -gid"
6601
6602 test_56r() {
6603         local dir=$DIR/$tdir
6604
6605         setup_56 $dir $NUMFILES $NUMDIRS
6606
6607         local expected=12
6608         local cmd="$LFS find -size 0 -type f -lazy $dir"
6609         local nums=$($cmd | wc -l)
6610
6611         [ $nums -eq $expected ] ||
6612                 error "'$cmd' wrong: found $nums, expected $expected"
6613         cmd="$LFS find -size 0 -type f $dir"
6614         nums=$($cmd | wc -l)
6615         [ $nums -eq $expected ] ||
6616                 error "'$cmd' wrong: found $nums, expected $expected"
6617
6618         expected=0
6619         cmd="$LFS find ! -size 0 -type f -lazy $dir"
6620         nums=$($cmd | wc -l)
6621         [ $nums -eq $expected ] ||
6622                 error "'$cmd' wrong: found $nums, expected $expected"
6623         cmd="$LFS find ! -size 0 -type f $dir"
6624         nums=$($cmd | wc -l)
6625         [ $nums -eq $expected ] ||
6626                 error "'$cmd' wrong: found $nums, expected $expected"
6627
6628         echo "test" > $dir/$tfile
6629         echo "test2" > $dir/$tfile.2 && sync
6630         expected=1
6631         cmd="$LFS find -size 5 -type f -lazy $dir"
6632         nums=$($cmd | wc -l)
6633         [ $nums -eq $expected ] ||
6634                 error "'$cmd' wrong: found $nums, expected $expected"
6635         cmd="$LFS find -size 5 -type f $dir"
6636         nums=$($cmd | wc -l)
6637         [ $nums -eq $expected ] ||
6638                 error "'$cmd' wrong: found $nums, expected $expected"
6639
6640         expected=1
6641         cmd="$LFS find -size +5 -type f -lazy $dir"
6642         nums=$($cmd | wc -l)
6643         [ $nums -eq $expected ] ||
6644                 error "'$cmd' wrong: found $nums, expected $expected"
6645         cmd="$LFS find -size +5 -type f $dir"
6646         nums=$($cmd | wc -l)
6647         [ $nums -eq $expected ] ||
6648                 error "'$cmd' wrong: found $nums, expected $expected"
6649
6650         expected=2
6651         cmd="$LFS find -size +0 -type f -lazy $dir"
6652         nums=$($cmd | wc -l)
6653         [ $nums -eq $expected ] ||
6654                 error "'$cmd' wrong: found $nums, expected $expected"
6655         cmd="$LFS find -size +0 -type f $dir"
6656         nums=$($cmd | wc -l)
6657         [ $nums -eq $expected ] ||
6658                 error "'$cmd' wrong: found $nums, expected $expected"
6659
6660         expected=2
6661         cmd="$LFS find ! -size -5 -type f -lazy $dir"
6662         nums=$($cmd | wc -l)
6663         [ $nums -eq $expected ] ||
6664                 error "'$cmd' wrong: found $nums, expected $expected"
6665         cmd="$LFS find ! -size -5 -type f $dir"
6666         nums=$($cmd | wc -l)
6667         [ $nums -eq $expected ] ||
6668                 error "'$cmd' wrong: found $nums, expected $expected"
6669
6670         expected=12
6671         cmd="$LFS find -size -5 -type f -lazy $dir"
6672         nums=$($cmd | wc -l)
6673         [ $nums -eq $expected ] ||
6674                 error "'$cmd' wrong: found $nums, expected $expected"
6675         cmd="$LFS find -size -5 -type f $dir"
6676         nums=$($cmd | wc -l)
6677         [ $nums -eq $expected ] ||
6678                 error "'$cmd' wrong: found $nums, expected $expected"
6679 }
6680 run_test 56r "check lfs find -size works"
6681
6682 test_56ra_sub() {
6683         local expected=$1
6684         local glimpses=$2
6685         local cmd="$3"
6686
6687         cancel_lru_locks $OSC
6688
6689         local rpcs_before=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
6690         local nums=$($cmd | wc -l)
6691
6692         [ $nums -eq $expected ] ||
6693                 error "'$cmd' wrong: found $nums, expected $expected"
6694
6695         local rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
6696
6697         if (( rpcs_before + glimpses != rpcs_after )); then
6698                 echo "Before: $rpcs_before After: $rpcs_after $NUMFILES"
6699                 $LCTL get_param osc.*.stats | grep ldlm_glimpse_enqueue
6700
6701                 if [[ $glimpses == 0 ]]; then
6702                         error "'$cmd' should not send glimpse RPCs to OST"
6703                 else
6704                         error "'$cmd' should send $glimpses glimpse RPCs to OST"
6705                 fi
6706         fi
6707 }
6708
6709 test_56ra() {
6710         [[ $MDS1_VERSION -gt $(version_code 2.12.58) ]] ||
6711                 skip "MDS < 2.12.58 doesn't return LSOM data"
6712         local dir=$DIR/$tdir
6713         local old_agl=$($LCTL get_param -n llite.*.statahead_agl)
6714
6715         [[ $OSC == "mdc" ]] && skip "statahead not needed for DoM files"
6716
6717         # statahead_agl may cause extra glimpse which confuses results. LU-13017
6718         $LCTL set_param -n llite.*.statahead_agl=0
6719         stack_trap "$LCTL set_param -n llite.*.statahead_agl=$old_agl"
6720
6721         setup_56 $dir $NUMFILES $NUMDIRS "-c 1"
6722         # open and close all files to ensure LSOM is updated
6723         cancel_lru_locks $OSC
6724         find $dir -type f | xargs cat > /dev/null
6725
6726         #   expect_found  glimpse_rpcs  command_to_run
6727         test_56ra_sub 12  0 "$LFS find -size 0 -type f -lazy $dir"
6728         test_56ra_sub 12 12 "$LFS find -size 0 -type f $dir"
6729         test_56ra_sub  0  0 "$LFS find ! -size 0 -type f -lazy $dir"
6730         test_56ra_sub  0 12 "$LFS find ! -size 0 -type f $dir"
6731
6732         echo "test" > $dir/$tfile
6733         echo "test2" > $dir/$tfile.2 && sync
6734         cancel_lru_locks $OSC
6735         cat $dir/$tfile $dir/$tfile.2 > /dev/null
6736
6737         test_56ra_sub  1  0 "$LFS find -size 5 -type f -lazy $dir"
6738         test_56ra_sub  1 14 "$LFS find -size 5 -type f $dir"
6739         test_56ra_sub  1  0 "$LFS find -size +5 -type f -lazy $dir"
6740         test_56ra_sub  1 14 "$LFS find -size +5 -type f $dir"
6741
6742         test_56ra_sub  2  0 "$LFS find -size +0 -type f -lazy $dir"
6743         test_56ra_sub  2 14 "$LFS find -size +0 -type f $dir"
6744         test_56ra_sub  2  0 "$LFS find ! -size -5 -type f -lazy $dir"
6745         test_56ra_sub  2 14 "$LFS find ! -size -5 -type f $dir"
6746         test_56ra_sub 12  0 "$LFS find -size -5 -type f -lazy $dir"
6747         test_56ra_sub 12 14 "$LFS find -size -5 -type f $dir"
6748 }
6749 run_test 56ra "check lfs find -size -lazy works for data on OSTs"
6750
6751 test_56rb() {
6752         local dir=$DIR/$tdir
6753         local tmp=$TMP/$tfile.log
6754         local mdt_idx;
6755
6756         test_mkdir -p $dir || error "failed to mkdir $dir"
6757         $LFS setstripe -c 1 -i 0 $dir/$tfile ||
6758                 error "failed to setstripe $dir/$tfile"
6759         mdt_idx=$($LFS getdirstripe -i $dir)
6760         dd if=/dev/zero of=$dir/$tfile bs=1M count=1
6761
6762         stack_trap "rm -f $tmp" EXIT
6763         $LFS find --size +100K --ost 0 $dir |& tee $tmp
6764         ! grep -q obd_uuid $tmp ||
6765                 error "failed to find --size +100K --ost 0 $dir"
6766         $LFS find --size +100K --mdt $mdt_idx $dir |& tee $tmp
6767         ! grep -q obd_uuid $tmp ||
6768                 error "failed to find --size +100K --mdt $mdt_idx $dir"
6769 }
6770 run_test 56rb "check lfs find --size --ost/--mdt works"
6771
6772 test_56rc() {
6773         (( MDSCOUNT >= 2 )) || skip "needs at least 2 MDTs"
6774         local dir=$DIR/$tdir
6775         local found
6776
6777         test_mkdir -c 2 -H all_char $dir || error "failed to mkdir $dir"
6778         $LFS mkdir -c 2 --mdt-hash all_char $dir/$tdir-all{1..10}
6779         (( $MDSCOUNT > 2 )) &&
6780                 $LFS mkdir -c 3 --mdt-hash fnv_1a_64 $dir/$tdir-fnv{1..10}
6781         mkdir $dir/$tdir-{1..10}
6782         touch $dir/$tfile-{1..10}
6783
6784         found=$($LFS find $dir --mdt-count 2 | wc -l)
6785         expect=11
6786         (( $found == $expect )) || error "found $found 2-stripe, expect $expect"
6787
6788         found=$($LFS find $dir -T +1 | wc -l)
6789         (( $MDSCOUNT > 2 )) && expect=$((expect + 10))
6790         (( $found == $expect )) || error "found $found 2+stripe, expect $expect"
6791
6792         found=$($LFS find $dir --mdt-hash all_char | wc -l)
6793         expect=11
6794         (( $found == $expect )) || error "found $found all_char, expect $expect"
6795
6796         found=$($LFS find $dir --mdt-hash fnv_1a_64 | wc -l)
6797         (( $MDSCOUNT > 2 )) && expect=10 || expect=0
6798         (( $found == $expect )) || error "found $found all_char, expect $expect"
6799 }
6800 run_test 56rc "check lfs find --mdt-count/--mdt-hash works"
6801
6802 test_56s() { # LU-611 #LU-9369
6803         [[ $OSTCOUNT -lt 2 ]] && skip_env "need at least 2 OSTs"
6804
6805         local dir=$DIR/$tdir
6806         local onestripe=$(((NUMDIRS + 1) * NUMFILES))
6807
6808         setup_56 $dir $NUMFILES $NUMDIRS "-c 1"
6809         for i in $(seq $NUMDIRS); do
6810                 $LFS setstripe -c $((OSTCOUNT + 1)) $dir/dir$i/$tfile
6811         done
6812
6813         local expected=$NUMDIRS
6814         local cmd="$LFS find -c $OSTCOUNT $dir"
6815         local nums=$($cmd | wc -l)
6816
6817         [ $nums -eq $expected ] || {
6818                 $LFS getstripe -R $dir
6819                 error "'$cmd' wrong: found $nums, expected $expected"
6820         }
6821
6822         expected=$((NUMDIRS + onestripe))
6823         cmd="$LFS find -stripe-count +0 -type f $dir"
6824         nums=$($cmd | wc -l)
6825         [ $nums -eq $expected ] || {
6826                 $LFS getstripe -R $dir
6827                 error "'$cmd' wrong: found $nums, expected $expected"
6828         }
6829
6830         expected=$onestripe
6831         cmd="$LFS find -stripe-count 1 -type f $dir"
6832         nums=$($cmd | wc -l)
6833         [ $nums -eq $expected ] || {
6834                 $LFS getstripe -R $dir
6835                 error "'$cmd' wrong: found $nums, expected $expected"
6836         }
6837
6838         cmd="$LFS find -stripe-count -2 -type f $dir"
6839         nums=$($cmd | wc -l)
6840         [ $nums -eq $expected ] || {
6841                 $LFS getstripe -R $dir
6842                 error "'$cmd' wrong: found $nums, expected $expected"
6843         }
6844
6845         expected=0
6846         cmd="$LFS find -stripe-count $((OSTCOUNT + 1)) -type f $dir"
6847         nums=$($cmd | wc -l)
6848         [ $nums -eq $expected ] || {
6849                 $LFS getstripe -R $dir
6850                 error "'$cmd' wrong: found $nums, expected $expected"
6851         }
6852 }
6853 run_test 56s "check lfs find -stripe-count works"
6854
6855 test_56t() { # LU-611 #LU-9369
6856         local dir=$DIR/$tdir
6857
6858         setup_56 $dir 0 $NUMDIRS
6859         for i in $(seq $NUMDIRS); do
6860                 $LFS setstripe -S 8M $dir/dir$i/$tfile
6861         done
6862
6863         local expected=$NUMDIRS
6864         local cmd="$LFS find -S 8M $dir"
6865         local nums=$($cmd | wc -l)
6866
6867         [ $nums -eq $expected ] || {
6868                 $LFS getstripe -R $dir
6869                 error "'$cmd' wrong: found $nums, expected $expected"
6870         }
6871         rm -rf $dir
6872
6873         setup_56 $dir $NUMFILES $NUMDIRS "--stripe-size 512k"
6874
6875         $LFS setstripe -S 256k $dir/$tfile.{0,1,2,3}
6876
6877         expected=$(((NUMDIRS + 1) * NUMFILES))
6878         cmd="$LFS find -stripe-size 512k -type f $dir"
6879         nums=$($cmd | wc -l)
6880         [ $nums -eq $expected ] ||
6881                 error "'$cmd' wrong: found $nums, expected $expected"
6882
6883         cmd="$LFS find -stripe-size +320k -type f $dir"
6884         nums=$($cmd | wc -l)
6885         [ $nums -eq $expected ] ||
6886                 error "'$cmd' wrong: found $nums, expected $expected"
6887
6888         expected=$(((NUMDIRS + 1) * NUMFILES + 4))
6889         cmd="$LFS find -stripe-size +200k -type f $dir"
6890         nums=$($cmd | wc -l)
6891         [ $nums -eq $expected ] ||
6892                 error "'$cmd' wrong: found $nums, expected $expected"
6893
6894         cmd="$LFS find -stripe-size -640k -type f $dir"
6895         nums=$($cmd | wc -l)
6896         [ $nums -eq $expected ] ||
6897                 error "'$cmd' wrong: found $nums, expected $expected"
6898
6899         expected=4
6900         cmd="$LFS find -stripe-size 256k -type f $dir"
6901         nums=$($cmd | wc -l)
6902         [ $nums -eq $expected ] ||
6903                 error "'$cmd' wrong: found $nums, expected $expected"
6904
6905         cmd="$LFS find -stripe-size -320k -type f $dir"
6906         nums=$($cmd | wc -l)
6907         [ $nums -eq $expected ] ||
6908                 error "'$cmd' wrong: found $nums, expected $expected"
6909
6910         expected=0
6911         cmd="$LFS find -stripe-size 1024k -type f $dir"
6912         nums=$($cmd | wc -l)
6913         [ $nums -eq $expected ] ||
6914                 error "'$cmd' wrong: found $nums, expected $expected"
6915 }
6916 run_test 56t "check lfs find -stripe-size works"
6917
6918 test_56u() { # LU-611
6919         local dir=$DIR/$tdir
6920
6921         setup_56 $dir $NUMFILES $NUMDIRS "-i 0 -c 1"
6922
6923         if [[ $OSTCOUNT -gt 1 ]]; then
6924                 $LFS setstripe -i 1 -c 1 $dir/$tfile.{0,1,2,3}
6925                 onestripe=4
6926         else
6927                 onestripe=0
6928         fi
6929
6930         local expected=$(((NUMDIRS + 1) * NUMFILES))
6931         local cmd="$LFS find -stripe-index 0 -type f $dir"
6932         local nums=$($cmd | wc -l)
6933
6934         [ $nums -eq $expected ] ||
6935                 error "'$cmd' wrong: found $nums, expected $expected"
6936
6937         expected=$onestripe
6938         cmd="$LFS find -stripe-index 1 -type f $dir"
6939         nums=$($cmd | wc -l)
6940         [ $nums -eq $expected ] ||
6941                 error "'$cmd' wrong: found $nums, expected $expected"
6942
6943         cmd="$LFS find ! -stripe-index 0 -type f $dir"
6944         nums=$($cmd | wc -l)
6945         [ $nums -eq $expected ] ||
6946                 error "'$cmd' wrong: found $nums, expected $expected"
6947
6948         expected=0
6949         # This should produce an error and not return any files
6950         cmd="$LFS find -stripe-index $OSTCOUNT -type f $dir"
6951         nums=$($cmd 2>/dev/null | wc -l)
6952         [ $nums -eq $expected ] ||
6953                 error "'$cmd' wrong: found $nums, expected $expected"
6954
6955         if [[ $OSTCOUNT -gt 1 ]]; then
6956                 expected=$(((NUMDIRS + 1) * NUMFILES + onestripe))
6957                 cmd="$LFS find -stripe-index 0,1 -type f $dir"
6958                 nums=$($cmd | wc -l)
6959                 [ $nums -eq $expected ] ||
6960                         error "'$cmd' wrong: found $nums, expected $expected"
6961         fi
6962 }
6963 run_test 56u "check lfs find -stripe-index works"
6964
6965 test_56v() {
6966         local mdt_idx=0
6967         local dir=$DIR/$tdir
6968
6969         setup_56 $dir $NUMFILES $NUMDIRS
6970
6971         UUID=$(mdtuuid_from_index $mdt_idx $dir)
6972         [ -z "$UUID" ] && error "mdtuuid_from_index cannot find MDT $mdt_idx"
6973
6974         for file in $($LFS find -m $UUID $dir); do
6975                 file_midx=$($LFS getstripe -m $file)
6976                 [ $file_midx -eq $mdt_idx ] ||
6977                         error "lfs find -m $UUID != getstripe -m $file_midx"
6978         done
6979 }
6980 run_test 56v "check 'lfs find -m match with lfs getstripe -m'"
6981
6982 test_56w() {
6983         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
6984         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6985
6986         local dir=$DIR/$tdir
6987
6988         setup_56 $dir $NUMFILES $NUMDIRS "-c $OSTCOUNT" "-c1"
6989
6990         local stripe_size=$($LFS getstripe -S -d $dir) ||
6991                 error "$LFS getstripe -S -d $dir failed"
6992         stripe_size=${stripe_size%% *}
6993
6994         local file_size=$((stripe_size * OSTCOUNT))
6995         local file_num=$((NUMDIRS * NUMFILES + NUMFILES))
6996         local required_space=$((file_num * file_size))
6997         local free_space=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
6998                            head -n1)
6999         [[ $free_space -le $((required_space / 1024)) ]] &&
7000                 skip_env "need $required_space, have $free_space kbytes"
7001
7002         local dd_bs=65536
7003         local dd_count=$((file_size / dd_bs))
7004
7005         # write data into the files
7006         local i
7007         local j
7008         local file
7009
7010         for i in $(seq $NUMFILES); do
7011                 file=$dir/file$i
7012                 yes | dd bs=$dd_bs count=$dd_count of=$file &>/dev/null ||
7013                         error "write data into $file failed"
7014         done
7015         for i in $(seq $NUMDIRS); do
7016                 for j in $(seq $NUMFILES); do
7017                         file=$dir/dir$i/file$j
7018                         yes|dd bs=$dd_bs count=$dd_count of=$file &>/dev/null ||
7019                                 error "write data into $file failed"
7020                 done
7021         done
7022
7023         # $LFS_MIGRATE will fail if hard link migration is unsupported
7024         if [[ $MDS1_VERSION -gt $(version_code 2.5.55) ]]; then
7025                 createmany -l$dir/dir1/file1 $dir/dir1/link 200 ||
7026                         error "creating links to $dir/dir1/file1 failed"
7027         fi
7028
7029         local expected=-1
7030
7031         [[ $OSTCOUNT -gt 1 ]] && expected=$((OSTCOUNT - 1))
7032
7033         # lfs_migrate file
7034         local cmd="$LFS_MIGRATE -y -c $expected $dir/file1"
7035
7036         echo "$cmd"
7037         eval $cmd || error "$cmd failed"
7038
7039         check_stripe_count $dir/file1 $expected
7040
7041         if [ $MDS1_VERSION -ge $(version_code 2.6.90) ];
7042         then
7043                 # lfs_migrate file onto OST 0 if it is on OST 1, or onto
7044                 # OST 1 if it is on OST 0. This file is small enough to
7045                 # be on only one stripe.
7046                 file=$dir/migr_1_ost
7047                 dd bs=$dd_bs count=1 if=/dev/urandom of=$file >/dev/null 2>&1 ||
7048                         error "write data into $file failed"
7049                 local obdidx=$($LFS getstripe -i $file)
7050                 local oldmd5=$(md5sum $file)
7051                 local newobdidx=0
7052
7053                 [[ $obdidx -eq 0 ]] && newobdidx=1
7054                 cmd="$LFS migrate -i $newobdidx $file"
7055                 echo $cmd
7056                 eval $cmd || error "$cmd failed"
7057
7058                 local realobdix=$($LFS getstripe -i $file)
7059                 local newmd5=$(md5sum $file)
7060
7061                 [[ $newobdidx -ne $realobdix ]] &&
7062                         error "new OST is different (was=$obdidx, "\
7063                               "wanted=$newobdidx, got=$realobdix)"
7064                 [[ "$oldmd5" != "$newmd5" ]] &&
7065                         error "md5sum differ: $oldmd5, $newmd5"
7066         fi
7067
7068         # lfs_migrate dir
7069         cmd="$LFS_MIGRATE -y -c $expected $dir/dir1"
7070         echo "$cmd"
7071         eval $cmd || error "$cmd failed"
7072
7073         for j in $(seq $NUMFILES); do
7074                 check_stripe_count $dir/dir1/file$j $expected
7075         done
7076
7077         # lfs_migrate works with lfs find
7078         cmd="$LFS find -stripe_count $OSTCOUNT -type f $dir |
7079              $LFS_MIGRATE -y -c $expected"
7080         echo "$cmd"
7081         eval $cmd || error "$cmd failed"
7082
7083         for i in $(seq 2 $NUMFILES); do
7084                 check_stripe_count $dir/file$i $expected
7085         done
7086         for i in $(seq 2 $NUMDIRS); do
7087                 for j in $(seq $NUMFILES); do
7088                 check_stripe_count $dir/dir$i/file$j $expected
7089                 done
7090         done
7091 }
7092 run_test 56w "check lfs_migrate -c stripe_count works"
7093
7094 test_56wb() {
7095         local file1=$DIR/$tdir/file1
7096         local create_pool=false
7097         local initial_pool=$($LFS getstripe -p $DIR)
7098         local pool_list=()
7099         local pool=""
7100
7101         echo -n "Creating test dir..."
7102         test_mkdir $DIR/$tdir &> /dev/null || error "cannot create dir"
7103         echo "done."
7104
7105         echo -n "Creating test file..."
7106         touch $file1 || error "cannot create file"
7107         echo "done."
7108
7109         echo -n "Detecting existing pools..."
7110         pool_list=($($LFS pool_list $FSNAME | grep "$FSNAME\." | cut -d. -f2))
7111
7112         if [ ${#pool_list[@]} -gt 0 ]; then
7113                 echo "${pool_list[@]}"
7114                 for thispool in "${pool_list[@]}"; do
7115                         if [[ -z "$initial_pool" ||
7116                               "$initial_pool" != "$thispool" ]]; then
7117                                 pool="$thispool"
7118                                 echo "Using existing pool '$pool'"
7119                                 break
7120                         fi
7121                 done
7122         else
7123                 echo "none detected."
7124         fi
7125         if [ -z "$pool" ]; then
7126                 pool=${POOL:-testpool}
7127                 [ "$initial_pool" = "$pool" ] && pool="testpool2"
7128                 echo -n "Creating pool '$pool'..."
7129                 create_pool=true
7130                 pool_add $pool &> /dev/null ||
7131                         error "pool_add failed"
7132                 echo "done."
7133
7134                 echo -n "Adding target to pool..."
7135                 pool_add_targets $pool 0 0 1 &> /dev/null ||
7136                         error "pool_add_targets failed"
7137                 echo "done."
7138         fi
7139
7140         echo -n "Setting pool using -p option..."
7141         $LFS_MIGRATE -y -q --no-rsync -p $pool $file1 &> /dev/null ||
7142                 error "migrate failed rc = $?"
7143         echo "done."
7144
7145         echo -n "Verifying test file is in pool after migrating..."
7146         [ "$($LFS getstripe -p $file1)" = $pool ] ||
7147                 error "file was not migrated to pool $pool"
7148         echo "done."
7149
7150         echo -n "Removing test file from pool '$pool'..."
7151         # "lfs migrate $file" won't remove the file from the pool
7152         # until some striping information is changed.
7153         $LFS migrate -c 1 $file1 &> /dev/null ||
7154                 error "cannot remove from pool"
7155         [ "$($LFS getstripe -p $file1)" ] &&
7156                 error "pool still set"
7157         echo "done."
7158
7159         echo -n "Setting pool using --pool option..."
7160         $LFS_MIGRATE -y -q --no-rsync --pool $pool $file1 &> /dev/null ||
7161                 error "migrate failed rc = $?"
7162         echo "done."
7163
7164         # Clean up
7165         rm -f $file1
7166         if $create_pool; then
7167                 destroy_test_pools 2> /dev/null ||
7168                         error "destroy test pools failed"
7169         fi
7170 }
7171 run_test 56wb "check lfs_migrate pool support"
7172
7173 test_56wc() {
7174         local file1="$DIR/$tdir/file1"
7175         local parent_ssize
7176         local parent_scount
7177         local cur_ssize
7178         local cur_scount
7179         local orig_ssize
7180
7181         echo -n "Creating test dir..."
7182         test_mkdir $DIR/$tdir &> /dev/null || error "cannot create dir"
7183         $LFS setstripe -S 1M -c 1 "$DIR/$tdir" &> /dev/null ||
7184                 error "cannot set stripe by '-S 1M -c 1'"
7185         echo "done"
7186
7187         echo -n "Setting initial stripe for test file..."
7188         $LFS setstripe -S 512K -c 1 "$file1" &> /dev/null ||
7189                 error "cannot set stripe"
7190         cur_ssize=$($LFS getstripe -S "$file1")
7191         [ $cur_ssize -eq 524288 ] || error "setstripe -S $cur_ssize != 524288"
7192         echo "done."
7193
7194         # File currently set to -S 512K -c 1
7195
7196         # Ensure -c and -S options are rejected when -R is set
7197         echo -n "Verifying incompatible options are detected..."
7198         $LFS_MIGRATE -y -R -c 1 "$file1" &> /dev/null &&
7199                 error "incompatible -c and -R options not detected"
7200         $LFS_MIGRATE -y -R -S 1M "$file1" &> /dev/null &&
7201                 error "incompatible -S and -R options not detected"
7202         echo "done."
7203
7204         # Ensure unrecognized options are passed through to 'lfs migrate'
7205         echo -n "Verifying -S option is passed through to lfs migrate..."
7206         $LFS_MIGRATE -y -S 1M "$file1" &> /dev/null ||
7207                 error "migration failed"
7208         cur_ssize=$($LFS getstripe -S "$file1")
7209         [ $cur_ssize -eq 1048576 ] || error "migrate -S $cur_ssize != 1048576"
7210         echo "done."
7211
7212         # File currently set to -S 1M -c 1
7213
7214         # Ensure long options are supported
7215         echo -n "Verifying long options supported..."
7216         $LFS_MIGRATE -y --non-block "$file1" &> /dev/null ||
7217                 error "long option without argument not supported"
7218         $LFS_MIGRATE -y --stripe-size 512K "$file1" &> /dev/null ||
7219                 error "long option with argument not supported"
7220         cur_ssize=$($LFS getstripe -S "$file1")
7221         [ $cur_ssize -eq 524288 ] ||
7222                 error "migrate --stripe-size $cur_ssize != 524288"
7223         echo "done."
7224
7225         # File currently set to -S 512K -c 1
7226
7227         if [ "$OSTCOUNT" -gt 1 ]; then
7228                 echo -n "Verifying explicit stripe count can be set..."
7229                 $LFS_MIGRATE -y -c 2 "$file1" &> /dev/null ||
7230                         error "migrate failed"
7231                 cur_scount=$($LFS getstripe -c "$file1")
7232                 [ $cur_scount -eq 2 ] || error "migrate -c $cur_scount != 2"
7233                 echo "done."
7234         fi
7235
7236         # File currently set to -S 512K -c 1 or -S 512K -c 2
7237
7238         # Ensure parent striping is used if -R is set, and no stripe
7239         # count or size is specified
7240         echo -n "Setting stripe for parent directory..."
7241         $LFS setstripe -S 2M -c 1 "$DIR/$tdir" &> /dev/null ||
7242                 error "cannot set stripe '-S 2M -c 1'"
7243         echo "done."
7244
7245         echo -n "Verifying restripe option uses parent stripe settings..."
7246         parent_ssize=$($LFS getstripe -S $DIR/$tdir 2>/dev/null)
7247         parent_scount=$($LFS getstripe -c $DIR/$tdir 2>/dev/null)
7248         $LFS_MIGRATE -y -R "$file1" &> /dev/null ||
7249                 error "migrate failed"
7250         cur_ssize=$($LFS getstripe -S "$file1")
7251         [ $cur_ssize -eq $parent_ssize ] ||
7252                 error "migrate -R stripe_size $cur_ssize != $parent_ssize"
7253         cur_scount=$($LFS getstripe -c "$file1")
7254         [ $cur_scount -eq $parent_scount ] ||
7255                 error "migrate -R stripe_count $cur_scount != $parent_scount"
7256         echo "done."
7257
7258         # File currently set to -S 1M -c 1
7259
7260         # Ensure striping is preserved if -R is not set, and no stripe
7261         # count or size is specified
7262         echo -n "Verifying striping size preserved when not specified..."
7263         orig_ssize=$($LFS getstripe -S "$file1" 2>/dev/null)
7264         $LFS setstripe -S 2M -c 1 "$DIR/$tdir" &> /dev/null ||
7265                 error "cannot set stripe on parent directory"
7266         $LFS_MIGRATE -y "$file1" &> /dev/null ||
7267                 error "migrate failed"
7268         cur_ssize=$($LFS getstripe -S "$file1")
7269         [ $cur_ssize -eq $orig_ssize ] ||
7270                 error "migrate by default $cur_ssize != $orig_ssize"
7271         echo "done."
7272
7273         # Ensure file name properly detected when final option has no argument
7274         echo -n "Verifying file name properly detected..."
7275         $LFS_MIGRATE -y "$file1" &> /dev/null ||
7276                 error "file name interpreted as option argument"
7277         echo "done."
7278
7279         # Clean up
7280         rm -f "$file1"
7281 }
7282 run_test 56wc "check unrecognized options for lfs_migrate are passed through"
7283
7284 test_56wd() {
7285         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7286
7287         local file1=$DIR/$tdir/file1
7288
7289         echo -n "Creating test dir..."
7290         test_mkdir $DIR/$tdir || error "cannot create dir"
7291         echo "done."
7292
7293         echo -n "Creating test file..."
7294         touch $file1
7295         echo "done."
7296
7297         # Ensure 'lfs migrate' will fail by using a non-existent option,
7298         # and make sure rsync is not called to recover
7299         echo -n "Make sure --no-rsync option works..."
7300         $LFS_MIGRATE -y --no-rsync --invalid-opt $file1 2>&1 |
7301                 grep -q 'refusing to fall back to rsync' ||
7302                 error "rsync was called with --no-rsync set"
7303         echo "done."
7304
7305         # Ensure rsync is called without trying 'lfs migrate' first
7306         echo -n "Make sure --rsync option works..."
7307         $LFS_MIGRATE -y --rsync --invalid-opt $file1 2>&1 |
7308                 grep -q 'falling back to rsync' &&
7309                 error "lfs migrate was called with --rsync set"
7310         echo "done."
7311
7312         echo -n "Make sure --rsync and --no-rsync options are exclusive..."
7313         $LFS_MIGRATE -y --rsync --no-rsync $file1 2>&1 |
7314                 grep -q 'at the same time' ||
7315                 error "--rsync and --no-rsync accepted concurrently"
7316         echo "done."
7317
7318         # Clean up
7319         rm -f $file1
7320 }
7321 run_test 56wd "check lfs_migrate --rsync and --no-rsync work"
7322
7323 test_56we() {
7324         local td=$DIR/$tdir
7325         local tf=$td/$tfile
7326
7327         test_mkdir $td || error "cannot create $td"
7328         touch $tf || error "cannot touch $tf"
7329
7330         echo -n "Make sure --non-direct|-D works..."
7331         $LFS_MIGRATE -y --non-direct -v $tf 2>&1 |
7332                 grep -q "lfs migrate --non-direct" ||
7333                 error "--non-direct option cannot work correctly"
7334         $LFS_MIGRATE -y -D -v $tf 2>&1 |
7335                 grep -q "lfs migrate -D" ||
7336                 error "-D option cannot work correctly"
7337         echo "done."
7338 }
7339 run_test 56we "check lfs_migrate --non-direct|-D support"
7340
7341 test_56x() {
7342         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7343         check_swap_layouts_support
7344
7345         local dir=$DIR/$tdir
7346         local ref1=/etc/passwd
7347         local file1=$dir/file1
7348
7349         test_mkdir $dir || error "creating dir $dir"
7350         $LFS setstripe -c 2 $file1
7351         cp $ref1 $file1
7352         $LFS migrate -c 1 $file1 || error "migrate failed rc = $?"
7353         stripe=$($LFS getstripe -c $file1)
7354         [[ $stripe == 1 ]] || error "stripe of $file1 is $stripe != 1"
7355         cmp $file1 $ref1 || error "content mismatch $file1 differs from $ref1"
7356
7357         # clean up
7358         rm -f $file1
7359 }
7360 run_test 56x "lfs migration support"
7361
7362 test_56xa() {
7363         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7364         check_swap_layouts_support
7365
7366         local dir=$DIR/$tdir/$testnum
7367
7368         test_mkdir -p $dir
7369
7370         local ref1=/etc/passwd
7371         local file1=$dir/file1
7372
7373         $LFS setstripe -c 2 $file1
7374         cp $ref1 $file1
7375         $LFS migrate --block -c 1 $file1 || error "migrate failed rc = $?"
7376
7377         local stripe=$($LFS getstripe -c $file1)
7378
7379         [[ $stripe == 1 ]] || error "stripe of $file1 is $stripe != 1"
7380         cmp $file1 $ref1 || error "content mismatch $file1 differs from $ref1"
7381
7382         # clean up
7383         rm -f $file1
7384 }
7385 run_test 56xa "lfs migration --block support"
7386
7387 check_migrate_links() {
7388         local dir="$1"
7389         local file1="$dir/file1"
7390         local begin="$2"
7391         local count="$3"
7392         local runas="$4"
7393         local total_count=$(($begin + $count - 1))
7394         local symlink_count=10
7395         local uniq_count=10
7396
7397         if [ ! -f "$file1" ]; then
7398                 echo -n "creating initial file..."
7399                 $LFS setstripe -c 1 -S "512k" "$file1" ||
7400                         error "cannot setstripe initial file"
7401                 echo "done"
7402
7403                 echo -n "creating symlinks..."
7404                 for s in $(seq 1 $symlink_count); do
7405                         ln -s "$file1" "$dir/slink$s" ||
7406                                 error "cannot create symlinks"
7407                 done
7408                 echo "done"
7409
7410                 echo -n "creating nonlinked files..."
7411                 createmany -o "$dir/uniq" 1 10 &> /dev/null ||
7412                         error "cannot create nonlinked files"
7413                 echo "done"
7414         fi
7415
7416         # create hard links
7417         if [ ! -f "$dir/file$total_count" ]; then
7418                 echo -n "creating hard links $begin:$total_count..."
7419                 createmany -l"$file1" "$dir/file" "$begin" "$count" &>  \
7420                         /dev/null || error "cannot create hard links"
7421                 echo "done"
7422         fi
7423
7424         echo -n "checking number of hard links listed in xattrs..."
7425         local fid=$($LFS getstripe -F "$file1")
7426         local paths=($($LFS fid2path "$MOUNT" "$fid" 2> /dev/null))
7427
7428         echo "${#paths[*]}"
7429         if [ ${#paths[*]} -lt $total_count -a "$begin" -eq 2  ]; then
7430                         skip "hard link list has unexpected size, skipping test"
7431         fi
7432         if [ ${#paths[*]} -ge $total_count -a "$begin" -ne 2  ]; then
7433                         error "link names should exceed xattrs size"
7434         fi
7435
7436         echo -n "migrating files..."
7437         local migrate_out=$($runas $LFS_MIGRATE -y -S '1m' $dir)
7438         local rc=$?
7439         [ $rc -eq 0 ] || error "migrate failed rc = $rc"
7440         echo "done"
7441
7442         # make sure all links have been properly migrated
7443         echo -n "verifying files..."
7444         fid=$($LFS getstripe -F "$file1") ||
7445                 error "cannot get fid for file $file1"
7446         for i in $(seq 2 $total_count); do
7447                 local fid2=$($LFS getstripe -F $dir/file$i)
7448
7449                 [ "$fid2" == "$fid" ] ||
7450                         error "migrated hard link has mismatched FID"
7451         done
7452
7453         # make sure hard links were properly detected, and migration was
7454         # performed only once for the entire link set; nonlinked files should
7455         # also be migrated
7456         local actual=$(grep -c 'done' <<< "$migrate_out")
7457         local expected=$(($uniq_count + 1))
7458
7459         [ "$actual" -eq  "$expected" ] ||
7460                 error "hard links individually migrated ($actual != $expected)"
7461
7462         # make sure the correct number of hard links are present
7463         local hardlinks=$(stat -c '%h' "$file1")
7464
7465         [ $hardlinks -eq $total_count ] ||
7466                 error "num hard links $hardlinks != $total_count"
7467         echo "done"
7468
7469         return 0
7470 }
7471
7472 test_56xb() {
7473         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
7474                 skip "Need MDS version at least 2.10.55"
7475
7476         local dir="$DIR/$tdir"
7477
7478         test_mkdir "$dir" || error "cannot create dir $dir"
7479
7480         echo "testing lfs migrate mode when all links fit within xattrs"
7481         LFS_MIGRATE_RSYNC_MODE=false check_migrate_links "$dir" 2 99
7482
7483         echo "testing rsync mode when all links fit within xattrs"
7484         LFS_MIGRATE_RSYNC_MODE=true check_migrate_links "$dir" 2 99
7485
7486         echo "testing lfs migrate mode when all links do not fit within xattrs"
7487         LFS_MIGRATE_RSYNC_MODE=false check_migrate_links "$dir" 101 100
7488
7489         echo "testing rsync mode when all links do not fit within xattrs"
7490         LFS_MIGRATE_RSYNC_MODE=true check_migrate_links "$dir" 101 100
7491
7492         chown -R $RUNAS_ID $dir
7493         echo "testing non-root lfs migrate mode when not all links are in xattr"
7494         LFS_MIGRATE_RSYNC_MODE=false check_migrate_links "$dir" 101 100 "$RUNAS"
7495
7496         # clean up
7497         rm -rf $dir
7498 }
7499 run_test 56xb "lfs migration hard link support"
7500
7501 test_56xc() {
7502         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7503
7504         local dir="$DIR/$tdir"
7505
7506         test_mkdir "$dir" || error "cannot create dir $dir"
7507
7508         # Test 1: ensure file < 1 GB is always migrated with 1 stripe
7509         echo -n "Setting initial stripe for 20MB test file..."
7510         $LFS setstripe -c 2 -i 0 "$dir/20mb" ||
7511                 error "cannot setstripe 20MB file"
7512         echo "done"
7513         echo -n "Sizing 20MB test file..."
7514         $TRUNCATE "$dir/20mb" 20971520 || error "cannot create 20MB test file"
7515         echo "done"
7516         echo -n "Verifying small file autostripe count is 1..."
7517         $LFS_MIGRATE -y -A -C 1 "$dir/20mb" ||
7518                 error "cannot migrate 20MB file"
7519         local stripe_count=$($LFS getstripe -c "$dir/20mb") ||
7520                 error "cannot get stripe for $dir/20mb"
7521         [ $stripe_count -eq 1 ] ||
7522                 error "unexpected stripe count $stripe_count for 20MB file"
7523         rm -f "$dir/20mb"
7524         echo "done"
7525
7526         # Test 2: File is small enough to fit within the available space on
7527         # sqrt(size_in_gb) + 1 OSTs but is larger than 1GB.  The file must
7528         # have at least an additional 1KB for each desired stripe for test 3
7529         echo -n "Setting stripe for 1GB test file..."
7530         $LFS setstripe -c 1 -i 0 "$dir/1gb" || error "cannot setstripe 1GB file"
7531         echo "done"
7532         echo -n "Sizing 1GB test file..."
7533         # File size is 1GB + 3KB
7534         $TRUNCATE "$dir/1gb" 1073744896 || error "cannot create 1GB test file"
7535         echo "done"
7536
7537         # need at least 512MB per OST for 1GB file to fit in 2 stripes
7538         local avail=$($LCTL get_param -n llite.$FSNAME*.kbytesavail)
7539         if (( avail > 524288 * OSTCOUNT )); then
7540                 echo -n "Migrating 1GB file..."
7541                 $LFS_MIGRATE -y -A -C 1 "$dir/1gb" ||
7542                         error "cannot migrate 1GB file"
7543                 echo "done"
7544                 echo -n "Verifying autostripe count is sqrt(n) + 1..."
7545                 stripe_count=$($LFS getstripe -c "$dir/1gb") ||
7546                         error "cannot getstripe for 1GB file"
7547                 [ $stripe_count -eq 2 ] ||
7548                         error "unexpected stripe count $stripe_count != 2"
7549                 echo "done"
7550         fi
7551
7552         # Test 3: File is too large to fit within the available space on
7553         # sqrt(n) + 1 OSTs.  Simulate limited available space with -X
7554         if [ $OSTCOUNT -ge 3 ]; then
7555                 # The required available space is calculated as
7556                 # file size (1GB + 3KB) / OST count (3).
7557                 local kb_per_ost=349526
7558
7559                 echo -n "Migrating 1GB file with limit..."
7560                 $LFS_MIGRATE -y -A -C 1 -X $kb_per_ost "$dir/1gb" ||
7561                         error "cannot migrate 1GB file with limit"
7562                 echo "done"
7563
7564                 stripe_count=$($LFS getstripe -c "$dir/1gb")
7565                 echo -n "Verifying 1GB autostripe count with limited space..."
7566                 [ "$stripe_count" -a $stripe_count -ge 3 ] ||
7567                         error "unexpected stripe count $stripe_count (min 3)"
7568                 echo "done"
7569         fi
7570
7571         # clean up
7572         rm -rf $dir
7573 }
7574 run_test 56xc "lfs migration autostripe"
7575
7576 test_56xd() {
7577         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7578
7579         local dir=$DIR/$tdir
7580         local f_mgrt=$dir/$tfile.mgrt
7581         local f_yaml=$dir/$tfile.yaml
7582         local f_copy=$dir/$tfile.copy
7583         local layout_yaml="-E 1M -S 512K -c 1 -E -1 -S 1M -c 2 -i 0"
7584         local layout_copy="-c 2 -S 2M -i 1"
7585         local yamlfile=$dir/yamlfile
7586         local layout_before;
7587         local layout_after;
7588
7589         test_mkdir "$dir" || error "cannot create dir $dir"
7590         $LFS setstripe $layout_yaml $f_yaml ||
7591                 error "cannot setstripe $f_yaml with layout $layout_yaml"
7592         $LFS getstripe --yaml $f_yaml > $yamlfile
7593         $LFS setstripe $layout_copy $f_copy ||
7594                 error "cannot setstripe $f_copy with layout $layout_copy"
7595         touch $f_mgrt
7596         dd if=/dev/zero of=$f_mgrt bs=1M count=4
7597
7598         # 1. test option --yaml
7599         $LFS_MIGRATE -y --yaml $yamlfile $f_mgrt ||
7600                 error "cannot migrate $f_mgrt with --yaml $yamlfile"
7601         layout_before=$(get_layout_param $f_yaml)
7602         layout_after=$(get_layout_param $f_mgrt)
7603         [ "$layout_after" == "$layout_before" ] ||
7604                 error "lfs_migrate --yaml: $layout_after != $layout_before"
7605
7606         # 2. test option --copy
7607         $LFS_MIGRATE -y --copy $f_copy $f_mgrt ||
7608                 error "cannot migrate $f_mgrt with --copy $f_copy"
7609         layout_before=$(get_layout_param $f_copy)
7610         layout_after=$(get_layout_param $f_mgrt)
7611         [ "$layout_after" == "$layout_before" ] ||
7612                 error "lfs_migrate --copy: $layout_after != $layout_before"
7613 }
7614 run_test 56xd "check lfs_migrate --yaml and --copy support"
7615
7616 test_56xe() {
7617         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7618
7619         local dir=$DIR/$tdir
7620         local f_comp=$dir/$tfile
7621         local layout="-E 1M -S 512K -c 1 -E -1 -S 1M -c 2 -i 0"
7622         local layout_before=""
7623         local layout_after=""
7624
7625         test_mkdir "$dir" || error "cannot create dir $dir"
7626         $LFS setstripe $layout $f_comp ||
7627                 error "cannot setstripe $f_comp with layout $layout"
7628         layout_before=$(get_layout_param $f_comp)
7629         dd if=/dev/zero of=$f_comp bs=1M count=4
7630
7631         # 1. migrate a comp layout file by lfs_migrate
7632         $LFS_MIGRATE -y $f_comp || error "cannot migrate $f_comp by lfs_migrate"
7633         layout_after=$(get_layout_param $f_comp)
7634         [ "$layout_before" == "$layout_after" ] ||
7635                 error "lfs_migrate: $layout_before != $layout_after"
7636
7637         # 2. migrate a comp layout file by lfs migrate
7638         $LFS migrate $f_comp || error "cannot migrate $f_comp by lfs migrate"
7639         layout_after=$(get_layout_param $f_comp)
7640         [ "$layout_before" == "$layout_after" ] ||
7641                 error "lfs migrate: $layout_before != $layout_after"
7642 }
7643 run_test 56xe "migrate a composite layout file"
7644
7645 test_56xf() {
7646         [[ $OSTCOUNT -ge 2 ]] || skip_env "needs >= 2 OSTs"
7647
7648         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
7649                 skip "Need server version at least 2.13.53"
7650
7651         local dir=$DIR/$tdir
7652         local f_comp=$dir/$tfile
7653         local layout="-E 1M -c1 -E -1 -c2"
7654         local fid_before=""
7655         local fid_after=""
7656
7657         test_mkdir "$dir" || error "cannot create dir $dir"
7658         $LFS setstripe $layout $f_comp ||
7659                 error "cannot setstripe $f_comp with layout $layout"
7660         fid_before=$($LFS getstripe --fid $f_comp)
7661         dd if=/dev/zero of=$f_comp bs=1M count=4
7662
7663         # 1. migrate a comp layout file to a comp layout
7664         $LFS migrate $f_comp || error "cannot migrate $f_comp by lfs migrate"
7665         fid_after=$($LFS getstripe --fid $f_comp)
7666         [ "$fid_before" == "$fid_after" ] ||
7667                 error "comp-to-comp migrate: $fid_before != $fid_after"
7668
7669         # 2. migrate a comp layout file to a plain layout
7670         $LFS migrate -c2 $f_comp ||
7671                 error "cannot migrate $f_comp by lfs migrate"
7672         fid_after=$($LFS getstripe --fid $f_comp)
7673         [ "$fid_before" == "$fid_after" ] ||
7674                 error "comp-to-plain migrate: $fid_before != $fid_after"
7675
7676         # 3. migrate a plain layout file to a comp layout
7677         $LFS migrate $layout $f_comp ||
7678                 error "cannot migrate $f_comp by lfs migrate"
7679         fid_after=$($LFS getstripe --fid $f_comp)
7680         [ "$fid_before" == "$fid_after" ] ||
7681                 error "plain-to-comp migrate: $fid_before != $fid_after"
7682 }
7683 run_test 56xf "FID is not lost during migration of a composite layout file"
7684
7685 check_file_ost_range() {
7686         local file="$1"
7687         shift
7688         local range="$*"
7689         local -a file_range
7690         local idx
7691
7692         file_range=($($LFS getstripe -y "$file" |
7693                 awk '/l_ost_idx:/ { print $NF }'))
7694
7695         if [[ "${#file_range[@]}" = 0 ]]; then
7696                 echo "No osts found for $file"
7697                 return 1
7698         fi
7699
7700         for idx in "${file_range[@]}"; do
7701                 [[ " $range " =~ " $idx " ]] ||
7702                         return 1
7703         done
7704
7705         return 0
7706 }
7707
7708 sub_test_56xg() {
7709         local stripe_opt="$1"
7710         local pool="$2"
7711         shift 2
7712         local pool_ostidx="$(seq $* | tr '\n' ' ')"
7713
7714         $LFS migrate $stripe_opt -p $pool $DIR/$tfile ||
7715                 error "Fail to migrate $tfile on $pool"
7716         [[ "$($LFS getstripe -p $DIR/$tfile)" = "$pool" ]] ||
7717                 error "$tfile is not in pool $pool"
7718         check_file_ost_range "$DIR/$tfile" $pool_ostidx ||
7719                 error "$tfile osts mismatch with pool $pool (osts $pool_ostidx)"
7720 }
7721
7722 test_56xg() {
7723         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
7724         [[ $OSTCOUNT -ge 2 ]] || skip "needs >= 2 OSTs"
7725         [[ $MDS1_VERSION -gt $(version_code 2.14.52) ]] ||
7726                 skip "Need MDS version newer than 2.14.52"
7727
7728         local -a pool_names=("${TESTNAME}_0" "${TESTNAME}_1" "${TESTNAME}_2")
7729         local -a pool_ranges=("0 0" "1 1" "0 1")
7730
7731         # init pools
7732         for i in "${!pool_names[@]}"; do
7733                 pool_add ${pool_names[$i]} ||
7734                         error "pool_add failed (pool: ${pool_names[$i]})"
7735                 pool_add_targets ${pool_names[$i]} ${pool_ranges[$i]} ||
7736                         error "pool_add_targets failed (pool: ${pool_names[$i]})"
7737         done
7738
7739         # init the file to migrate
7740         $LFS setstripe -c1 -i1 $DIR/$tfile ||
7741                 error "Unable to create $tfile on OST1"
7742         dd if=/dev/urandom of=$DIR/$tfile bs=1M count=4 status=none ||
7743                 error "Unable to write on $tfile"
7744
7745         echo "1. migrate $tfile on pool ${pool_names[0]}"
7746         sub_test_56xg "-c-1" "${pool_names[0]}" ${pool_ranges[0]}
7747
7748         echo "2. migrate $tfile on pool ${pool_names[2]}"
7749         sub_test_56xg "-c-1 -S2M" "${pool_names[2]}" ${pool_ranges[2]}
7750
7751         echo "3. migrate $tfile on pool ${pool_names[1]}"
7752         sub_test_56xg "-n -c-1" "${pool_names[1]}" ${pool_ranges[1]}
7753
7754         echo "4. migrate $tfile on pool ${pool_names[2]} with default stripe parameters"
7755         sub_test_56xg "" "${pool_names[2]}" ${pool_ranges[2]}
7756         echo
7757
7758         # Clean pools
7759         destroy_test_pools ||
7760                 error "pool_destroy failed"
7761 }
7762 run_test 56xg "lfs migrate pool support"
7763
7764 test_56y() {
7765         [ $MDS1_VERSION -lt $(version_code 2.4.53) ] &&
7766                 skip "No HSM $(lustre_build_version $SINGLEMDS) MDS < 2.4.53"
7767
7768         local res=""
7769         local dir=$DIR/$tdir
7770         local f1=$dir/file1
7771         local f2=$dir/file2
7772
7773         test_mkdir -p $dir || error "creating dir $dir"
7774         touch $f1 || error "creating std file $f1"
7775         $MULTIOP $f2 H2c || error "creating released file $f2"
7776
7777         # a directory can be raid0, so ask only for files
7778         res=$($LFS find $dir -L raid0 -type f | wc -l)
7779         [[ $res == 2 ]] || error "search raid0: found $res files != 2"
7780
7781         res=$($LFS find $dir \! -L raid0 -type f | wc -l)
7782         [[ $res == 0 ]] || error "search !raid0: found $res files != 0"
7783
7784         # only files can be released, so no need to force file search
7785         res=$($LFS find $dir -L released)
7786         [[ $res == $f2 ]] || error "search released: found $res != $f2"
7787
7788         res=$($LFS find $dir -type f \! -L released)
7789         [[ $res == $f1 ]] || error "search !released: found $res != $f1"
7790 }
7791 run_test 56y "lfs find -L raid0|released"
7792
7793 test_56z() { # LU-4824
7794         # This checks to make sure 'lfs find' continues after errors
7795         # There are two classes of errors that should be caught:
7796         # - If multiple paths are provided, all should be searched even if one
7797         #   errors out
7798         # - If errors are encountered during the search, it should not terminate
7799         #   early
7800         local dir=$DIR/$tdir
7801         local i
7802
7803         test_mkdir $dir
7804         for i in d{0..9}; do
7805                 test_mkdir $dir/$i
7806                 touch $dir/$i/$tfile
7807         done
7808         $LFS find $DIR/non_existent_dir $dir &&
7809                 error "$LFS find did not return an error"
7810         # Make a directory unsearchable. This should NOT be the last entry in
7811         # directory order.  Arbitrarily pick the 6th entry
7812         chmod 700 $($LFS find $dir -type d | sed '6!d')
7813
7814         $RUNAS $LFS find $DIR/non_existent $dir
7815         local count=$($RUNAS $LFS find $DIR/non_existent $dir | wc -l)
7816
7817         # The user should be able to see 10 directories and 9 files
7818         (( count == 19 )) ||
7819                 error "$LFS find found $count != 19 entries after error"
7820 }
7821 run_test 56z "lfs find should continue after an error"
7822
7823 test_56aa() { # LU-5937
7824         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
7825
7826         local dir=$DIR/$tdir
7827
7828         mkdir $dir
7829         $LFS setdirstripe -c$MDSCOUNT $dir/striped_dir
7830
7831         createmany -o $dir/striped_dir/${tfile}- 1024
7832         local dirs=$($LFS find --size +8k $dir/)
7833
7834         [ -n "$dirs" ] || error "lfs find --size wrong under striped dir"
7835 }
7836 run_test 56aa "lfs find --size under striped dir"
7837
7838 test_56ab() { # LU-10705
7839         test_mkdir $DIR/$tdir
7840         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=8k count=1 seek=2k
7841         dd if=/dev/zero of=$DIR/$tdir/$tfile.2 bs=4k count=1 seek=4k
7842         dd if=/dev/zero of=$DIR/$tdir/$tfile.3 bs=1M count=2 seek=16
7843         # Flush writes to ensure valid blocks.  Need to be more thorough for
7844         # ZFS, since blocks are not allocated/returned to client immediately.
7845         sync_all_data
7846         wait_zfs_commit ost1 2
7847         cancel_lru_locks osc
7848         ls -ls $DIR/$tdir
7849
7850         local files=$($LFS find --size +16M $DIR/$tdir | wc -l)
7851
7852         [[ $files == 3 ]] || error ">16M size files $files isn't 3 as expected"
7853
7854         files=$($LFS find --blocks +1M $DIR/$tdir | wc -l)
7855         [[ $files == 1 ]] || error ">1M blocks files $files isn't 1 as expected"
7856
7857         rm -f $DIR/$tdir/$tfile.[123]
7858 }
7859 run_test 56ab "lfs find --blocks"
7860
7861 # LU-11188
7862 test_56aca() {
7863         local dir="$DIR/$tdir"
7864         local perms=(001 002 003 004 005 006 007
7865                      010 020 030 040 050 060 070
7866                      100 200 300 400 500 600 700
7867                      111 222 333 444 555 666 777)
7868         local perm_minus=(8 8 4 8 4 4 2
7869                           8 8 4 8 4 4 2
7870                           8 8 4 8 4 4 2
7871                           4 4 2 4 2 2 1)
7872         local perm_slash=(8  8 12  8 12 12 14
7873                           8  8 12  8 12 12 14
7874                           8  8 12  8 12 12 14
7875                          16 16 24 16 24 24 28)
7876
7877         test_mkdir "$dir"
7878         for perm in ${perms[*]}; do
7879                 touch "$dir/$tfile.$perm"
7880                 chmod $perm "$dir/$tfile.$perm"
7881         done
7882
7883         for ((i = 0; i < ${#perms[*]}; i++)); do
7884                 local num=$($LFS find $dir -perm ${perms[i]} | wc -l)
7885                 (( $num == 1 )) ||
7886                         error "lfs find -perm ${perms[i]}:"\
7887                               "$num != 1"
7888
7889                 num=$($LFS find $dir -perm -${perms[i]} -type f| wc -l)
7890                 (( $num == ${perm_minus[i]} )) ||
7891                         error "lfs find -perm -${perms[i]}:"\
7892                               "$num != ${perm_minus[i]}"
7893
7894                 num=$($LFS find $dir -perm /${perms[i]} -type f| wc -l)
7895                 (( $num == ${perm_slash[i]} )) ||
7896                         error "lfs find -perm /${perms[i]}:"\
7897                               "$num != ${perm_slash[i]}"
7898         done
7899 }
7900 run_test 56aca "check lfs find -perm with octal representation"
7901
7902 test_56acb() {
7903         local dir=$DIR/$tdir
7904         # p is the permission of write and execute for user, group and other
7905         # without the umask. It is used to test +wx.
7906         local p=$(printf "%o" "$((0333 & ~$(umask)))")
7907         local perms=(1000 000 2000 4000 $p 644 111 110 100 004)
7908         local symbolic=(+t  a+t u+t g+t o+t
7909                         g+s u+s o+s +s o+sr
7910                         o=r,ug+o,u+w
7911                         u+ g+ o+ a+ ugo+
7912                         u- g- o- a- ugo-
7913                         u= g= o= a= ugo=
7914                         o=r,ug+o,u+w u=r,a+u,u+w
7915                         g=r,ugo=g,u+w u+x,+X +X
7916                         u+x,u+X u+X u+x,g+X o+r,+X
7917                         u+x,go+X +wx +rwx)
7918
7919         test_mkdir $dir
7920         for perm in ${perms[*]}; do
7921                 touch "$dir/$tfile.$perm"
7922                 chmod $perm "$dir/$tfile.$perm"
7923         done
7924
7925         for (( i = 0; i < ${#symbolic[*]}; i++ )); do
7926                 local num=$($LFS find $dir -perm ${symbolic[i]} | wc -l)
7927
7928                 (( $num == 1 )) ||
7929                         error "lfs find $dir -perm ${symbolic[i]}: $num != 1"
7930         done
7931 }
7932 run_test 56acb "check lfs find -perm with symbolic representation"
7933
7934 test_56acc() {
7935         local dir=$DIR/$tdir
7936         local tests="17777 787 789 abcd
7937                 ug=uu ug=a ug=gu uo=ou urw
7938                 u+xg+x a=r,u+x,"
7939
7940         test_mkdir $dir
7941         for err in $tests; do
7942                 if $LFS find $dir -perm $err 2>/dev/null; then
7943                         error "lfs find -perm $err: parsing should have failed"
7944                 fi
7945         done
7946 }
7947 run_test 56acc "check parsing error for lfs find -perm"
7948
7949 test_56ba() {
7950         [ $MDS1_VERSION -lt $(version_code 2.10.50) ] &&
7951                 skip "Need MDS version at least 2.10.50"
7952
7953         # Create composite files with one component
7954         local dir=$DIR/$tdir
7955
7956         setup_56 $dir/1Mfiles 5 1 "-S 1M --component-end 1M"
7957         # Create composite files with three components
7958         setup_56 $dir/2Mfiles 5 2 "-E 2M -S 1M -E 4M -E 6M"
7959         # Create non-composite files
7960         createmany -o $dir/${tfile}- 10
7961
7962         local nfiles=$($LFS find --component-end 1M --type f $dir | wc -l)
7963
7964         [[ $nfiles == 10 ]] ||
7965                 error "lfs find -E 1M found $nfiles != 10 files"
7966
7967         nfiles=$($LFS find ! -E 1M --type f $dir | wc -l)
7968         [[ $nfiles == 25 ]] ||
7969                 error "lfs find ! -E 1M found $nfiles != 25 files"
7970
7971         # All files have a component that starts at 0
7972         nfiles=$($LFS find --component-start 0 --type f $dir | wc -l)
7973         [[ $nfiles == 35 ]] ||
7974                 error "lfs find --component-start 0 - $nfiles != 35 files"
7975
7976         nfiles=$($LFS find --component-start 2M --type f $dir | wc -l)
7977         [[ $nfiles == 15 ]] ||
7978                 error "lfs find --component-start 2M - $nfiles != 15 files"
7979
7980         # All files created here have a componenet that does not starts at 2M
7981         nfiles=$($LFS find ! --component-start 2M --type f $dir | wc -l)
7982         [[ $nfiles == 35 ]] ||
7983                 error "lfs find ! --component-start 2M - $nfiles != 35 files"
7984
7985         # Find files with a specified number of components
7986         local nfiles=$($LFS find --component-count 3 --type f $dir | wc -l)
7987         [[ $nfiles == 15 ]] ||
7988                 error "lfs find --component-count 3 - $nfiles != 15 files"
7989
7990         # Remember non-composite files have a component count of zero
7991         local nfiles=$($LFS find --component-count 0 --type f $dir | wc -l)
7992         [[ $nfiles == 10 ]] ||
7993                 error "lfs find --component-count 0 - $nfiles != 10 files"
7994
7995         nfiles=$($LFS find ! --component-count 3 --type f $dir | wc -l)
7996         [[ $nfiles == 20 ]] ||
7997                 error "lfs find ! --component-count 3 - $nfiles != 20 files"
7998
7999         # All files have a flag called "init"
8000         local nfiles=$($LFS find --component-flags init --type f $dir | wc -l)
8001         [[ $nfiles == 35 ]] ||
8002                 error "lfs find --component-flags init - $nfiles != 35 files"
8003
8004         # Multi-component files will have a component not initialized
8005         local nfiles=$($LFS find ! --component-flags init --type f $dir | wc -l)
8006         [[ $nfiles == 15 ]] ||
8007                 error "lfs find !--component-flags init - $nfiles != 15 files"
8008
8009         rm -rf $dir
8010
8011 }
8012 run_test 56ba "test lfs find --component-end, -start, -count, and -flags"
8013
8014 test_56ca() {
8015         [[ $MDS1_VERSION -ge $(version_code 2.10.57) ]] ||
8016                 skip "Need MDS version at least 2.10.57"
8017
8018         local td=$DIR/$tdir
8019         local tf=$td/$tfile
8020         local dir
8021         local nfiles
8022         local cmd
8023         local i
8024         local j
8025
8026         # create mirrored directories and mirrored files
8027         mkdir $td || error "mkdir $td failed"
8028         $LFS mirror create -N3 $td || error "create mirrored dir $td failed"
8029         createmany -o $tf- 10 || error "create $tf- failed"
8030
8031         for i in $(seq 2); do
8032                 dir=$td/dir$i
8033                 mkdir $dir || error "mkdir $dir failed"
8034                 $LFS mirror create -N$((3 + i)) $dir ||
8035                         error "create mirrored dir $dir failed"
8036                 createmany -o $dir/$tfile- 10 ||
8037                         error "create $dir/$tfile- failed"
8038         done
8039
8040         # change the states of some mirrored files
8041         echo foo > $tf-6
8042         for i in $(seq 2); do
8043                 dir=$td/dir$i
8044                 for j in $(seq 4 9); do
8045                         echo foo > $dir/$tfile-$j
8046                 done
8047         done
8048
8049         # find mirrored files with specific mirror count
8050         cmd="$LFS find --mirror-count 3 --type f $td"
8051         nfiles=$($cmd | wc -l)
8052         [[ $nfiles = 10 ]] || error "$cmd: $nfiles != 10 files"
8053
8054         cmd="$LFS find ! --mirror-count 3 --type f $td"
8055         nfiles=$($cmd | wc -l)
8056         [[ $nfiles = 20 ]] || error "$cmd: $nfiles != 20 files"
8057
8058         cmd="$LFS find --mirror-count +2 --type f $td"
8059         nfiles=$($cmd | wc -l)
8060         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
8061
8062         cmd="$LFS find --mirror-count -6 --type f $td"
8063         nfiles=$($cmd | wc -l)
8064         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
8065
8066         # find mirrored files with specific file state
8067         cmd="$LFS find --maxdepth 1 --mirror-state=^ro --type f $td"
8068         [[ $($cmd) = $tf-6 ]] || error "$cmd: didn't return $tf-6"
8069
8070         cmd="$LFS find --mirror-state=ro --type f $td"
8071         nfiles=$($cmd | wc -l)
8072         [[ $nfiles = 17 ]] || error "$cmd: $nfiles != 17 files"
8073
8074         cmd="$LFS find ! --mirror-state=ro --type f $td"
8075         nfiles=$($cmd | wc -l)
8076         [[ $nfiles = 13 ]] || error "$cmd: $nfiles != 13 files"
8077
8078         cmd="$LFS find --mirror-state=wp --type f $td"
8079         nfiles=$($cmd | wc -l)
8080         [[ $nfiles = 13 ]] || error "$cmd: $nfiles != 13 files"
8081
8082         cmd="$LFS find ! --mirror-state=sp --type f $td"
8083         nfiles=$($cmd | wc -l)
8084         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
8085 }
8086 run_test 56ca "check lfs find --mirror-count|-N and --mirror-state"
8087
8088 test_56da() { # LU-14179
8089         local path=$DIR/$tdir
8090
8091         test_mkdir $path
8092         cd $path
8093
8094         local longdir=$(str_repeat 'a' 255)
8095
8096         for i in {1..15}; do
8097                 path=$path/$longdir
8098                 test_mkdir $longdir
8099                 cd $longdir
8100         done
8101
8102         local len=${#path}
8103         local lastdir=$(str_repeat 'a' $((4096 - 1 - $len - 1)))
8104
8105         test_mkdir $lastdir
8106         cd $lastdir
8107         # PATH_MAX-1
8108         (( ${#PWD} == 4095 )) || error "bad PWD length ${#PWD}, expect 4095"
8109
8110         # NAME_MAX
8111         touch $(str_repeat 'f' 255)
8112
8113         $LFS find $DIR/$tdir --type d |& grep "lfs find: error" &&
8114                 error "lfs find reported an error"
8115
8116         rm -rf $DIR/$tdir
8117 }
8118 run_test 56da "test lfs find with long paths"
8119
8120 test_57a() {
8121         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8122         # note test will not do anything if MDS is not local
8123         if [ "$mds1_FSTYPE" != ldiskfs ]; then
8124                 skip_env "ldiskfs only test"
8125         fi
8126         remote_mds_nodsh && skip "remote MDS with nodsh"
8127
8128         local MNTDEV="osd*.*MDT*.mntdev"
8129         DEV=$(do_facet $SINGLEMDS lctl get_param -n $MNTDEV)
8130         [ -z "$DEV" ] && error "can't access $MNTDEV"
8131         for DEV in $(do_facet $SINGLEMDS lctl get_param -n $MNTDEV); do
8132                 do_facet $SINGLEMDS $DUMPE2FS -h $DEV > $TMP/t57a.dump ||
8133                         error "can't access $DEV"
8134                 DEVISIZE=$(awk '/Inode size:/ { print $3 }' $TMP/t57a.dump)
8135                 [[ $DEVISIZE -gt 128 ]] || error "inode size $DEVISIZE"
8136                 rm $TMP/t57a.dump
8137         done
8138 }
8139 run_test 57a "verify MDS filesystem created with large inodes =="
8140
8141 test_57b() {
8142         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8143         if [ "$mds1_FSTYPE" != ldiskfs ]; then
8144                 skip_env "ldiskfs only test"
8145         fi
8146         remote_mds_nodsh && skip "remote MDS with nodsh"
8147
8148         local dir=$DIR/$tdir
8149         local filecount=100
8150         local file1=$dir/f1
8151         local fileN=$dir/f$filecount
8152
8153         rm -rf $dir || error "removing $dir"
8154         test_mkdir -c1 $dir
8155         local mdtidx=$($LFS getstripe -m $dir)
8156         local mdtname=MDT$(printf %04x $mdtidx)
8157         local facet=mds$((mdtidx + 1))
8158
8159         echo "mcreating $filecount files"
8160         createmany -m $dir/f 1 $filecount || error "creating files in $dir"
8161
8162         # verify that files do not have EAs yet
8163         $LFS getstripe $file1 2>&1 | grep -q "no stripe" ||
8164                 error "$file1 has an EA"
8165         $LFS getstripe $fileN 2>&1 | grep -q "no stripe" ||
8166                 error "$fileN has an EA"
8167
8168         sync
8169         sleep 1
8170         df $dir  #make sure we get new statfs data
8171         local mdsfree=$(do_facet $facet \
8172                         lctl get_param -n osd*.*$mdtname.kbytesfree)
8173         local mdcfree=$(lctl get_param -n mdc.*$mdtname-mdc-*.kbytesfree)
8174         local file
8175
8176         echo "opening files to create objects/EAs"
8177         for file in $(seq -f $dir/f%g 1 $filecount); do
8178                 $OPENFILE -f O_RDWR $file > /dev/null 2>&1 ||
8179                         error "opening $file"
8180         done
8181
8182         # verify that files have EAs now
8183         $LFS getstripe $file1 | grep -q "obdidx" || error "$file1 missing EA"
8184         $LFS getstripe $fileN | grep -q "obdidx" || error "$fileN missing EA"
8185
8186         sleep 1  #make sure we get new statfs data
8187         df $dir
8188         local mdsfree2=$(do_facet $facet \
8189                          lctl get_param -n osd*.*$mdtname.kbytesfree)
8190         local mdcfree2=$(lctl get_param -n mdc.*$mdtname-mdc-*.kbytesfree)
8191
8192         if [[ $mdcfree2 -lt $((mdcfree - 16)) ]]; then
8193                 if [ "$mdsfree" != "$mdsfree2" ]; then
8194                         error "MDC before $mdcfree != after $mdcfree2"
8195                 else
8196                         echo "MDC before $mdcfree != after $mdcfree2"
8197                         echo "unable to confirm if MDS has large inodes"
8198                 fi
8199         fi
8200         rm -rf $dir
8201 }
8202 run_test 57b "default LOV EAs are stored inside large inodes ==="
8203
8204 test_58() {
8205         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8206         [ -z "$(which wiretest 2>/dev/null)" ] &&
8207                         skip_env "could not find wiretest"
8208
8209         wiretest
8210 }
8211 run_test 58 "verify cross-platform wire constants =============="
8212
8213 test_59() {
8214         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8215
8216         echo "touch 130 files"
8217         createmany -o $DIR/f59- 130
8218         echo "rm 130 files"
8219         unlinkmany $DIR/f59- 130
8220         sync
8221         # wait for commitment of removal
8222         wait_delete_completed
8223 }
8224 run_test 59 "verify cancellation of llog records async ========="
8225
8226 TEST60_HEAD="test_60 run $RANDOM"
8227 test_60a() {
8228         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8229         remote_mgs_nodsh && skip "remote MGS with nodsh"
8230         do_facet mgs "! which run-llog.sh &> /dev/null" &&
8231                 do_facet mgs "! ls run-llog.sh &> /dev/null" &&
8232                         skip_env "missing subtest run-llog.sh"
8233
8234         log "$TEST60_HEAD - from kernel mode"
8235         do_facet mgs "$LCTL dk > /dev/null"
8236         do_facet mgs "bash run-llog.sh" || error "run-llog.sh failed"
8237         do_facet mgs $LCTL dk > $TMP/$tfile
8238
8239         # LU-6388: test llog_reader
8240         local llog_reader=$(do_facet mgs "which llog_reader 2> /dev/null")
8241         llog_reader=${llog_reader:-$LUSTRE/utils/llog_reader}
8242         [ -z $(do_facet mgs ls -d $llog_reader 2> /dev/null) ] &&
8243                         skip_env "missing llog_reader"
8244         local fstype=$(facet_fstype mgs)
8245         [ $fstype != ldiskfs -a $fstype != zfs ] &&
8246                 skip_env "Only for ldiskfs or zfs type mgs"
8247
8248         local mntpt=$(facet_mntpt mgs)
8249         local mgsdev=$(mgsdevname 1)
8250         local fid_list
8251         local fid
8252         local rec_list
8253         local rec
8254         local rec_type
8255         local obj_file
8256         local path
8257         local seq
8258         local oid
8259         local pass=true
8260
8261         #get fid and record list
8262         fid_list=($(awk '/9_sub.*record/ { print $NF }' $TMP/$tfile |
8263                 tail -n 4))
8264         rec_list=($(awk '/9_sub.*record/ { print $((NF-3)) }' $TMP/$tfile |
8265                 tail -n 4))
8266         #remount mgs as ldiskfs or zfs type
8267         stop mgs || error "stop mgs failed"
8268         mount_fstype mgs || error "remount mgs failed"
8269         for ((i = 0; i < ${#fid_list[@]}; i++)); do
8270                 fid=${fid_list[i]}
8271                 rec=${rec_list[i]}
8272                 seq=$(echo $fid | awk -F ':' '{ print $1 }' | sed -e "s/^0x//g")
8273                 oid=$(echo $fid | awk -F ':' '{ print $2 }' | sed -e "s/^0x//g")
8274                 oid=$((16#$oid))
8275
8276                 case $fstype in
8277                         ldiskfs )
8278                                 obj_file=$mntpt/O/$seq/d$((oid%32))/$oid ;;
8279                         zfs )
8280                                 obj_file=$mntpt/oi.$(($((16#$seq))&127))/$fid ;;
8281                 esac
8282                 echo "obj_file is $obj_file"
8283                 do_facet mgs $llog_reader $obj_file
8284
8285                 rec_type=$(do_facet mgs $llog_reader $obj_file | grep "type=" |
8286                         awk '{ print $3 }' | sed -e "s/^type=//g")
8287                 if [ $rec_type != $rec ]; then
8288                         echo "FAILED test_60a wrong record type $rec_type," \
8289                               "should be $rec"
8290                         pass=false
8291                         break
8292                 fi
8293
8294                 #check obj path if record type is LLOG_LOGID_MAGIC
8295                 if [ "$rec" == "1064553b" ]; then
8296                         path=$(do_facet mgs $llog_reader $obj_file |
8297                                 grep "path=" | awk '{ print $NF }' |
8298                                 sed -e "s/^path=//g")
8299                         if [ $obj_file != $mntpt/$path ]; then
8300                                 echo "FAILED test_60a wrong obj path" \
8301                                       "$montpt/$path, should be $obj_file"
8302                                 pass=false
8303                                 break
8304                         fi
8305                 fi
8306         done
8307         rm -f $TMP/$tfile
8308         #restart mgs before "error", otherwise it will block the next test
8309         stop mgs || error "stop mgs failed"
8310         start mgs $(mgsdevname) $MGS_MOUNT_OPTS || error "start mgs failed"
8311         $pass || error "test failed, see FAILED test_60a messages for specifics"
8312 }
8313 run_test 60a "llog_test run from kernel module and test llog_reader"
8314
8315 test_60b() { # bug 6411
8316         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8317
8318         dmesg > $DIR/$tfile
8319         LLOG_COUNT=$(do_facet mgs dmesg |
8320                      awk "/$TEST60_HEAD/ { marker = 1; from_marker = 0; }
8321                           /llog_[a-z]*.c:[0-9]/ {
8322                                 if (marker)
8323                                         from_marker++
8324                                 from_begin++
8325                           }
8326                           END {
8327                                 if (marker)
8328                                         print from_marker
8329                                 else
8330                                         print from_begin
8331                           }")
8332
8333         [[ $LLOG_COUNT -gt 120 ]] &&
8334                 error "CDEBUG_LIMIT not limiting messages ($LLOG_COUNT)" || true
8335 }
8336 run_test 60b "limit repeated messages from CERROR/CWARN"
8337
8338 test_60c() {
8339         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8340
8341         echo "create 5000 files"
8342         createmany -o $DIR/f60c- 5000
8343 #define OBD_FAIL_MDS_LLOG_CREATE_FAILED  0x137
8344         lctl set_param fail_loc=0x80000137
8345         unlinkmany $DIR/f60c- 5000
8346         lctl set_param fail_loc=0
8347 }
8348 run_test 60c "unlink file when mds full"
8349
8350 test_60d() {
8351         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8352
8353         SAVEPRINTK=$(lctl get_param -n printk)
8354         # verify "lctl mark" is even working"
8355         MESSAGE="test message ID $RANDOM $$"
8356         $LCTL mark "$MESSAGE" || error "$LCTL mark failed"
8357         dmesg | grep -q "$MESSAGE" || error "didn't find debug marker in log"
8358
8359         lctl set_param printk=0 || error "set lnet.printk failed"
8360         lctl get_param -n printk | grep emerg || error "lnet.printk dropped emerg"
8361         MESSAGE="new test message ID $RANDOM $$"
8362         # Assume here that libcfs_debug_mark_buffer() uses D_WARNING
8363         $LCTL mark "$MESSAGE" || error "$LCTL mark failed"
8364         dmesg | grep -q "$MESSAGE" && error "D_WARNING wasn't masked" || true
8365
8366         lctl set_param -n printk="$SAVEPRINTK"
8367 }
8368 run_test 60d "test printk console message masking"
8369
8370 test_60e() {
8371         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8372         remote_mds_nodsh && skip "remote MDS with nodsh"
8373
8374         touch $DIR/$tfile
8375 #define OBD_FAIL_MDS_LLOG_CREATE_FAILED2  0x15b
8376         do_facet mds1 lctl set_param fail_loc=0x15b
8377         rm $DIR/$tfile
8378 }
8379 run_test 60e "no space while new llog is being created"
8380
8381 test_60f() {
8382         local old_path=$($LCTL get_param -n debug_path)
8383
8384         stack_trap "$LCTL set_param debug_path=$old_path"
8385         stack_trap "rm -f $TMP/$tfile*"
8386         rm -f $TMP/$tfile* 2> /dev/null
8387         #define OBD_FAIL_PTLRPC_DUMP_LOG         0x50e
8388         $LCTL set_param debug_path=$TMP/$tfile fail_loc=0x8000050e
8389         test_mkdir $DIR/$tdir
8390         # retry in case the open is cached and not released
8391         for (( i = 0; i < 100 && $(ls $TMP/$tfile* | wc -l) == 0; i++ )); do
8392                 echo $i > $DIR/$tdir/$tfile.$i && cat $DIR/$tdir/$tfile.$i
8393                 sleep 0.1
8394         done
8395         ls $TMP/$tfile*
8396         (( $(ls $TMP/$tfile* | wc -l) > 0 )) || error "$TMP/$tfile not dumped"
8397 }
8398 run_test 60f "change debug_path works"
8399
8400 test_60g() {
8401         local pid
8402         local i
8403
8404         test_mkdir -c $MDSCOUNT $DIR/$tdir
8405
8406         (
8407                 local index=0
8408                 while true; do
8409                         $LFS setdirstripe -i $(($index % $MDSCOUNT)) \
8410                                 -c $MDSCOUNT $DIR/$tdir/subdir$index \
8411                                 2>/dev/null
8412                         mkdir $DIR/$tdir/subdir$index 2>/dev/null
8413                         rmdir $DIR/$tdir/subdir$index 2>/dev/null
8414                         index=$((index + 1))
8415                 done
8416         ) &
8417
8418         pid=$!
8419
8420         for i in {0..100}; do
8421                 # define OBD_FAIL_OSD_TXN_START    0x19a
8422                 local index=$((i % MDSCOUNT + 1))
8423
8424                 do_facet mds$index $LCTL set_param fail_loc=0x8000019a \
8425                         > /dev/null
8426                 sleep 0.01
8427         done
8428
8429         kill -9 $pid
8430
8431         for i in $(seq $MDSCOUNT); do
8432                 do_facet mds$i $LCTL set_param fail_loc=0 > /dev/null
8433         done
8434
8435         mkdir $DIR/$tdir/new || error "mkdir failed"
8436         rmdir $DIR/$tdir/new || error "rmdir failed"
8437
8438         do_facet mds1 $LCTL lfsck_start -M $(facet_svc mds1) -A -C \
8439                 -t namespace
8440         for i in $(seq $MDSCOUNT); do
8441                 wait_update_facet mds$i "$LCTL get_param -n \
8442                         mdd.$(facet_svc mds$i).lfsck_namespace |
8443                         awk '/^status/ { print \\\$2 }'" "completed"
8444         done
8445
8446         ls -R $DIR/$tdir || error "ls failed"
8447         rm -rf $DIR/$tdir || error "rmdir failed"
8448 }
8449 run_test 60g "transaction abort won't cause MDT hung"
8450
8451 test_60h() {
8452         [ $MDS1_VERSION -le $(version_code 2.12.52) ] &&
8453                 skip "Need MDS version at least 2.12.52"
8454         [ $MDSCOUNT -lt 2 ] && skip "Need at least 2 MDTs"
8455
8456         local f
8457
8458         #define OBD_FAIL_MDS_STRIPE_CREATE       0x188
8459         #define OBD_FAIL_MDS_STRIPE_FID          0x189
8460         for fail_loc in 0x80000188 0x80000189; do
8461                 do_facet mds1 "$LCTL set_param fail_loc=$fail_loc"
8462                 $LFS mkdir -c $MDSCOUNT -i 0 $DIR/$tdir-$fail_loc ||
8463                         error "mkdir $dir-$fail_loc failed"
8464                 for i in {0..10}; do
8465                         # create may fail on missing stripe
8466                         echo $i > $DIR/$tdir-$fail_loc/$i
8467                 done
8468                 $LFS getdirstripe $DIR/$tdir-$fail_loc ||
8469                         error "getdirstripe $tdir-$fail_loc failed"
8470                 $LFS migrate -m 1 $DIR/$tdir-$fail_loc ||
8471                         error "migrate $tdir-$fail_loc failed"
8472                 $LFS getdirstripe $DIR/$tdir-$fail_loc ||
8473                         error "getdirstripe $tdir-$fail_loc failed"
8474                 pushd $DIR/$tdir-$fail_loc
8475                 for f in *; do
8476                         echo $f | cmp $f - || error "$f data mismatch"
8477                 done
8478                 popd
8479                 rm -rf $DIR/$tdir-$fail_loc
8480         done
8481 }
8482 run_test 60h "striped directory with missing stripes can be accessed"
8483
8484 function t60i_load() {
8485         mkdir $DIR/$tdir
8486         #define OBD_FAIL_LLOG_PAUSE_AFTER_PAD               0x131c
8487         $LCTL set_param fail_loc=0x131c fail_val=1
8488         for ((i=0; i<5000; i++)); do
8489                 touch $DIR/$tdir/f$i
8490         done
8491 }
8492
8493 test_60i() {
8494         changelog_register || error "changelog_register failed"
8495         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
8496         changelog_users $SINGLEMDS | grep -q $cl_user ||
8497                 error "User $cl_user not found in changelog_users"
8498         changelog_chmask "ALL"
8499         t60i_load &
8500         local PID=$!
8501         for((i=0; i<100; i++)); do
8502                 changelog_dump >/dev/null ||
8503                         error "can't read changelog"
8504         done
8505         kill $PID
8506         wait $PID
8507         changelog_deregister || error "changelog_deregister failed"
8508         $LCTL set_param fail_loc=0
8509 }
8510 run_test 60i "llog: new record vs reader race"
8511
8512 test_61a() {
8513         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8514
8515         f="$DIR/f61"
8516         dd if=/dev/zero of=$f bs=$PAGE_SIZE count=1 || error "dd $f failed"
8517         cancel_lru_locks osc
8518         $MULTIOP $f OSMWUc || error "$MULTIOP $f failed"
8519         sync
8520 }
8521 run_test 61a "mmap() writes don't make sync hang ================"
8522
8523 test_61b() {
8524         mmap_mknod_test $DIR/$tfile || error "mmap_mknod_test failed"
8525 }
8526 run_test 61b "mmap() of unstriped file is successful"
8527
8528 # bug 2330 - insufficient obd_match error checking causes LBUG
8529 test_62() {
8530         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8531
8532         f="$DIR/f62"
8533         echo foo > $f
8534         cancel_lru_locks osc
8535         lctl set_param fail_loc=0x405
8536         cat $f && error "cat succeeded, expect -EIO"
8537         lctl set_param fail_loc=0
8538 }
8539 # This test is now irrelevant (as of bug 10718 inclusion), we no longer
8540 # match every page all of the time.
8541 #run_test 62 "verify obd_match failure doesn't LBUG (should -EIO)"
8542
8543 # bug 2319 - oig_wait() interrupted causes crash because of invalid waitq.
8544 # Though this test is irrelevant anymore, it helped to reveal some
8545 # other grant bugs (LU-4482), let's keep it.
8546 test_63a() {   # was test_63
8547         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8548
8549         MAX_DIRTY_MB=$(lctl get_param -n osc.*.max_dirty_mb | head -n 1)
8550
8551         for i in `seq 10` ; do
8552                 dd if=/dev/zero of=$DIR/f63 bs=8k &
8553                 sleep 5
8554                 kill $!
8555                 sleep 1
8556         done
8557
8558         rm -f $DIR/f63 || true
8559 }
8560 run_test 63a "Verify oig_wait interruption does not crash ======="
8561
8562 # bug 2248 - async write errors didn't return to application on sync
8563 # bug 3677 - async write errors left page locked
8564 test_63b() {
8565         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8566
8567         debugsave
8568         lctl set_param debug=-1
8569
8570         # ensure we have a grant to do async writes
8571         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1
8572         rm $DIR/$tfile
8573
8574         sync    # sync lest earlier test intercept the fail_loc
8575
8576         #define OBD_FAIL_OSC_BRW_PREP_REQ        0x406
8577         lctl set_param fail_loc=0x80000406
8578         $MULTIOP $DIR/$tfile Owy && \
8579                 error "sync didn't return ENOMEM"
8580         sync; sleep 2; sync     # do a real sync this time to flush page
8581         lctl get_param -n llite.*.dump_page_cache | grep locked && \
8582                 error "locked page left in cache after async error" || true
8583         debugrestore
8584 }
8585 run_test 63b "async write errors should be returned to fsync ==="
8586
8587 test_64a () {
8588         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8589
8590         lfs df $DIR
8591         lctl get_param osc.*[oO][sS][cC][_-]*.cur* | grep "=[1-9]"
8592 }
8593 run_test 64a "verify filter grant calculations (in kernel) ====="
8594
8595 test_64b () {
8596         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8597
8598         sh oos.sh $MOUNT || error "oos.sh failed: $?"
8599 }
8600 run_test 64b "check out-of-space detection on client"
8601
8602 test_64c() {
8603         $LCTL set_param osc.*OST0000-osc-[^mM]*.cur_grant_bytes=0
8604 }
8605 run_test 64c "verify grant shrink"
8606
8607 import_param() {
8608         local tgt=$1
8609         local param=$2
8610
8611         $LCTL get_param osc.$tgt.import | awk "/$param/ { print \$2 }"
8612 }
8613
8614 # this does exactly what osc_request.c:osc_announce_cached() does in
8615 # order to calculate max amount of grants to ask from server
8616 want_grant() {
8617         local tgt=$1
8618
8619         local nrpages=$($LCTL get_param -n osc.$tgt.max_pages_per_rpc)
8620         local rpc_in_flight=$($LCTL get_param -n osc.$tgt.max_rpcs_in_flight)
8621
8622         ((rpc_in_flight++));
8623         nrpages=$((nrpages * rpc_in_flight))
8624
8625         local dirty_max_pages=$($LCTL get_param -n osc.$tgt.max_dirty_mb)
8626
8627         dirty_max_pages=$((dirty_max_pages * 1024 * 1024 / PAGE_SIZE))
8628
8629         [[ $dirty_max_pages -gt $nrpages ]] && nrpages=$dirty_max_pages
8630         local undirty=$((nrpages * PAGE_SIZE))
8631
8632         local max_extent_pages
8633         max_extent_pages=$(import_param $tgt grant_max_extent_size)
8634         max_extent_pages=$((max_extent_pages / PAGE_SIZE))
8635         local nrextents=$(((nrpages + max_extent_pages - 1) / max_extent_pages))
8636         local grant_extent_tax
8637         grant_extent_tax=$(import_param $tgt grant_extent_tax)
8638
8639         undirty=$((undirty + nrextents * grant_extent_tax))
8640
8641         echo $undirty
8642 }
8643
8644 # this is size of unit for grant allocation. It should be equal to
8645 # what tgt_grant.c:tgt_grant_chunk() calculates
8646 grant_chunk() {
8647         local tgt=$1
8648         local max_brw_size
8649         local grant_extent_tax
8650
8651         max_brw_size=$(import_param $tgt max_brw_size)
8652
8653         grant_extent_tax=$(import_param $tgt grant_extent_tax)
8654
8655         echo $(((max_brw_size + grant_extent_tax) * 2))
8656 }
8657
8658 test_64d() {
8659         [ $OST1_VERSION -ge $(version_code 2.10.56) ] ||
8660                 skip "OST < 2.10.55 doesn't limit grants enough"
8661
8662         local tgt=$($LCTL dl | awk '/OST0000-osc-[^mM]/ { print $4 }')
8663
8664         [[ "$($LCTL get_param osc.${tgt}.import)" =~ "grant_param" ]] ||
8665                 skip "no grant_param connect flag"
8666
8667         local olddebug="$($LCTL get_param -n debug 2> /dev/null)"
8668
8669         $LCTL set_param -n -n debug="$OLDDEBUG" || true
8670         stack_trap "$LCTL set_param -n debug='$olddebug'" EXIT
8671
8672
8673         local max_cur_granted=$(($(want_grant $tgt) + $(grant_chunk $tgt)))
8674         stack_trap "rm -f $DIR/$tfile && wait_delete_completed" EXIT
8675
8676         $LFS setstripe $DIR/$tfile -i 0 -c 1
8677         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1000 &
8678         ddpid=$!
8679
8680         while kill -0 $ddpid; do
8681                 local cur_grant=$($LCTL get_param -n osc.$tgt.cur_grant_bytes)
8682
8683                 if [[ $cur_grant -gt $max_cur_granted ]]; then
8684                         kill $ddpid
8685                         error "cur_grant $cur_grant > $max_cur_granted"
8686                 fi
8687
8688                 sleep 1
8689         done
8690 }
8691 run_test 64d "check grant limit exceed"
8692
8693 check_grants() {
8694         local tgt=$1
8695         local expected=$2
8696         local msg=$3
8697         local cur_grants=$($LCTL get_param -n osc.$tgt.cur_grant_bytes)
8698
8699         ((cur_grants == expected)) ||
8700                 error "$msg: grants mismatch: $cur_grants, expected $expected"
8701 }
8702
8703 round_up_p2() {
8704         echo $((($1 + $2 - 1) & ~($2 - 1)))
8705 }
8706
8707 test_64e() {
8708         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8709         [ $OST1_VERSION -ge $(version_code 2.11.56) ] ||
8710                 skip "Need OSS version at least 2.11.56"
8711
8712         # Remount client to reset grant
8713         remount_client $MOUNT || error "failed to remount client"
8714         local osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
8715
8716         local init_grants=$(import_param $osc_tgt initial_grant)
8717
8718         check_grants $osc_tgt $init_grants "init grants"
8719
8720         local extent_tax=$(import_param $osc_tgt grant_extent_tax)
8721         local max_brw_size=$(import_param $osc_tgt max_brw_size)
8722         local gbs=$(import_param $osc_tgt grant_block_size)
8723
8724         # write random number of bytes from max_brw_size / 4 to max_brw_size
8725         local write_bytes=$(shuf -i $((max_brw_size / 4))-$max_brw_size -n 1)
8726         # align for direct io
8727         write_bytes=$(round_up_p2 $write_bytes PAGE_SIZE)
8728         # round to grant consumption unit
8729         local wb_round_up=$(round_up_p2 $write_bytes gbs)
8730
8731         local grants=$((wb_round_up + extent_tax))
8732
8733         $LFS setstripe -c 1 -i 0 $DIR/$tfile  || error "lfs setstripe failed"
8734
8735         # define OBD_FAIL_TGT_NO_GRANT 0x725
8736         # make the server not grant more back
8737         do_facet ost1 $LCTL set_param fail_loc=0x725
8738         dd if=/dev/zero of=$DIR/$tfile bs=$write_bytes count=1 oflag=direct
8739
8740         do_facet ost1 $LCTL set_param fail_loc=0
8741
8742         check_grants $osc_tgt $((init_grants - grants)) "dio w/o grant alloc"
8743
8744         rm -f $DIR/$tfile || error "rm failed"
8745
8746         # Remount client to reset grant
8747         remount_client $MOUNT || error "failed to remount client"
8748         osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
8749
8750         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "lfs setstripe failed"
8751
8752         # define OBD_FAIL_TGT_NO_GRANT 0x725
8753         # make the server not grant more back
8754         do_facet ost1 $LCTL set_param fail_loc=0x725
8755         $MULTIOP $DIR/$tfile "oO_WRONLY:w${write_bytes}yc"
8756         do_facet ost1 $LCTL set_param fail_loc=0
8757
8758         check_grants $osc_tgt $((init_grants - grants)) "buf io w/o grant alloc"
8759 }
8760 run_test 64e "check grant consumption (no grant allocation)"
8761
8762 test_64f() {
8763         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8764
8765         # Remount client to reset grant
8766         remount_client $MOUNT || error "failed to remount client"
8767         local osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
8768
8769         local init_grants=$(import_param $osc_tgt initial_grant)
8770         local extent_tax=$(import_param $osc_tgt grant_extent_tax)
8771         local max_brw_size=$(import_param $osc_tgt max_brw_size)
8772         local gbs=$(import_param $osc_tgt grant_block_size)
8773         local chunk=$(grant_chunk $osc_tgt)
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         dd if=/dev/zero of=$DIR/$tfile bs=$write_bytes count=1 oflag=direct ||
8786                 error "error writing to $DIR/$tfile"
8787
8788         check_grants $osc_tgt $((init_grants - grants + chunk)) \
8789                 "direct io with grant allocation"
8790
8791         rm -f $DIR/$tfile || error "rm failed"
8792
8793         # Remount client to reset grant
8794         remount_client $MOUNT || error "failed to remount client"
8795         osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
8796
8797         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "lfs setstripe failed"
8798
8799         local cmd="oO_WRONLY:w${write_bytes}_yc"
8800
8801         $MULTIOP $DIR/$tfile $cmd &
8802         MULTIPID=$!
8803         sleep 1
8804
8805         check_grants $osc_tgt $((init_grants - grants)) \
8806                 "buffered io, not write rpc"
8807
8808         kill -USR1 $MULTIPID
8809         wait
8810
8811         check_grants $osc_tgt $((init_grants - grants + chunk)) \
8812                 "buffered io, one RPC"
8813 }
8814 run_test 64f "check grant consumption (with grant allocation)"
8815
8816 test_64g() {
8817         #[ $MDS1_VERSION -lt $(version_code 2.14.54) ] &&
8818         #       skip "Need MDS version at least 2.14.54"
8819
8820         local mdts=$(comma_list $(mdts_nodes))
8821
8822         local old=$($LCTL get_param mdc.$FSNAME-*.grant_shrink_interval |
8823                         tr '\n' ' ')
8824         stack_trap "$LCTL set_param $old"
8825
8826         # generate dirty pages and increase dirty granted on MDT
8827         stack_trap "rm -f $DIR/$tfile-*"
8828         for (( i = 0; i < 10; i++)); do
8829                 $LFS setstripe -E 1M -L mdt $DIR/$tfile-$i ||
8830                         error "can't set stripe"
8831                 dd if=/dev/zero of=$DIR/$tfile-$i bs=128k count=1 ||
8832                         error "can't dd"
8833                 $LFS getstripe $DIR/$tfile-$i | grep -q pattern.*mdt || {
8834                         $LFS getstripe $DIR/$tfile-$i
8835                         error "not DoM file"
8836                 }
8837         done
8838
8839         # flush dirty pages
8840         sync
8841
8842         # wait until grant shrink reset grant dirty on MDTs
8843         for ((i = 0; i < 120; i++)); do
8844                 grant_dirty=$(do_nodes $mdts $LCTL get_param -n  mdt.*.tot_dirty |
8845                         awk '{sum=sum+$1} END {print sum}')
8846                 vm_dirty=$(awk '/Dirty:/{print $2}' /proc/meminfo)
8847                 echo "$grant_dirty grants, $vm_dirty pages"
8848                 (( grant_dirty + vm_dirty == 0 )) && break
8849                 (( i == 3 )) && sync &&
8850                         $LCTL set_param mdc.$FSNAME-*.grant_shrink_interval=5
8851                 sleep 1
8852         done
8853
8854         grant_dirty=$(do_nodes $mdts $LCTL get_param -n  mdt.*.tot_dirty |
8855                 awk '{sum=sum+$1} END {print sum}')
8856         (( grant_dirty == 0 )) || error "$grant_dirty on MDT"
8857 }
8858 run_test 64g "grant shrink on MDT"
8859
8860 test_64h() {
8861         local instance=$($LFS getname -i $DIR)
8862         local osc_tgt="$FSNAME-OST0000-osc-$instance"
8863         local num_exps=$(do_facet ost1 \
8864             $LCTL get_param -n obdfilter.*OST0000*.num_exports)
8865         local max_brw_size=$(import_param $osc_tgt max_brw_size)
8866         local avail=$($LCTL get_param -n osc.*OST0000-osc-$instance.kbytesavail)
8867         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
8868
8869         # 10MiB is for file to be written, max_brw_size * 16 *
8870         # num_exps is space reserve so that tgt_grant_shrink() decided
8871         # to not shrink
8872         local expect=$((max_brw_size * 16 * num_exps + 10 * 1048576))
8873         (( avail * 1024 < expect )) &&
8874                 skip "need $expect bytes on ost1, have $(( avail * 1024 )) only"
8875
8876         save_lustre_params client "osc.*OST0000*.grant_shrink" > $p
8877         save_lustre_params client "osc.*OST0000*.grant_shrink_interval" >> $p
8878         stack_trap "restore_lustre_params < $p; rm -f $save" EXIT
8879         $LCTL set_param osc.*OST0000*.grant_shrink=1
8880         $LCTL set_param osc.*OST0000*.grant_shrink_interval=10
8881
8882         $LFS setstripe -c 1 -i 0 $DIR/$tfile
8883         dd if=/dev/zero of=$DIR/$tfile bs=1M count=10 oflag=sync
8884
8885         # drop cache so that coming read would do rpc
8886         cancel_lru_locks osc
8887
8888         # shrink interval is set to 10, pause for 7 seconds so that
8889         # grant thread did not wake up yet but coming read entered
8890         # shrink mode for rpc (osc_should_shrink_grant())
8891         sleep 7
8892
8893         declare -a cur_grant_bytes
8894         declare -a tot_granted
8895         cur_grant_bytes[0]=$($LCTL get_param -n osc.*OST0000*.cur_grant_bytes)
8896         tot_granted[0]=$(do_facet ost1 \
8897             $LCTL get_param -n obdfilter.*OST0000*.tot_granted)
8898
8899         dd if=$DIR/$tfile bs=4K count=1 of=/dev/null
8900
8901         cur_grant_bytes[1]=$($LCTL get_param -n osc.*OST0000*.cur_grant_bytes)
8902         tot_granted[1]=$(do_facet ost1 \
8903             $LCTL get_param -n obdfilter.*OST0000*.tot_granted)
8904
8905         # grant change should be equal on both sides
8906         (( cur_grant_bytes[0] - cur_grant_bytes[1] ==
8907                 tot_granted[0] - tot_granted[1])) ||
8908                 error "grant change mismatch, "                                \
8909                         "server: ${tot_granted[0]} to ${tot_granted[1]}, "     \
8910                         "client: ${cur_grant_bytes[0]} to ${cur_grant_bytes[1]}"
8911 }
8912 run_test 64h "grant shrink on read"
8913
8914 test_64i() {
8915         (( $OST1_VERSION >= $(version_code 2.14.55) )) ||
8916                 skip "need OST at least 2.14.55 to avoid grant shrink on replay"
8917
8918         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8919         remote_ost_nodsh && skip "remote OSTs with nodsh"
8920
8921         $LFS setstripe -c 1 -i 0 $DIR/$tfile
8922
8923         dd if=/dev/zero of=$DIR/$tfile bs=1M count=64
8924
8925         # lustre-ffff9fc75e850800 /mnt/lustre -> ffff9fc75e850800
8926         local instance=$($LFS getname -i $DIR)
8927
8928         local osc_tgt="$FSNAME-OST0000-osc-$instance"
8929         local cgb=$($LCTL get_param -n osc.$osc_tgt.cur_grant_bytes)
8930
8931         # shrink grants and simulate rpc loss
8932         #define OBD_FAIL_PTLRPC_DROP_REQ_OPC     0x513
8933         do_facet ost1 "$LCTL set_param fail_loc=0x80000513 fail_val=17"
8934         $LCTL set_param osc.$osc_tgt.cur_grant_bytes=$((cgb/2))B
8935
8936         fail ost1
8937
8938         dd if=/dev/zero of=$DIR/$tfile oflag=append bs=1M count=8 conv=notrunc
8939
8940         local testid=$(echo $TESTNAME | tr '_' ' ')
8941
8942         do_facet ost1 dmesg | tac | sed "/$testid/,$ d" |
8943                 grep "GRANT, real grant" &&
8944                 error "client has more grants then it owns" || true
8945 }
8946 run_test 64i "shrink on reconnect"
8947
8948 # bug 1414 - set/get directories' stripe info
8949 test_65a() {
8950         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8951
8952         test_mkdir $DIR/$tdir
8953         touch $DIR/$tdir/f1
8954         $LVERIFY $DIR/$tdir $DIR/$tdir/f1 || error "lverify failed"
8955 }
8956 run_test 65a "directory with no stripe info"
8957
8958 test_65b() {
8959         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8960
8961         test_mkdir $DIR/$tdir
8962         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
8963
8964         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
8965                                                 error "setstripe"
8966         touch $DIR/$tdir/f2
8967         $LVERIFY $DIR/$tdir $DIR/$tdir/f2 || error "lverify failed"
8968 }
8969 run_test 65b "directory setstripe -S stripe_size*2 -i 0 -c 1"
8970
8971 test_65c() {
8972         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8973         [ $OSTCOUNT -lt 2 ] && skip_env "need at least 2 OSTs"
8974
8975         test_mkdir $DIR/$tdir
8976         local stripesize=$($LFS getstripe -S $DIR/$tdir)
8977
8978         $LFS setstripe -S $((stripesize * 4)) -i 1 \
8979                 -c $((OSTCOUNT - 1)) $DIR/$tdir || error "setstripe"
8980         touch $DIR/$tdir/f3
8981         $LVERIFY $DIR/$tdir $DIR/$tdir/f3 || error "lverify failed"
8982 }
8983 run_test 65c "directory setstripe -S stripe_size*4 -i 1 -c $((OSTCOUNT-1))"
8984
8985 test_65d() {
8986         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8987
8988         test_mkdir $DIR/$tdir
8989         local STRIPECOUNT=$($LFS getstripe -c $DIR/$tdir)
8990         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
8991
8992         if [[ $STRIPECOUNT -le 0 ]]; then
8993                 sc=1
8994         elif [[ $STRIPECOUNT -gt $LOV_MAX_STRIPE_COUNT ]]; then
8995                 [[ $OSTCOUNT -gt $LOV_MAX_STRIPE_COUNT ]] &&
8996                         sc=$LOV_MAX_STRIPE_COUNT || sc=$(($OSTCOUNT - 1))
8997         else
8998                 sc=$(($STRIPECOUNT - 1))
8999         fi
9000         $LFS setstripe -S $STRIPESIZE -c $sc $DIR/$tdir || error "setstripe"
9001         touch $DIR/$tdir/f4 $DIR/$tdir/f5
9002         $LVERIFY $DIR/$tdir $DIR/$tdir/f4 $DIR/$tdir/f5 ||
9003                 error "lverify failed"
9004 }
9005 run_test 65d "directory setstripe -S stripe_size -c stripe_count"
9006
9007 test_65e() {
9008         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9009
9010         test_mkdir $DIR/$tdir
9011
9012         $LFS setstripe $DIR/$tdir || error "setstripe"
9013         $LFS getstripe -v $DIR/$tdir | grep "Default" ||
9014                                         error "no stripe info failed"
9015         touch $DIR/$tdir/f6
9016         $LVERIFY $DIR/$tdir $DIR/$tdir/f6 || error "lverify failed"
9017 }
9018 run_test 65e "directory setstripe defaults"
9019
9020 test_65f() {
9021         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9022
9023         test_mkdir $DIR/${tdir}f
9024         $RUNAS $LFS setstripe $DIR/${tdir}f &&
9025                 error "setstripe succeeded" || true
9026 }
9027 run_test 65f "dir setstripe permission (should return error) ==="
9028
9029 test_65g() {
9030         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9031
9032         test_mkdir $DIR/$tdir
9033         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
9034
9035         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
9036                 error "setstripe -S failed"
9037         $LFS setstripe -d $DIR/$tdir || error "setstripe -d failed"
9038         $LFS getstripe -v $DIR/$tdir | grep "Default" ||
9039                 error "delete default stripe failed"
9040 }
9041 run_test 65g "directory setstripe -d"
9042
9043 test_65h() {
9044         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9045
9046         test_mkdir $DIR/$tdir
9047         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
9048
9049         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
9050                 error "setstripe -S failed"
9051         test_mkdir $DIR/$tdir/dd1
9052         [ $($LFS getstripe -c $DIR/$tdir) = $($LFS getstripe -c $DIR/$tdir/dd1) ] ||
9053                 error "stripe info inherit failed"
9054 }
9055 run_test 65h "directory stripe info inherit ===================="
9056
9057 test_65i() {
9058         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9059
9060         save_layout_restore_at_exit $MOUNT
9061
9062         # bug6367: set non-default striping on root directory
9063         $LFS setstripe -S 65536 -c -1 $MOUNT || error "error setting stripe"
9064
9065         # bug12836: getstripe on -1 default directory striping
9066         $LFS getstripe $MOUNT || error "getstripe $MOUNT failed"
9067
9068         # bug12836: getstripe -v on -1 default directory striping
9069         $LFS getstripe -v $MOUNT || error "getstripe -v $MOUNT failed"
9070
9071         # bug12836: new find on -1 default directory striping
9072         $LFS find -mtime -1 $MOUNT > /dev/null || error "find $MOUNT failed"
9073 }
9074 run_test 65i "various tests to set root directory striping"
9075
9076 test_65j() { # bug6367
9077         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9078
9079         sync; sleep 1
9080
9081         # if we aren't already remounting for each test, do so for this test
9082         if [ "$I_MOUNTED" = "yes" ]; then
9083                 cleanup || error "failed to unmount"
9084                 setup
9085         fi
9086
9087         save_layout_restore_at_exit $MOUNT
9088
9089         $LFS setstripe -d $MOUNT || error "setstripe failed"
9090 }
9091 run_test 65j "set default striping on root directory (bug 6367)="
9092
9093 cleanup_65k() {
9094         rm -rf $DIR/$tdir
9095         wait_delete_completed
9096         do_facet $SINGLEMDS "lctl set_param -n \
9097                 osp.$ost*MDT0000.max_create_count=$max_count"
9098         do_facet $SINGLEMDS "lctl set_param -n \
9099                 osp.$ost*MDT0000.create_count=$count"
9100         do_facet $SINGLEMDS lctl --device  %$INACTIVE_OSC activate
9101         echo $INACTIVE_OSC "is Activate"
9102
9103         wait_osc_import_state mds ost$(( ostnum + 1 )) FULL
9104 }
9105
9106 test_65k() { # bug11679
9107         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9108         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
9109         remote_mds_nodsh && skip "remote MDS with nodsh"
9110
9111         local disable_precreate=true
9112         [ $MDS1_VERSION -le $(version_code 2.8.54) ] &&
9113                 disable_precreate=false
9114
9115         echo "Check OST status: "
9116         local MDS_OSCS=$(do_facet $SINGLEMDS lctl dl |
9117                 awk '/[oO][sS][cC].*md[ts]/ { print $4 }')
9118
9119         for OSC in $MDS_OSCS; do
9120                 echo $OSC "is active"
9121                 do_facet $SINGLEMDS lctl --device %$OSC activate
9122         done
9123
9124         for INACTIVE_OSC in $MDS_OSCS; do
9125                 local ost=$(osc_to_ost $INACTIVE_OSC)
9126                 local ostnum=$(do_facet $SINGLEMDS lctl get_param -n \
9127                                lov.*md*.target_obd |
9128                                awk -F: /$ost/'{ print $1 }' | head -n 1)
9129
9130                 mkdir -p $DIR/$tdir
9131                 $LFS setstripe -i $ostnum -c 1 $DIR/$tdir
9132                 createmany -o $DIR/$tdir/$tfile.$ostnum. 1000
9133
9134                 echo "Deactivate: " $INACTIVE_OSC
9135                 do_facet $SINGLEMDS lctl --device %$INACTIVE_OSC deactivate
9136
9137                 local count=$(do_facet $SINGLEMDS "lctl get_param -n \
9138                               osp.$ost*MDT0000.create_count")
9139                 local max_count=$(do_facet $SINGLEMDS "lctl get_param -n \
9140                                   osp.$ost*MDT0000.max_create_count")
9141                 $disable_precreate &&
9142                         do_facet $SINGLEMDS "lctl set_param -n \
9143                                 osp.$ost*MDT0000.max_create_count=0"
9144
9145                 for idx in $(seq 0 $((OSTCOUNT - 1))); do
9146                         [ -f $DIR/$tdir/$idx ] && continue
9147                         echo "$LFS setstripe -i $idx -c 1 $DIR/$tdir/$idx"
9148                         $LFS setstripe -i $idx -c 1 $DIR/$tdir/$idx ||
9149                                 { cleanup_65k;
9150                                   error "setstripe $idx should succeed"; }
9151                         rm -f $DIR/$tdir/$idx || error "rm $idx failed"
9152                 done
9153                 unlinkmany $DIR/$tdir/$tfile.$ostnum. 1000
9154                 rmdir $DIR/$tdir
9155
9156                 do_facet $SINGLEMDS "lctl set_param -n \
9157                         osp.$ost*MDT0000.max_create_count=$max_count"
9158                 do_facet $SINGLEMDS "lctl set_param -n \
9159                         osp.$ost*MDT0000.create_count=$count"
9160                 do_facet $SINGLEMDS lctl --device  %$INACTIVE_OSC activate
9161                 echo $INACTIVE_OSC "is Activate"
9162
9163                 wait_osc_import_state mds ost$(( ostnum + 1 )) FULL
9164         done
9165 }
9166 run_test 65k "validate manual striping works properly with deactivated OSCs"
9167
9168 test_65l() { # bug 12836
9169         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9170
9171         test_mkdir -p $DIR/$tdir/test_dir
9172         $LFS setstripe -c -1 $DIR/$tdir/test_dir
9173         $LFS find -mtime -1 $DIR/$tdir >/dev/null
9174 }
9175 run_test 65l "lfs find on -1 stripe dir ========================"
9176
9177 test_65m() {
9178         local layout=$(save_layout $MOUNT)
9179         $RUNAS $LFS setstripe -c 2 $MOUNT && {
9180                 restore_layout $MOUNT $layout
9181                 error "setstripe should fail by non-root users"
9182         }
9183         true
9184 }
9185 run_test 65m "normal user can't set filesystem default stripe"
9186
9187 test_65n() {
9188         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
9189         [[ $MDS1_VERSION -ge $(version_code 2.12.50) ]] ||
9190                 skip "Need MDS version at least 2.12.50"
9191         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
9192
9193         [[ $OSTCOUNT -ge 2 ]] || skip_env "needs >= 2 OSTs"
9194         which getfattr > /dev/null 2>&1 || skip_env "no getfattr command"
9195         which setfattr > /dev/null 2>&1 || skip_env "no setfattr command"
9196
9197         save_layout_restore_at_exit $MOUNT
9198
9199         # new subdirectory under root directory should not inherit
9200         # the default layout from root
9201         local dir1=$MOUNT/$tdir-1
9202         mkdir $dir1 || error "mkdir $dir1 failed"
9203         ! getfattr -n trusted.lov $dir1 &> /dev/null ||
9204                 error "$dir1 shouldn't have LOV EA"
9205
9206         # delete the default layout on root directory
9207         $LFS setstripe -d $MOUNT || error "delete root default layout failed"
9208
9209         local dir2=$MOUNT/$tdir-2
9210         mkdir $dir2 || error "mkdir $dir2 failed"
9211         ! getfattr -n trusted.lov $dir2 &> /dev/null ||
9212                 error "$dir2 shouldn't have LOV EA"
9213
9214         # set a new striping pattern on root directory
9215         local def_stripe_size=$($LFS getstripe -S $MOUNT)
9216         local new_def_stripe_size=$((def_stripe_size * 2))
9217         $LFS setstripe -S $new_def_stripe_size $MOUNT ||
9218                 error "set stripe size on $MOUNT failed"
9219
9220         # new file created in $dir2 should inherit the new stripe size from
9221         # the filesystem default
9222         local file2=$dir2/$tfile-2
9223         touch $file2 || error "touch $file2 failed"
9224
9225         local file2_stripe_size=$($LFS getstripe -S $file2)
9226         [[ $file2_stripe_size -eq $new_def_stripe_size ]] ||
9227         {
9228                 echo "file2_stripe_size: '$file2_stripe_size'"
9229                 echo "new_def_stripe_size: '$new_def_stripe_size'"
9230                 error "$file2 didn't inherit stripe size $new_def_stripe_size"
9231         }
9232
9233         local dir3=$MOUNT/$tdir-3
9234         mkdir $dir3 || error "mkdir $dir3 failed"
9235         # $dir3 shouldn't have LOV EA, but "lfs getstripe -d $dir3" should show
9236         # the root layout, which is the actual default layout that will be used
9237         # when new files are created in $dir3.
9238         local dir3_layout=$(get_layout_param $dir3)
9239         local root_dir_layout=$(get_layout_param $MOUNT)
9240         [[ "$dir3_layout" = "$root_dir_layout" ]] ||
9241         {
9242                 echo "dir3_layout: '$dir3_layout'"
9243                 echo "root_dir_layout: '$root_dir_layout'"
9244                 error "$dir3 should show the default layout from $MOUNT"
9245         }
9246
9247         # set OST pool on root directory
9248         local pool=$TESTNAME
9249         pool_add $pool || error "add $pool failed"
9250         pool_add_targets $pool 0 $((OSTCOUNT - 1)) 1 ||
9251                 error "add targets to $pool failed"
9252
9253         $LFS setstripe -p $pool $MOUNT ||
9254                 error "set OST pool on $MOUNT failed"
9255
9256         # new file created in $dir3 should inherit the pool from
9257         # the filesystem default
9258         local file3=$dir3/$tfile-3
9259         touch $file3 || error "touch $file3 failed"
9260
9261         local file3_pool=$($LFS getstripe -p $file3)
9262         [[ "$file3_pool" = "$pool" ]] ||
9263                 error "$file3 ('$file3_pool') didn't inherit OST pool '$pool'"
9264
9265         local dir4=$MOUNT/$tdir-4
9266         mkdir $dir4 || error "mkdir $dir4 failed"
9267         local dir4_layout=$(get_layout_param $dir4)
9268         root_dir_layout=$(get_layout_param $MOUNT)
9269         echo "$LFS getstripe -d $dir4"
9270         $LFS getstripe -d $dir4
9271         echo "$LFS getstripe -d $MOUNT"
9272         $LFS getstripe -d $MOUNT
9273         [[ "$dir4_layout" = "$root_dir_layout" ]] ||
9274         {
9275                 echo "dir4_layout: '$dir4_layout'"
9276                 echo "root_dir_layout: '$root_dir_layout'"
9277                 error "$dir4 should show the default layout from $MOUNT"
9278         }
9279
9280         # new file created in $dir4 should inherit the pool from
9281         # the filesystem default
9282         local file4=$dir4/$tfile-4
9283         touch $file4 || error "touch $file4 failed"
9284
9285         local file4_pool=$($LFS getstripe -p $file4)
9286         [[ "$file4_pool" = "$pool" ]] ||
9287                 error "$file4 ('$file4_pool') didn't inherit OST pool $pool"
9288
9289         # new subdirectory under non-root directory should inherit
9290         # the default layout from its parent directory
9291         $LFS setstripe -S $new_def_stripe_size -p $pool $dir4 ||
9292                 error "set directory layout on $dir4 failed"
9293
9294         local dir5=$dir4/$tdir-5
9295         mkdir $dir5 || error "mkdir $dir5 failed"
9296
9297         dir4_layout=$(get_layout_param $dir4)
9298         local dir5_layout=$(get_layout_param $dir5)
9299         [[ "$dir4_layout" = "$dir5_layout" ]] ||
9300         {
9301                 echo "dir4_layout: '$dir4_layout'"
9302                 echo "dir5_layout: '$dir5_layout'"
9303                 error "$dir5 should inherit the default layout from $dir4"
9304         }
9305
9306         # though subdir under ROOT doesn't inherit default layout, but
9307         # its sub dir/file should be created with default layout.
9308         [[ $MDSCOUNT -ge 2 ]] || skip_env "needs >= 2 MDTs"
9309         [[ $MDS1_VERSION -ge $(version_code 2.12.59) ]] ||
9310                 skip "Need MDS version at least 2.12.59"
9311
9312         local default_lmv_count=$($LFS getdirstripe -D -c $MOUNT)
9313         local default_lmv_index=$($LFS getdirstripe -D -i $MOUNT)
9314         local default_lmv_hash=$($LFS getdirstripe -D -H $MOUNT)
9315
9316         if [ $default_lmv_hash == "none" ]; then
9317                 stack_trap "$LFS setdirstripe -D -d $MOUNT" EXIT
9318         else
9319                 stack_trap "$LFS setdirstripe -D -i $default_lmv_index \
9320                         -c $default_lmv_count -H $default_lmv_hash $MOUNT" EXIT
9321         fi
9322
9323         $LFS setdirstripe -D -c 2 $MOUNT ||
9324                 error "setdirstripe -D -c 2 failed"
9325         mkdir $MOUNT/$tdir-6 || error "mkdir $tdir-6 failed"
9326         local lmv_count=$($LFS getdirstripe -c $MOUNT/$tdir-6)
9327         [ $lmv_count -eq 2 ] || error "$tdir-6 stripe count $lmv_count"
9328 }
9329 run_test 65n "don't inherit default layout from root for new subdirectories"
9330
9331 # bug 2543 - update blocks count on client
9332 test_66() {
9333         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9334
9335         COUNT=${COUNT:-8}
9336         dd if=/dev/zero of=$DIR/f66 bs=1k count=$COUNT
9337         sync; sync_all_data; sync; sync_all_data
9338         cancel_lru_locks osc
9339         BLOCKS=`ls -s $DIR/f66 | awk '{ print $1 }'`
9340         [ $BLOCKS -ge $COUNT ] || error "$DIR/f66 blocks $BLOCKS < $COUNT"
9341 }
9342 run_test 66 "update inode blocks count on client ==============="
9343
9344 meminfo() {
9345         awk '($1 == "'$1':") { print $2 }' /proc/meminfo
9346 }
9347
9348 swap_used() {
9349         swapon -s | awk '($1 == "'$1'") { print $4 }'
9350 }
9351
9352 # bug5265, obdfilter oa2dentry return -ENOENT
9353 # #define OBD_FAIL_SRV_ENOENT 0x217
9354 test_69() {
9355         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9356         remote_ost_nodsh && skip "remote OST with nodsh"
9357
9358         f="$DIR/$tfile"
9359         $LFS setstripe -c 1 -i 0 $f
9360
9361         $DIRECTIO write ${f}.2 0 1 || error "directio write error"
9362
9363         do_facet ost1 lctl set_param fail_loc=0x217
9364         $TRUNCATE $f 1 # vmtruncate() will ignore truncate() error.
9365         $DIRECTIO write $f 0 2 && error "write succeeded, expect -ENOENT"
9366
9367         do_facet ost1 lctl set_param fail_loc=0
9368         $DIRECTIO write $f 0 2 || error "write error"
9369
9370         cancel_lru_locks osc
9371         $DIRECTIO read $f 0 1 || error "read error"
9372
9373         do_facet ost1 lctl set_param fail_loc=0x217
9374         $DIRECTIO read $f 1 1 && error "read succeeded, expect -ENOENT"
9375
9376         do_facet ost1 lctl set_param fail_loc=0
9377         rm -f $f
9378 }
9379 run_test 69 "verify oa2dentry return -ENOENT doesn't LBUG ======"
9380
9381 test_71() {
9382         test_mkdir $DIR/$tdir
9383         $LFS setdirstripe -D -c$MDSCOUNT $DIR/$tdir
9384         sh rundbench -C -D $DIR/$tdir 2 || error "dbench failed!"
9385 }
9386 run_test 71 "Running dbench on lustre (don't segment fault) ===="
9387
9388 test_72a() { # bug 5695 - Test that on 2.6 remove_suid works properly
9389         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9390         [ "$RUNAS_ID" = "$UID" ] &&
9391                 skip_env "RUNAS_ID = UID = $UID -- skipping"
9392         # Check that testing environment is properly set up. Skip if not
9393         FAIL_ON_ERROR=false check_runas_id_ret $RUNAS_ID $RUNAS_GID $RUNAS ||
9394                 skip_env "User $RUNAS_ID does not exist - skipping"
9395
9396         touch $DIR/$tfile
9397         chmod 777 $DIR/$tfile
9398         chmod ug+s $DIR/$tfile
9399         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=512 count=1 ||
9400                 error "$RUNAS dd $DIR/$tfile failed"
9401         # See if we are still setuid/sgid
9402         [ -u $DIR/$tfile ] || [ -g $DIR/$tfile ] &&
9403                 error "S/gid is not dropped on write"
9404         # Now test that MDS is updated too
9405         cancel_lru_locks mdc
9406         [ -u $DIR/$tfile ] || [ -g $DIR/$tfile ] &&
9407                 error "S/gid is not dropped on MDS"
9408         rm -f $DIR/$tfile
9409 }
9410 run_test 72a "Test that remove suid works properly (bug5695) ===="
9411
9412 test_72b() { # bug 24226 -- keep mode setting when size is not changing
9413         local perm
9414
9415         [ "$RUNAS_ID" = "$UID" ] &&
9416                 skip_env "RUNAS_ID = UID = $UID -- skipping"
9417         [ "$RUNAS_ID" -eq 0 ] &&
9418                 skip_env "RUNAS_ID = 0 -- skipping"
9419         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9420         # Check that testing environment is properly set up. Skip if not
9421         FAIL_ON_ERROR=false check_runas_id_ret $RUNAS_ID $RUNAS_ID $RUNAS ||
9422                 skip_env "User $RUNAS_ID does not exist - skipping"
9423
9424         touch $DIR/${tfile}-f{g,u}
9425         test_mkdir $DIR/${tfile}-dg
9426         test_mkdir $DIR/${tfile}-du
9427         chmod 770 $DIR/${tfile}-{f,d}{g,u}
9428         chmod g+s $DIR/${tfile}-{f,d}g
9429         chmod u+s $DIR/${tfile}-{f,d}u
9430         for perm in 777 2777 4777; do
9431                 $RUNAS chmod $perm $DIR/${tfile}-fg && error "S/gid file allowed improper chmod to $perm"
9432                 $RUNAS chmod $perm $DIR/${tfile}-fu && error "S/uid file allowed improper chmod to $perm"
9433                 $RUNAS chmod $perm $DIR/${tfile}-dg && error "S/gid dir allowed improper chmod to $perm"
9434                 $RUNAS chmod $perm $DIR/${tfile}-du && error "S/uid dir allowed improper chmod to $perm"
9435         done
9436         true
9437 }
9438 run_test 72b "Test that we keep mode setting if without file data changed (bug 24226)"
9439
9440 # bug 3462 - multiple simultaneous MDC requests
9441 test_73() {
9442         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9443
9444         test_mkdir $DIR/d73-1
9445         test_mkdir $DIR/d73-2
9446         multiop_bg_pause $DIR/d73-1/f73-1 O_c || return 1
9447         pid1=$!
9448
9449         lctl set_param fail_loc=0x80000129
9450         $MULTIOP $DIR/d73-1/f73-2 Oc &
9451         sleep 1
9452         lctl set_param fail_loc=0
9453
9454         $MULTIOP $DIR/d73-2/f73-3 Oc &
9455         pid3=$!
9456
9457         kill -USR1 $pid1
9458         wait $pid1 || return 1
9459
9460         sleep 25
9461
9462         $CHECKSTAT -t file $DIR/d73-1/f73-1 || return 4
9463         $CHECKSTAT -t file $DIR/d73-1/f73-2 || return 5
9464         $CHECKSTAT -t file $DIR/d73-2/f73-3 || return 6
9465
9466         rm -rf $DIR/d73-*
9467 }
9468 run_test 73 "multiple MDC requests (should not deadlock)"
9469
9470 test_74a() { # bug 6149, 6184
9471         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9472
9473         touch $DIR/f74a
9474         #define OBD_FAIL_LDLM_ENQUEUE_OLD_EXPORT 0x30e
9475         #
9476         # very important to OR with OBD_FAIL_ONCE (0x80000000) -- otherwise it
9477         # will spin in a tight reconnection loop
9478         $LCTL set_param fail_loc=0x8000030e
9479         # get any lock that won't be difficult - lookup works.
9480         ls $DIR/f74a
9481         $LCTL set_param fail_loc=0
9482         rm -f $DIR/f74a
9483         true
9484 }
9485 run_test 74a "ldlm_enqueue freed-export error path, ls (shouldn't LBUG)"
9486
9487 test_74b() { # bug 13310
9488         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9489
9490         #define OBD_FAIL_LDLM_ENQUEUE_OLD_EXPORT 0x30e
9491         #
9492         # very important to OR with OBD_FAIL_ONCE (0x80000000) -- otherwise it
9493         # will spin in a tight reconnection loop
9494         $LCTL set_param fail_loc=0x8000030e
9495         # get a "difficult" lock
9496         touch $DIR/f74b
9497         $LCTL set_param fail_loc=0
9498         rm -f $DIR/f74b
9499         true
9500 }
9501 run_test 74b "ldlm_enqueue freed-export error path, touch (shouldn't LBUG)"
9502
9503 test_74c() {
9504         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9505
9506         #define OBD_FAIL_LDLM_NEW_LOCK
9507         $LCTL set_param fail_loc=0x319
9508         touch $DIR/$tfile && error "touch successful"
9509         $LCTL set_param fail_loc=0
9510         true
9511 }
9512 run_test 74c "ldlm_lock_create error path, (shouldn't LBUG)"
9513
9514 slab_lic=/sys/kernel/slab/lustre_inode_cache
9515 num_objects() {
9516         [ -f $slab_lic/shrink ] && echo 1 > $slab_lic/shrink
9517         [ -f $slab_lic/objects ] && awk '{ print $1 }' $slab_lic/objects ||
9518                 awk '/lustre_inode_cache/ { print $2; exit }' /proc/slabinfo
9519 }
9520
9521 test_76a() { # Now for b=20433, added originally in b=1443
9522         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9523
9524         cancel_lru_locks osc
9525         # there may be some slab objects cached per core
9526         local cpus=$(getconf _NPROCESSORS_ONLN 2>/dev/null)
9527         local before=$(num_objects)
9528         local count=$((512 * cpus))
9529         [ "$SLOW" = "no" ] && count=$((128 * cpus))
9530         local margin=$((count / 10))
9531         if [[ -f $slab_lic/aliases ]]; then
9532                 local aliases=$(cat $slab_lic/aliases)
9533                 (( aliases > 0 )) && margin=$((margin * aliases))
9534         fi
9535
9536         echo "before slab objects: $before"
9537         for i in $(seq $count); do
9538                 touch $DIR/$tfile
9539                 rm -f $DIR/$tfile
9540         done
9541         cancel_lru_locks osc
9542         local after=$(num_objects)
9543         echo "created: $count, after slab objects: $after"
9544         # shared slab counts are not very accurate, allow significant margin
9545         # the main goal is that the cache growth is not permanently > $count
9546         while (( after > before + margin )); do
9547                 sleep 1
9548                 after=$(num_objects)
9549                 wait=$((wait + 1))
9550                 (( wait % 5 == 0 )) && echo "wait $wait seconds objects: $after"
9551                 if (( wait > 60 )); then
9552                         error "inode slab grew from $before+$margin to $after"
9553                 fi
9554         done
9555 }
9556 run_test 76a "confirm clients recycle inodes properly ===="
9557
9558 test_76b() {
9559         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9560         [ $CLIENT_VERSION -ge $(version_code 2.13.55) ] || skip "not supported"
9561
9562         local count=512
9563         local before=$(num_objects)
9564
9565         for i in $(seq $count); do
9566                 mkdir $DIR/$tdir
9567                 rmdir $DIR/$tdir
9568         done
9569
9570         local after=$(num_objects)
9571         local wait=0
9572
9573         while (( after > before )); do
9574                 sleep 1
9575                 after=$(num_objects)
9576                 wait=$((wait + 1))
9577                 (( wait % 5 == 0 )) && echo "wait $wait seconds objects: $after"
9578                 if (( wait > 60 )); then
9579                         error "inode slab grew from $before to $after"
9580                 fi
9581         done
9582
9583         echo "slab objects before: $before, after: $after"
9584 }
9585 run_test 76b "confirm clients recycle directory inodes properly ===="
9586
9587 export ORIG_CSUM=""
9588 set_checksums()
9589 {
9590         # Note: in sptlrpc modes which enable its own bulk checksum, the
9591         # original crc32_le bulk checksum will be automatically disabled,
9592         # and the OBD_FAIL_OSC_CHECKSUM_SEND/OBD_FAIL_OSC_CHECKSUM_RECEIVE
9593         # will be checked by sptlrpc code against sptlrpc bulk checksum.
9594         # In this case set_checksums() will not be no-op, because sptlrpc
9595         # bulk checksum will be enabled all through the test.
9596
9597         [ "$ORIG_CSUM" ] || ORIG_CSUM=`lctl get_param -n osc.*.checksums | head -n1`
9598         lctl set_param -n osc.*.checksums $1
9599         return 0
9600 }
9601
9602 export ORIG_CSUM_TYPE="`lctl get_param -n osc.*osc-[^mM]*.checksum_type |
9603                         sed 's/.*\[\(.*\)\].*/\1/g' | head -n1`"
9604 CKSUM_TYPES=${CKSUM_TYPES:-$(lctl get_param -n osc.*osc-[^mM]*.checksum_type |
9605                              tr -d [] | head -n1)}
9606 set_checksum_type()
9607 {
9608         lctl set_param -n osc.*osc-[^mM]*.checksum_type $1
9609         rc=$?
9610         log "set checksum type to $1, rc = $rc"
9611         return $rc
9612 }
9613
9614 get_osc_checksum_type()
9615 {
9616         # arugment 1: OST name, like OST0000
9617         ost=$1
9618         checksum_type=$(lctl get_param -n osc.*${ost}-osc-[^mM]*.checksum_type |
9619                         sed 's/.*\[\(.*\)\].*/\1/g')
9620         rc=$?
9621         [ $rc -ne 0 ] && error "failed to get checksum type of $ost, rc = $rc, output = $checksum_type"
9622         echo $checksum_type
9623 }
9624
9625 F77_TMP=$TMP/f77-temp
9626 F77SZ=8
9627 setup_f77() {
9628         dd if=/dev/urandom of=$F77_TMP bs=1M count=$F77SZ || \
9629                 error "error writing to $F77_TMP"
9630 }
9631
9632 test_77a() { # bug 10889
9633         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9634         $GSS && skip_env "could not run with gss"
9635
9636         [ ! -f $F77_TMP ] && setup_f77
9637         set_checksums 1
9638         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ || error "dd error"
9639         set_checksums 0
9640         rm -f $DIR/$tfile
9641 }
9642 run_test 77a "normal checksum read/write operation"
9643
9644 test_77b() { # bug 10889
9645         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9646         $GSS && skip_env "could not run with gss"
9647
9648         [ ! -f $F77_TMP ] && setup_f77
9649         #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
9650         $LCTL set_param fail_loc=0x80000409
9651         set_checksums 1
9652
9653         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ conv=sync ||
9654                 error "dd error: $?"
9655         $LCTL set_param fail_loc=0
9656
9657         for algo in $CKSUM_TYPES; do
9658                 cancel_lru_locks osc
9659                 set_checksum_type $algo
9660                 #define OBD_FAIL_OSC_CHECKSUM_RECEIVE    0x408
9661                 $LCTL set_param fail_loc=0x80000408
9662                 cmp $F77_TMP $DIR/$tfile || error "file compare failed"
9663                 $LCTL set_param fail_loc=0
9664         done
9665         set_checksums 0
9666         set_checksum_type $ORIG_CSUM_TYPE
9667         rm -f $DIR/$tfile
9668 }
9669 run_test 77b "checksum error on client write, read"
9670
9671 cleanup_77c() {
9672         trap 0
9673         set_checksums 0
9674         $LCTL set_param osc.*osc-[^mM]*.checksum_dump=0
9675         $check_ost &&
9676                 do_facet ost1 $LCTL set_param obdfilter.*-OST*.checksum_dump=0
9677         [ -n "$osc_file_prefix" ] && rm -f ${osc_file_prefix}*
9678         $check_ost && [ -n "$ost_file_prefix" ] &&
9679                 do_facet ost1 rm -f ${ost_file_prefix}\*
9680 }
9681
9682 test_77c() {
9683         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9684         $GSS && skip_env "could not run with gss"
9685         remote_ost_nodsh && skip "remote OST with nodsh"
9686
9687         local bad1
9688         local osc_file_prefix
9689         local osc_file
9690         local check_ost=false
9691         local ost_file_prefix
9692         local ost_file
9693         local orig_cksum
9694         local dump_cksum
9695         local fid
9696
9697         # ensure corruption will occur on first OSS/OST
9698         $LFS setstripe -i 0 $DIR/$tfile
9699
9700         [ ! -f $F77_TMP ] && setup_f77
9701         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ conv=sync ||
9702                 error "dd write error: $?"
9703         fid=$($LFS path2fid $DIR/$tfile)
9704
9705         if [ $OST1_VERSION -ge $(version_code 2.9.57) ]
9706         then
9707                 check_ost=true
9708                 ost_file_prefix=$(do_facet ost1 $LCTL get_param -n debug_path)
9709                 ost_file_prefix=${ost_file_prefix}-checksum_dump-ost-\\${fid}
9710         else
9711                 echo "OSS do not support bulk pages dump upon error"
9712         fi
9713
9714         osc_file_prefix=$($LCTL get_param -n debug_path)
9715         osc_file_prefix=${osc_file_prefix}-checksum_dump-osc-\\${fid}
9716
9717         trap cleanup_77c EXIT
9718
9719         set_checksums 1
9720         # enable bulk pages dump upon error on Client
9721         $LCTL set_param osc.*osc-[^mM]*.checksum_dump=1
9722         # enable bulk pages dump upon error on OSS
9723         $check_ost &&
9724                 do_facet ost1 $LCTL set_param obdfilter.*-OST*.checksum_dump=1
9725
9726         # flush Client cache to allow next read to reach OSS
9727         cancel_lru_locks osc
9728
9729         #define OBD_FAIL_OSC_CHECKSUM_RECEIVE       0x408
9730         $LCTL set_param fail_loc=0x80000408
9731         dd if=$DIR/$tfile of=/dev/null bs=1M || error "dd read error: $?"
9732         $LCTL set_param fail_loc=0
9733
9734         rm -f $DIR/$tfile
9735
9736         # check cksum dump on Client
9737         osc_file=$(ls ${osc_file_prefix}*)
9738         [ -n "$osc_file" ] || error "no checksum dump file on Client"
9739         # OBD_FAIL_OSC_CHECKSUM_RECEIVE corrupts with "bad1" at start of file
9740         bad1=$(dd if=$osc_file bs=1 count=4 2>/dev/null) || error "dd error: $?"
9741         [ $bad1 == "bad1" ] || error "unexpected corrupt pattern"
9742         orig_cksum=$(dd if=$F77_TMP bs=1 skip=4 count=1048572 2>/dev/null |
9743                      cksum)
9744         dump_cksum=$(dd if=$osc_file bs=1 skip=4 2>/dev/null | cksum)
9745         [[ "$orig_cksum" == "$dump_cksum" ]] ||
9746                 error "dump content does not match on Client"
9747
9748         $check_ost || skip "No need to check cksum dump on OSS"
9749
9750         # check cksum dump on OSS
9751         ost_file=$(do_facet ost1 ls ${ost_file_prefix}\*)
9752         [ -n "$ost_file" ] || error "no checksum dump file on OSS"
9753         orig_cksum=$(dd if=$F77_TMP bs=1048576 count=1 2>/dev/null | cksum)
9754         dump_cksum=$(do_facet ost1 dd if=$ost_file 2>/dev/null \| cksum)
9755         [[ "$orig_cksum" == "$dump_cksum" ]] ||
9756                 error "dump content does not match on OSS"
9757
9758         cleanup_77c
9759 }
9760 run_test 77c "checksum error on client read with debug"
9761
9762 test_77d() { # bug 10889
9763         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9764         $GSS && skip_env "could not run with gss"
9765
9766         stack_trap "rm -f $DIR/$tfile"
9767         #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
9768         $LCTL set_param fail_loc=0x80000409
9769         set_checksums 1
9770         $DIRECTIO write $DIR/$tfile 0 $F77SZ $((1024 * 1024)) ||
9771                 error "direct write: rc=$?"
9772         $LCTL set_param fail_loc=0
9773         set_checksums 0
9774
9775         #define OBD_FAIL_OSC_CHECKSUM_RECEIVE    0x408
9776         $LCTL set_param fail_loc=0x80000408
9777         set_checksums 1
9778         cancel_lru_locks osc
9779         $DIRECTIO read $DIR/$tfile 0 $F77SZ $((1024 * 1024)) ||
9780                 error "direct read: rc=$?"
9781         $LCTL set_param fail_loc=0
9782         set_checksums 0
9783 }
9784 run_test 77d "checksum error on OST direct write, read"
9785
9786 test_77f() { # bug 10889
9787         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9788         $GSS && skip_env "could not run with gss"
9789
9790         set_checksums 1
9791         stack_trap "rm -f $DIR/$tfile"
9792         for algo in $CKSUM_TYPES; do
9793                 cancel_lru_locks osc
9794                 set_checksum_type $algo
9795                 #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
9796                 $LCTL set_param fail_loc=0x409
9797                 $DIRECTIO write $DIR/$tfile 0 $F77SZ $((1024 * 1024)) &&
9798                         error "direct write succeeded"
9799                 $LCTL set_param fail_loc=0
9800         done
9801         set_checksum_type $ORIG_CSUM_TYPE
9802         set_checksums 0
9803 }
9804 run_test 77f "repeat checksum error on write (expect error)"
9805
9806 test_77g() { # bug 10889
9807         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9808         $GSS && skip_env "could not run with gss"
9809         remote_ost_nodsh && skip "remote OST with nodsh"
9810
9811         [ ! -f $F77_TMP ] && setup_f77
9812
9813         local file=$DIR/$tfile
9814         stack_trap "rm -f $file" EXIT
9815
9816         $LFS setstripe -c 1 -i 0 $file
9817         #define OBD_FAIL_OST_CHECKSUM_RECEIVE       0x21a
9818         do_facet ost1 lctl set_param fail_loc=0x8000021a
9819         set_checksums 1
9820         dd if=$F77_TMP of=$file bs=1M count=$F77SZ ||
9821                 error "write error: rc=$?"
9822         do_facet ost1 lctl set_param fail_loc=0
9823         set_checksums 0
9824
9825         cancel_lru_locks osc
9826         #define OBD_FAIL_OST_CHECKSUM_SEND          0x21b
9827         do_facet ost1 lctl set_param fail_loc=0x8000021b
9828         set_checksums 1
9829         cmp $F77_TMP $file || error "file compare failed"
9830         do_facet ost1 lctl set_param fail_loc=0
9831         set_checksums 0
9832 }
9833 run_test 77g "checksum error on OST write, read"
9834
9835 test_77k() { # LU-10906
9836         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9837         $GSS && skip_env "could not run with gss"
9838
9839         local cksum_param="osc.$FSNAME*.checksums"
9840         local get_checksum="$LCTL get_param -n $cksum_param | head -n1"
9841         local checksum
9842         local i
9843
9844         [ "$ORIG_CSUM" ] || ORIG_CSUM=$(eval $get_checksum)
9845         stack_trap "wait_update $HOSTNAME '$get_checksum' $ORIG_CSUM || true"
9846         stack_trap "do_facet mgs $LCTL set_param -P $cksum_param=$ORIG_CSUM"
9847
9848         for i in 0 1; do
9849                 do_facet mgs $LCTL set_param -P $cksum_param=$i ||
9850                         error "failed to set checksum=$i on MGS"
9851                 wait_update $HOSTNAME "$get_checksum" $i
9852                 #remount
9853                 echo "remount client, checksum should be $i"
9854                 remount_client $MOUNT || error "failed to remount client"
9855                 checksum=$(eval $get_checksum)
9856                 [ $checksum -eq $i ] || error "checksum($checksum) != $i"
9857         done
9858         # remove persistent param to avoid races with checksum mountopt below
9859         do_facet mgs $LCTL set_param -P -d $cksum_param ||
9860                 error "failed to delete checksum on MGS"
9861
9862         for opt in "checksum" "nochecksum"; do
9863                 #remount with mount option
9864                 echo "remount client with option $opt, checksum should be $i"
9865                 umount_client $MOUNT || error "failed to umount client"
9866                 mount_client $MOUNT "$MOUNT_OPTS,$opt" ||
9867                         error "failed to mount client with option '$opt'"
9868                 checksum=$(eval $get_checksum)
9869                 [ $checksum -eq $i ] || error "checksum($checksum) != $i"
9870                 i=$((i - 1))
9871         done
9872
9873         remount_client $MOUNT || error "failed to remount client"
9874 }
9875 run_test 77k "enable/disable checksum correctly"
9876
9877 test_77l() {
9878         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9879         $GSS && skip_env "could not run with gss"
9880
9881         set_checksums 1
9882         stack_trap "set_checksums $ORIG_CSUM" EXIT
9883         stack_trap "set_checksum_type $ORIG_CSUM_TYPE" EXIT
9884
9885         set_checksum_type invalid && error "unexpected success of invalid checksum type"
9886
9887         $LFS setstripe -c 1 -i 0 $DIR/$tfile
9888         for algo in $CKSUM_TYPES; do
9889                 set_checksum_type $algo || error "fail to set checksum type $algo"
9890                 osc_algo=$(get_osc_checksum_type OST0000)
9891                 [ "$osc_algo" != "$algo" ] && error "checksum type is $osc_algo after setting it to $algo"
9892
9893                 # no locks, no reqs to let the connection idle
9894                 cancel_lru_locks osc
9895                 lru_resize_disable osc
9896                 wait_osc_import_state client ost1 IDLE
9897
9898                 # ensure ost1 is connected
9899                 stat $DIR/$tfile >/dev/null || error "can't stat"
9900                 wait_osc_import_state client ost1 FULL
9901
9902                 osc_algo=$(get_osc_checksum_type OST0000)
9903                 [ "$osc_algo" != "$algo" ] && error "checksum type changed from $algo to $osc_algo after reconnection"
9904         done
9905         return 0
9906 }
9907 run_test 77l "preferred checksum type is remembered after reconnected"
9908
9909 [ "$ORIG_CSUM" ] && set_checksums $ORIG_CSUM || true
9910 rm -f $F77_TMP
9911 unset F77_TMP
9912
9913 test_77m() {
9914         (( $CLIENT_VERSION >= $(version_code 2.14.52) )) ||
9915                 skip "Need at least version 2.14.52"
9916         local param=checksum_speed
9917
9918         $LCTL get_param $param || error "reading $param failed"
9919
9920         csum_speeds=$($LCTL get_param -n $param)
9921
9922         [[ "$csum_speeds" =~ "adler32" && "$csum_speeds" =~ "crc32" ]] ||
9923                 error "known checksum types are missing"
9924 }
9925 run_test 77m "Verify checksum_speed is correctly read"
9926
9927 check_filefrag_77n() {
9928         local nr_ext=0
9929         local starts=()
9930         local ends=()
9931
9932         while read extidx a b start end rest; do
9933                 if [[ "${extidx}" =~ ^[0-9]+: ]]; then
9934                         nr_ext=$(( $nr_ext + 1 ))
9935                         starts+=( ${start%..} )
9936                         ends+=( ${end%:} )
9937                 fi
9938         done < <( filefrag -sv $1 )
9939
9940         [[ $nr_ext -eq 2 ]] && [[ "${starts[-1]}" == $(( ${ends[0]} + 1 )) ]] && return 0
9941         return 1
9942 }
9943
9944 test_77n() {
9945         [[ "$CKSUM_TYPES" =~ t10 ]] || skip "no T10 checksum support on osc"
9946
9947         touch $DIR/$tfile
9948         $TRUNCATE $DIR/$tfile 0
9949         dd if=/dev/urandom of=$DIR/$tfile bs=4k conv=notrunc count=1 seek=0
9950         dd if=/dev/urandom of=$DIR/$tfile bs=4k conv=notrunc count=1 seek=2
9951         check_filefrag_77n $DIR/$tfile ||
9952                 skip "$tfile blocks not contiguous around hole"
9953
9954         set_checksums 1
9955         stack_trap "set_checksums $ORIG_CSUM" EXIT
9956         stack_trap "set_checksum_type $ORIG_CSUM_TYPE" EXIT
9957         stack_trap "rm -f $DIR/$tfile"
9958
9959         for algo in $CKSUM_TYPES; do
9960                 if [[ "$algo" =~ ^t10 ]]; then
9961                         set_checksum_type $algo ||
9962                                 error "fail to set checksum type $algo"
9963                         dd if=$DIR/$tfile of=/dev/null bs=12k count=1 iflag=direct ||
9964                                 error "fail to read $tfile with $algo"
9965                 fi
9966         done
9967         rm -f $DIR/$tfile
9968         return 0
9969 }
9970 run_test 77n "Verify read from a hole inside contiguous blocks with T10PI"
9971
9972 test_77o() {
9973         (( $CLIENT_VERSION >= $(version_code 2.14.54) )) ||
9974                 skip "Need at least version 2.14.54"
9975         local ofd=obdfilter
9976         local mdt=mdt
9977
9978         # print OST checksum_type
9979         echo "$ofd.$FSNAME-*.checksum_type:"
9980         do_nodes $(comma_list $(osts_nodes)) \
9981                 $LCTL get_param -n $ofd.$FSNAME-*.checksum_type
9982
9983         # print MDT checksum_type
9984         echo "$mdt.$FSNAME-*.checksum_type:"
9985         do_nodes $(comma_list $(mdts_nodes)) \
9986                 $LCTL get_param -n $mdt.$FSNAME-*.checksum_type
9987
9988         local o_count=$(do_nodes $(comma_list $(osts_nodes)) \
9989                    $LCTL get_param -n $ofd.$FSNAME-*.checksum_type | wc -l)
9990
9991         (( $o_count == $OSTCOUNT )) ||
9992                 error "found $o_count checksums, not \$MDSCOUNT=$OSTCOUNT"
9993
9994         local m_count=$(do_nodes $(comma_list $(mdts_nodes)) \
9995                    $LCTL get_param -n $mdt.$FSNAME-*.checksum_type | wc -l)
9996
9997         (( $m_count == $MDSCOUNT )) ||
9998                 error "found $m_count checksums, not \$MDSCOUNT=$MDSCOUNT"
9999 }
10000 run_test 77o "Verify checksum_type for server (mdt and ofd(obdfilter))"
10001
10002 cleanup_test_78() {
10003         trap 0
10004         rm -f $DIR/$tfile
10005 }
10006
10007 test_78() { # bug 10901
10008         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10009         remote_ost || skip_env "local OST"
10010
10011         NSEQ=5
10012         F78SIZE=$(($(awk '/MemFree:/ { print $2 }' /proc/meminfo) / 1024))
10013         echo "MemFree: $F78SIZE, Max file size: $MAXFREE"
10014         MEMTOTAL=$(($(awk '/MemTotal:/ { print $2 }' /proc/meminfo) / 1024))
10015         echo "MemTotal: $MEMTOTAL"
10016
10017         # reserve 256MB of memory for the kernel and other running processes,
10018         # and then take 1/2 of the remaining memory for the read/write buffers.
10019         if [ $MEMTOTAL -gt 512 ] ;then
10020                 MEMTOTAL=$(((MEMTOTAL - 256 ) / 2))
10021         else
10022                 # for those poor memory-starved high-end clusters...
10023                 MEMTOTAL=$((MEMTOTAL / 2))
10024         fi
10025         echo "Mem to use for directio: $MEMTOTAL"
10026
10027         [[ $F78SIZE -gt $MEMTOTAL ]] && F78SIZE=$MEMTOTAL
10028         [[ $F78SIZE -gt 512 ]] && F78SIZE=512
10029         [[ $F78SIZE -gt $((MAXFREE / 1024)) ]] && F78SIZE=$((MAXFREE / 1024))
10030         SMALLESTOST=$($LFS df $DIR | grep OST | awk '{ print $4 }' | sort -n |
10031                 head -n1)
10032         echo "Smallest OST: $SMALLESTOST"
10033         [[ $SMALLESTOST -lt 10240 ]] &&
10034                 skip "too small OSTSIZE, useless to run large O_DIRECT test"
10035
10036         trap cleanup_test_78 EXIT
10037
10038         [[ $F78SIZE -gt $((SMALLESTOST * $OSTCOUNT / 1024 - 80)) ]] &&
10039                 F78SIZE=$((SMALLESTOST * $OSTCOUNT / 1024 - 80))
10040
10041         [ "$SLOW" = "no" ] && NSEQ=1 && [ $F78SIZE -gt 32 ] && F78SIZE=32
10042         echo "File size: $F78SIZE"
10043         $LFS setstripe -c $OSTCOUNT $DIR/$tfile || error "setstripe failed"
10044         for i in $(seq 1 $NSEQ); do
10045                 FSIZE=$(($F78SIZE / ($NSEQ - $i + 1)))
10046                 echo directIO rdwr round $i of $NSEQ
10047                 $DIRECTIO rdwr $DIR/$tfile 0 $FSIZE 1048576||error "rdwr failed"
10048         done
10049
10050         cleanup_test_78
10051 }
10052 run_test 78 "handle large O_DIRECT writes correctly ============"
10053
10054 test_79() { # bug 12743
10055         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10056
10057         wait_delete_completed
10058
10059         BKTOTAL=$(calc_osc_kbytes kbytestotal)
10060         BKFREE=$(calc_osc_kbytes kbytesfree)
10061         BKAVAIL=$(calc_osc_kbytes kbytesavail)
10062
10063         STRING=`df -P $MOUNT | tail -n 1 | awk '{print $2","$3","$4}'`
10064         DFTOTAL=`echo $STRING | cut -d, -f1`
10065         DFUSED=`echo $STRING  | cut -d, -f2`
10066         DFAVAIL=`echo $STRING | cut -d, -f3`
10067         DFFREE=$(($DFTOTAL - $DFUSED))
10068
10069         ALLOWANCE=$((64 * $OSTCOUNT))
10070
10071         if [ $DFTOTAL -lt $(($BKTOTAL - $ALLOWANCE)) ] ||
10072            [ $DFTOTAL -gt $(($BKTOTAL + $ALLOWANCE)) ] ; then
10073                 error "df total($DFTOTAL) mismatch OST total($BKTOTAL)"
10074         fi
10075         if [ $DFFREE -lt $(($BKFREE - $ALLOWANCE)) ] ||
10076            [ $DFFREE -gt $(($BKFREE + $ALLOWANCE)) ] ; then
10077                 error "df free($DFFREE) mismatch OST free($BKFREE)"
10078         fi
10079         if [ $DFAVAIL -lt $(($BKAVAIL - $ALLOWANCE)) ] ||
10080            [ $DFAVAIL -gt $(($BKAVAIL + $ALLOWANCE)) ] ; then
10081                 error "df avail($DFAVAIL) mismatch OST avail($BKAVAIL)"
10082         fi
10083 }
10084 run_test 79 "df report consistency check ======================="
10085
10086 test_80() { # bug 10718
10087         remote_ost_nodsh && skip "remote OST with nodsh"
10088         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10089
10090         # relax strong synchronous semantics for slow backends like ZFS
10091         if [ "$ost1_FSTYPE" != "ldiskfs" ]; then
10092                 local soc="obdfilter.*.sync_lock_cancel"
10093                 local save=$(do_facet ost1 $LCTL get_param -n $soc | head -n1)
10094
10095                 # "sync_on_lock_cancel" was broken by v2_11_55_0-26-g7059644e9a
10096                 if [ -z "$save" ]; then
10097                         soc="obdfilter.*.sync_on_lock_cancel"
10098                         save=$(do_facet ost1 $LCTL get_param -n $soc | head -n1)
10099                 fi
10100
10101                 if [ "$save" != "never" ]; then
10102                         local hosts=$(comma_list $(osts_nodes))
10103
10104                         do_nodes $hosts $LCTL set_param $soc=never
10105                         stack_trap "do_nodes $hosts $LCTL set_param $soc=$save"
10106                 fi
10107         fi
10108
10109         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=1M
10110         sync; sleep 1; sync
10111         local before=$(date +%s)
10112         cancel_lru_locks osc
10113         local after=$(date +%s)
10114         local diff=$((after - before))
10115         [ $diff -le 1 ] || error "elapsed for 1M@1T = $diff"
10116
10117         rm -f $DIR/$tfile
10118 }
10119 run_test 80 "Page eviction is equally fast at high offsets too"
10120
10121 test_81a() { # LU-456
10122         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10123         remote_ost_nodsh && skip "remote OST with nodsh"
10124
10125         # define OBD_FAIL_OST_MAPBLK_ENOSPC    0x228
10126         # MUST OR with the OBD_FAIL_ONCE (0x80000000)
10127         do_facet ost1 lctl set_param fail_loc=0x80000228
10128
10129         # write should trigger a retry and success
10130         $LFS setstripe -i 0 -c 1 $DIR/$tfile
10131         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
10132         RC=$?
10133         if [ $RC -ne 0 ] ; then
10134                 error "write should success, but failed for $RC"
10135         fi
10136 }
10137 run_test 81a "OST should retry write when get -ENOSPC ==============="
10138
10139 test_81b() { # LU-456
10140         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10141         remote_ost_nodsh && skip "remote OST with nodsh"
10142
10143         # define OBD_FAIL_OST_MAPBLK_ENOSPC    0x228
10144         # Don't OR with the OBD_FAIL_ONCE (0x80000000)
10145         do_facet ost1 lctl set_param fail_loc=0x228
10146
10147         # write should retry several times and return -ENOSPC finally
10148         $LFS setstripe -i 0 -c 1 $DIR/$tfile
10149         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
10150         RC=$?
10151         ENOSPC=28
10152         if [ $RC -ne $ENOSPC ] ; then
10153                 error "dd should fail for -ENOSPC, but succeed."
10154         fi
10155 }
10156 run_test 81b "OST should return -ENOSPC when retry still fails ======="
10157
10158 test_99() {
10159         [ -z "$(which cvs 2>/dev/null)" ] && skip_env "could not find cvs"
10160
10161         test_mkdir $DIR/$tdir.cvsroot
10162         chown $RUNAS_ID $DIR/$tdir.cvsroot
10163
10164         cd $TMP
10165         $RUNAS cvs -d $DIR/$tdir.cvsroot init || error "cvs init failed"
10166
10167         cd /etc/init.d
10168         # some versions of cvs import exit(1) when asked to import links or
10169         # files they can't read.  ignore those files.
10170         local toignore=$(find . -type l -printf '-I %f\n' -o \
10171                          ! -perm /4 -printf '-I %f\n')
10172         $RUNAS cvs -d $DIR/$tdir.cvsroot import -m "nomesg" $toignore \
10173                 $tdir.reposname vtag rtag
10174
10175         cd $DIR
10176         test_mkdir $DIR/$tdir.reposname
10177         chown $RUNAS_ID $DIR/$tdir.reposname
10178         $RUNAS cvs -d $DIR/$tdir.cvsroot co $tdir.reposname
10179
10180         cd $DIR/$tdir.reposname
10181         $RUNAS touch foo99
10182         $RUNAS cvs add -m 'addmsg' foo99
10183         $RUNAS cvs update
10184         $RUNAS cvs commit -m 'nomsg' foo99
10185         rm -fr $DIR/$tdir.cvsroot
10186 }
10187 run_test 99 "cvs strange file/directory operations"
10188
10189 test_100() {
10190         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10191         [[ "$NETTYPE" =~ tcp ]] ||
10192                 skip_env "TCP secure port test, not useful for NETTYPE=$NETTYPE"
10193         remote_ost_nodsh && skip "remote OST with nodsh"
10194         remote_mds_nodsh && skip "remote MDS with nodsh"
10195         remote_servers ||
10196                 skip "useless for local single node setup"
10197
10198         netstat -tna | ( rc=1; while read PROT SND RCV LOCAL REMOTE STAT; do
10199                 [ "$PROT" != "tcp" ] && continue
10200                 RPORT=$(echo $REMOTE | cut -d: -f2)
10201                 [ "$RPORT" != "$ACCEPTOR_PORT" ] && continue
10202
10203                 rc=0
10204                 LPORT=`echo $LOCAL | cut -d: -f2`
10205                 if [ $LPORT -ge 1024 ]; then
10206                         echo "bad: $PROT $SND $RCV $LOCAL $REMOTE $STAT"
10207                         netstat -tna
10208                         error_exit "local: $LPORT > 1024, remote: $RPORT"
10209                 fi
10210         done
10211         [ "$rc" = 0 ] || error_exit "privileged port not found" )
10212 }
10213 run_test 100 "check local port using privileged port ==========="
10214
10215 function get_named_value()
10216 {
10217     local tag=$1
10218
10219     grep -w "$tag" | sed "s/^$tag  *\([0-9]*\)  *.*/\1/"
10220 }
10221
10222 export CACHE_MAX=$($LCTL get_param -n llite.*.max_cached_mb |
10223                    awk '/^max_cached_mb/ { print $2 }')
10224
10225 cleanup_101a() {
10226         $LCTL set_param -n llite.*.max_cached_mb $CACHE_MAX
10227         trap 0
10228 }
10229
10230 test_101a() {
10231         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10232
10233         local s
10234         local discard
10235         local nreads=10000
10236         local cache_limit=32
10237
10238         $LCTL set_param -n osc.*-osc*.rpc_stats=0
10239         trap cleanup_101a EXIT
10240         $LCTL set_param -n llite.*.read_ahead_stats=0
10241         $LCTL set_param -n llite.*.max_cached_mb=$cache_limit
10242
10243         #
10244         # randomly read 10000 of 64K chunks from file 3x 32MB in size
10245         #
10246         echo "nreads: $nreads file size: $((cache_limit * 3))MB"
10247         $READS -f $DIR/$tfile -s$((cache_limit * 3192 * 1024)) -b65536 -C -n$nreads -t 180
10248
10249         discard=0
10250         for s in $($LCTL get_param -n llite.*.read_ahead_stats |
10251                    get_named_value 'read.but.discarded'); do
10252                         discard=$(($discard + $s))
10253         done
10254         cleanup_101a
10255
10256         $LCTL get_param osc.*-osc*.rpc_stats
10257         $LCTL get_param llite.*.read_ahead_stats
10258
10259         # Discard is generally zero, but sometimes a few random reads line up
10260         # and trigger larger readahead, which is wasted & leads to discards.
10261         if [[ $(($discard)) -gt $nreads ]]; then
10262                 error "too many ($discard) discarded pages"
10263         fi
10264         rm -f $DIR/$tfile || true
10265 }
10266 run_test 101a "check read-ahead for random reads"
10267
10268 setup_test101bc() {
10269         test_mkdir $DIR/$tdir
10270         local ssize=$1
10271         local FILE_LENGTH=$2
10272         STRIPE_OFFSET=0
10273
10274         local FILE_SIZE_MB=$((FILE_LENGTH / ssize))
10275
10276         local list=$(comma_list $(osts_nodes))
10277         set_osd_param $list '' read_cache_enable 0
10278         set_osd_param $list '' writethrough_cache_enable 0
10279
10280         trap cleanup_test101bc EXIT
10281         # prepare the read-ahead file
10282         $LFS setstripe -S $ssize -i $STRIPE_OFFSET -c $OSTCOUNT $DIR/$tfile
10283
10284         dd if=/dev/zero of=$DIR/$tfile bs=$ssize \
10285                                 count=$FILE_SIZE_MB 2> /dev/null
10286
10287 }
10288
10289 cleanup_test101bc() {
10290         trap 0
10291         rm -rf $DIR/$tdir
10292         rm -f $DIR/$tfile
10293
10294         local list=$(comma_list $(osts_nodes))
10295         set_osd_param $list '' read_cache_enable 1
10296         set_osd_param $list '' writethrough_cache_enable 1
10297 }
10298
10299 calc_total() {
10300         awk 'BEGIN{total=0}; {total+=$1}; END{print total}'
10301 }
10302
10303 ra_check_101() {
10304         local READ_SIZE=$1
10305         local STRIPE_SIZE=$2
10306         local FILE_LENGTH=$3
10307         local RA_INC=1048576
10308         local STRIDE_LENGTH=$((STRIPE_SIZE/READ_SIZE))
10309         local discard_limit=$((((STRIDE_LENGTH - 1)*3/(STRIDE_LENGTH*OSTCOUNT))* \
10310                              (STRIDE_LENGTH*OSTCOUNT - STRIDE_LENGTH)))
10311         DISCARD=$($LCTL get_param -n llite.*.read_ahead_stats |
10312                   get_named_value 'read.but.discarded' | calc_total)
10313         if [[ $DISCARD -gt $discard_limit ]]; then
10314                 $LCTL get_param llite.*.read_ahead_stats
10315                 error "Too many ($DISCARD) discarded pages with size (${READ_SIZE})"
10316         else
10317                 echo "Read-ahead success for size ${READ_SIZE}"
10318         fi
10319 }
10320
10321 test_101b() {
10322         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10323         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
10324
10325         local STRIPE_SIZE=1048576
10326         local STRIDE_SIZE=$((STRIPE_SIZE*OSTCOUNT))
10327
10328         if [ $SLOW == "yes" ]; then
10329                 local FILE_LENGTH=$((STRIDE_SIZE * 64))
10330         else
10331                 local FILE_LENGTH=$((STRIDE_SIZE * 8))
10332         fi
10333
10334         local ITERATION=$((FILE_LENGTH / STRIDE_SIZE))
10335
10336         # prepare the read-ahead file
10337         setup_test101bc $STRIPE_SIZE $FILE_LENGTH
10338         cancel_lru_locks osc
10339         for BIDX in 2 4 8 16 32 64 128 256
10340         do
10341                 local BSIZE=$((BIDX*4096))
10342                 local READ_COUNT=$((STRIPE_SIZE/BSIZE))
10343                 local STRIDE_LENGTH=$((STRIDE_SIZE/BSIZE))
10344                 local OFFSET=$((STRIPE_SIZE/BSIZE*(OSTCOUNT - 1)))
10345                 $LCTL set_param -n llite.*.read_ahead_stats=0
10346                 $READS -f $DIR/$tfile  -l $STRIDE_LENGTH -o $OFFSET \
10347                               -s $FILE_LENGTH -b $STRIPE_SIZE -a $READ_COUNT -n $ITERATION
10348                 cancel_lru_locks osc
10349                 ra_check_101 $BSIZE $STRIPE_SIZE $FILE_LENGTH
10350         done
10351         cleanup_test101bc
10352         true
10353 }
10354 run_test 101b "check stride-io mode read-ahead ================="
10355
10356 test_101c() {
10357         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10358
10359         local STRIPE_SIZE=1048576
10360         local FILE_LENGTH=$((STRIPE_SIZE*100))
10361         local nreads=10000
10362         local rsize=65536
10363         local osc_rpc_stats
10364
10365         setup_test101bc $STRIPE_SIZE $FILE_LENGTH
10366
10367         cancel_lru_locks osc
10368         $LCTL set_param osc.*.rpc_stats=0
10369         $READS -f $DIR/$tfile -s$FILE_LENGTH -b$rsize -n$nreads -t 180
10370         $LCTL get_param osc.*.rpc_stats
10371         for osc_rpc_stats in $($LCTL get_param -N osc.*.rpc_stats); do
10372                 local stats=$($LCTL get_param -n $osc_rpc_stats)
10373                 local lines=$(echo "$stats" | awk 'END {print NR;}')
10374                 local size
10375
10376                 if [ $lines -le 20 ]; then
10377                         echo "continue debug"
10378                         continue
10379                 fi
10380                 for size in 1 2 4 8; do
10381                         local rpc=$(echo "$stats" |
10382                                     awk '($1 == "'$size':") {print $2; exit; }')
10383                         [ $rpc != 0 ] && ((size * PAGE_SIZE < rsize)) &&
10384                                 error "Small $((size*PAGE_SIZE)) read IO $rpc!"
10385                 done
10386                 echo "$osc_rpc_stats check passed!"
10387         done
10388         cleanup_test101bc
10389         true
10390 }
10391 run_test 101c "check stripe_size aligned read-ahead"
10392
10393 test_101d() {
10394         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10395
10396         local file=$DIR/$tfile
10397         local sz_MB=${FILESIZE_101d:-80}
10398         local ra_MB=${READAHEAD_MB:-40}
10399
10400         local free_MB=$(($(df -P $DIR | tail -n 1 | awk '{ print $4 }') / 1024))
10401         [ $free_MB -lt $sz_MB ] &&
10402                 skip "Need free space ${sz_MB}M, have ${free_MB}M"
10403
10404         echo "Create test file $file size ${sz_MB}M, ${free_MB}M free"
10405         $LFS setstripe -c -1 $file || error "setstripe failed"
10406
10407         dd if=/dev/zero of=$file bs=1M count=$sz_MB || error "dd failed"
10408         echo Cancel LRU locks on lustre client to flush the client cache
10409         cancel_lru_locks osc
10410
10411         echo Disable read-ahead
10412         local old_RA=$($LCTL get_param -n llite.*.max_read_ahead_mb | head -n 1)
10413         $LCTL set_param -n llite.*.max_read_ahead_mb=0
10414         stack_trap "$LCTL set_param -n llite.*.max_read_ahead_mb=$old_RA" EXIT
10415         $LCTL get_param -n llite.*.max_read_ahead_mb
10416
10417         echo "Reading the test file $file with read-ahead disabled"
10418         local sz_KB=$((sz_MB * 1024 / 4))
10419         # 10485760 bytes transferred in 0.000938 secs (11179579337 bytes/sec)
10420         # 104857600 bytes (105 MB) copied, 0.00876352 s, 12.0 GB/s
10421         local raOFF=$(LANG=C dd if=$file of=/dev/null bs=4k count=$sz_KB |&
10422                       sed -e '/records/d' -e 's/.* \([0-9]*\.[0-9]*\) *s.*/\1/')
10423
10424         echo "Cancel LRU locks on lustre client to flush the client cache"
10425         cancel_lru_locks osc
10426         echo Enable read-ahead with ${ra_MB}MB
10427         $LCTL set_param -n llite.*.max_read_ahead_mb=$ra_MB
10428
10429         echo "Reading the test file $file with read-ahead enabled"
10430         local raON=$(LANG=C dd if=$file of=/dev/null bs=4k count=$sz_KB |&
10431                      sed -e '/records/d' -e 's/.* \([0-9]*\.[0-9]*\) *s.*/\1/')
10432
10433         echo "read-ahead disabled time read $raOFF"
10434         echo "read-ahead enabled time read $raON"
10435
10436         rm -f $file
10437         wait_delete_completed
10438
10439         # use awk for this check instead of bash because it handles decimals
10440         awk "{ exit !($raOFF < 1.0 || $raOFF > $raON) }" <<<"ignore_me" ||
10441                 error "readahead ${raON}s > no-readahead ${raOFF}s ${sz_MB}M"
10442 }
10443 run_test 101d "file read with and without read-ahead enabled"
10444
10445 test_101e() {
10446         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10447
10448         local file=$DIR/$tfile
10449         local size_KB=500  #KB
10450         local count=100
10451         local bsize=1024
10452
10453         local free_KB=$(df -P $DIR | tail -n 1 | awk '{ print $4 }')
10454         local need_KB=$((count * size_KB))
10455         [[ $free_KB -le $need_KB ]] &&
10456                 skip_env "Need free space $need_KB, have $free_KB"
10457
10458         echo "Creating $count ${size_KB}K test files"
10459         for ((i = 0; i < $count; i++)); do
10460                 dd if=/dev/zero of=$file.$i bs=$bsize count=$size_KB 2>/dev/null
10461         done
10462
10463         echo "Cancel LRU locks on lustre client to flush the client cache"
10464         cancel_lru_locks $OSC
10465
10466         echo "Reset readahead stats"
10467         $LCTL set_param -n llite.*.read_ahead_stats=0
10468
10469         for ((i = 0; i < $count; i++)); do
10470                 dd if=$file.$i of=/dev/null bs=$bsize count=$size_KB 2>/dev/null
10471         done
10472
10473         $LCTL get_param llite.*.max_cached_mb
10474         $LCTL get_param llite.*.read_ahead_stats
10475         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
10476                      get_named_value 'misses' | calc_total)
10477
10478         for ((i = 0; i < $count; i++)); do
10479                 rm -rf $file.$i 2>/dev/null
10480         done
10481
10482         #10000 means 20% reads are missing in readahead
10483         [[ $miss -lt 10000 ]] ||  error "misses too much for small reads"
10484 }
10485 run_test 101e "check read-ahead for small read(1k) for small files(500k)"
10486
10487 test_101f() {
10488         which iozone || skip_env "no iozone installed"
10489
10490         local old_debug=$($LCTL get_param debug)
10491         old_debug=${old_debug#*=}
10492         $LCTL set_param debug="reada mmap"
10493
10494         # create a test file
10495         iozone -i 0 -+n -r 1m -s 128m -w -f $DIR/$tfile > /dev/null 2>&1
10496
10497         echo Cancel LRU locks on lustre client to flush the client cache
10498         cancel_lru_locks osc
10499
10500         echo Reset readahead stats
10501         $LCTL set_param -n llite.*.read_ahead_stats=0
10502
10503         echo mmap read the file with small block size
10504         iozone -i 1 -u 1 -l 1 -+n -r 32k -s 128m -B -f $DIR/$tfile \
10505                 > /dev/null 2>&1
10506
10507         echo checking missing pages
10508         $LCTL get_param llite.*.read_ahead_stats
10509         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
10510                         get_named_value 'misses' | calc_total)
10511
10512         $LCTL set_param debug="$old_debug"
10513         [ $miss -lt 3 ] || error "misses too much pages ('$miss')!"
10514         rm -f $DIR/$tfile
10515 }
10516 run_test 101f "check mmap read performance"
10517
10518 test_101g_brw_size_test() {
10519         local mb=$1
10520         local pages=$((mb * 1048576 / PAGE_SIZE))
10521         local file=$DIR/$tfile
10522
10523         $LCTL set_param osc.*.max_pages_per_rpc=${mb}M ||
10524                 { error "unable to set max_pages_per_rpc=${mb}M"; return 1; }
10525         for mp in $($LCTL get_param -n osc.*.max_pages_per_rpc); do
10526                 [ $mp -ne $pages ] && error "max_pages_per_rpc $mp != $pages" &&
10527                         return 2
10528         done
10529
10530         stack_trap "rm -f $file" EXIT
10531         $LCTL set_param -n osc.*.rpc_stats=0
10532
10533         # 10 RPCs should be enough for the test
10534         local count=10
10535         dd if=/dev/zero of=$file bs=${mb}M count=$count ||
10536                 { error "dd write ${mb} MB blocks failed"; return 3; }
10537         cancel_lru_locks osc
10538         dd of=/dev/null if=$file bs=${mb}M count=$count ||
10539                 { error "dd write ${mb} MB blocks failed"; return 4; }
10540
10541         # calculate number of full-sized read and write RPCs
10542         rpcs=($($LCTL get_param -n 'osc.*.rpc_stats' |
10543                 sed -n '/pages per rpc/,/^$/p' |
10544                 awk '/'$pages':/ { reads += $2; writes += $6 }; \
10545                 END { print reads,writes }'))
10546         # allow one extra full-sized read RPC for async readahead
10547         [[ ${rpcs[0]} == $count || ${rpcs[0]} == $((count + 1)) ]] ||
10548                 { error "${rpcs[0]} != $count read RPCs"; return 5; }
10549         [[ ${rpcs[1]} == $count ]] ||
10550                 { error "${rpcs[1]} != $count write RPCs"; return 6; }
10551 }
10552
10553 test_101g() {
10554         remote_ost_nodsh && skip "remote OST with nodsh"
10555
10556         local rpcs
10557         local osts=$(get_facets OST)
10558         local list=$(comma_list $(osts_nodes))
10559         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
10560         local brw_size="obdfilter.*.brw_size"
10561
10562         $LFS setstripe -i 0 -c 1 $DIR/$tfile
10563
10564         local orig_mb=$(do_facet ost1 $LCTL get_param -n $brw_size | head -n 1)
10565
10566         if { [ $OST1_VERSION -ge $(version_code 2.8.52) ] ||
10567                 { [ $OST1_VERSION -ge $(version_code 2.7.17) ] &&
10568                   [ $OST1_VERSION -lt $(version_code 2.7.50) ]; }; } &&
10569            { [ $CLIENT_VERSION -ge $(version_code 2.8.52) ] ||
10570                 { [ $CLIENT_VERSION -ge $(version_code 2.7.17) ] &&
10571                   [ $CLIENT_VERSION -lt $(version_code 2.7.50) ]; }; }; then
10572
10573                 [ $OST1_VERSION -ge $(version_code 2.9.52) ] &&
10574                         suffix="M"
10575
10576                 if [[ $orig_mb -lt 16 ]]; then
10577                         save_lustre_params $osts "$brw_size" > $p
10578                         do_nodes $list $LCTL set_param -n $brw_size=16$suffix ||
10579                                 error "set 16MB RPC size failed"
10580
10581                         echo "remount client to enable new RPC size"
10582                         remount_client $MOUNT || error "remount_client failed"
10583                 fi
10584
10585                 test_101g_brw_size_test 16 || error "16MB RPC test failed"
10586                 # should be able to set brw_size=12, but no rpc_stats for that
10587                 test_101g_brw_size_test 8 || error "8MB RPC test failed"
10588         fi
10589
10590         test_101g_brw_size_test 4 || error "4MB RPC test failed"
10591
10592         if [[ $orig_mb -lt 16 ]]; then
10593                 restore_lustre_params < $p
10594                 remount_client $MOUNT || error "remount_client restore failed"
10595         fi
10596
10597         rm -f $p $DIR/$tfile
10598 }
10599 run_test 101g "Big bulk(4/16 MiB) readahead"
10600
10601 test_101h() {
10602         $LFS setstripe -i 0 -c 1 $DIR/$tfile
10603
10604         dd if=/dev/zero of=$DIR/$tfile bs=1M count=70 ||
10605                 error "dd 70M file failed"
10606         echo Cancel LRU locks on lustre client to flush the client cache
10607         cancel_lru_locks osc
10608
10609         echo "Reset readahead stats"
10610         $LCTL set_param -n llite.*.read_ahead_stats 0
10611
10612         echo "Read 10M of data but cross 64M bundary"
10613         dd if=$DIR/$tfile of=/dev/null bs=10M skip=6 count=1
10614         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
10615                      get_named_value 'misses' | calc_total)
10616         [ $miss -eq 1 ] || error "expected miss 1 but got $miss"
10617         rm -f $p $DIR/$tfile
10618 }
10619 run_test 101h "Readahead should cover current read window"
10620
10621 test_101i() {
10622         dd if=/dev/zero of=$DIR/$tfile bs=1M count=10 ||
10623                 error "dd 10M file failed"
10624
10625         local max_per_file_mb=$($LCTL get_param -n \
10626                 llite.*.max_read_ahead_per_file_mb 2>/dev/null)
10627         cancel_lru_locks osc
10628         stack_trap "$LCTL set_param llite.*.max_read_ahead_per_file_mb=$max_per_file_mb"
10629         $LCTL set_param llite.*.max_read_ahead_per_file_mb=1 ||
10630                 error "set max_read_ahead_per_file_mb to 1 failed"
10631
10632         echo "Reset readahead stats"
10633         $LCTL set_param llite.*.read_ahead_stats=0
10634
10635         dd if=$DIR/$tfile of=/dev/null bs=2M
10636
10637         $LCTL get_param llite.*.read_ahead_stats
10638         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
10639                      awk '/misses/ { print $2 }')
10640         [ $miss -eq 5 ] || error "expected misses 5 but got $miss"
10641         rm -f $DIR/$tfile
10642 }
10643 run_test 101i "allow current readahead to exceed reservation"
10644
10645 test_101j() {
10646         $LFS setstripe -i 0 -c 1 $DIR/$tfile ||
10647                 error "setstripe $DIR/$tfile failed"
10648         local file_size=$((1048576 * 16))
10649         local old_ra=$($LCTL get_param -n llite.*.max_read_ahead_mb | head -n 1)
10650         stack_trap "$LCTL set_param -n llite.*.max_read_ahead_mb $old_ra" EXIT
10651
10652         echo Disable read-ahead
10653         $LCTL set_param -n llite.*.max_read_ahead_mb=0
10654
10655         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$(($file_size / 1048576))
10656         for blk in $PAGE_SIZE 1048576 $file_size; do
10657                 cancel_lru_locks osc
10658                 echo "Reset readahead stats"
10659                 $LCTL set_param -n llite.*.read_ahead_stats=0
10660                 local count=$(($file_size / $blk))
10661                 dd if=$DIR/$tfile bs=$blk count=$count of=/dev/null
10662                 local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
10663                              get_named_value 'failed.to.fast.read' | calc_total)
10664                 $LCTL get_param -n llite.*.read_ahead_stats
10665                 [ $miss -eq $count ] || error "expected $count got $miss"
10666         done
10667
10668         rm -f $p $DIR/$tfile
10669 }
10670 run_test 101j "A complete read block should be submitted when no RA"
10671
10672 setup_test102() {
10673         test_mkdir $DIR/$tdir
10674         chown $RUNAS_ID $DIR/$tdir
10675         STRIPE_SIZE=65536
10676         STRIPE_OFFSET=1
10677         STRIPE_COUNT=$OSTCOUNT
10678         [[ $OSTCOUNT -gt 4 ]] && STRIPE_COUNT=4
10679
10680         trap cleanup_test102 EXIT
10681         cd $DIR
10682         $1 $LFS setstripe -S $STRIPE_SIZE -i $STRIPE_OFFSET -c $STRIPE_COUNT $tdir
10683         cd $DIR/$tdir
10684         for num in 1 2 3 4; do
10685                 for count in $(seq 1 $STRIPE_COUNT); do
10686                         for idx in $(seq 0 $[$STRIPE_COUNT - 1]); do
10687                                 local size=`expr $STRIPE_SIZE \* $num`
10688                                 local file=file"$num-$idx-$count"
10689                                 $1 $LFS setstripe -S $size -i $idx -c $count $file
10690                         done
10691                 done
10692         done
10693
10694         cd $DIR
10695         $1 tar cf $TMP/f102.tar $tdir --xattrs
10696 }
10697
10698 cleanup_test102() {
10699         trap 0
10700         rm -f $TMP/f102.tar
10701         rm -rf $DIR/d0.sanity/d102
10702 }
10703
10704 test_102a() {
10705         [ "$UID" != 0 ] && skip "must run as root"
10706         [ -z "$(lctl get_param -n mdc.*-mdc-*.connect_flags | grep xattr)" ] &&
10707                 skip_env "must have user_xattr"
10708
10709         [ -z "$(which setfattr 2>/dev/null)" ] &&
10710                 skip_env "could not find setfattr"
10711
10712         local testfile=$DIR/$tfile
10713
10714         touch $testfile
10715         echo "set/get xattr..."
10716         setfattr -n trusted.name1 -v value1 $testfile ||
10717                 error "setfattr -n trusted.name1=value1 $testfile failed"
10718         getfattr -n trusted.name1 $testfile 2> /dev/null |
10719           grep "trusted.name1=.value1" ||
10720                 error "$testfile missing trusted.name1=value1"
10721
10722         setfattr -n user.author1 -v author1 $testfile ||
10723                 error "setfattr -n user.author1=author1 $testfile failed"
10724         getfattr -n user.author1 $testfile 2> /dev/null |
10725           grep "user.author1=.author1" ||
10726                 error "$testfile missing trusted.author1=author1"
10727
10728         echo "listxattr..."
10729         setfattr -n trusted.name2 -v value2 $testfile ||
10730                 error "$testfile unable to set trusted.name2"
10731         setfattr -n trusted.name3 -v value3 $testfile ||
10732                 error "$testfile unable to set trusted.name3"
10733         [ $(getfattr -d -m "^trusted" $testfile 2> /dev/null |
10734             grep "trusted.name" | wc -l) -eq 3 ] ||
10735                 error "$testfile missing 3 trusted.name xattrs"
10736
10737         setfattr -n user.author2 -v author2 $testfile ||
10738                 error "$testfile unable to set user.author2"
10739         setfattr -n user.author3 -v author3 $testfile ||
10740                 error "$testfile unable to set user.author3"
10741         [ $(getfattr -d -m "^user" $testfile 2> /dev/null |
10742             grep "user.author" | wc -l) -eq 3 ] ||
10743                 error "$testfile missing 3 user.author xattrs"
10744
10745         echo "remove xattr..."
10746         setfattr -x trusted.name1 $testfile ||
10747                 error "$testfile error deleting trusted.name1"
10748         getfattr -d -m trusted $testfile 2> /dev/null | grep "trusted.name1" &&
10749                 error "$testfile did not delete trusted.name1 xattr"
10750
10751         setfattr -x user.author1 $testfile ||
10752                 error "$testfile error deleting user.author1"
10753         echo "set lustre special xattr ..."
10754         $LFS setstripe -c1 $testfile
10755         local lovea=$(getfattr -n "trusted.lov" -e hex $testfile |
10756                 awk -F "=" '/trusted.lov/ { print $2 }' )
10757         setfattr -n "trusted.lov" -v $lovea $testfile ||
10758                 error "$testfile doesn't ignore setting trusted.lov again"
10759         setfattr -n "trusted.lov" -v "invalid_value" $testfile &&
10760                 error "$testfile allow setting invalid trusted.lov"
10761         rm -f $testfile
10762 }
10763 run_test 102a "user xattr test =================================="
10764
10765 check_102b_layout() {
10766         local layout="$*"
10767         local testfile=$DIR/$tfile
10768
10769         echo "test layout '$layout'"
10770         $LFS setstripe $layout $testfile || error "setstripe failed"
10771         $LFS getstripe -y $testfile
10772
10773         echo "get/set/list trusted.lov xattr ..." # b=10930
10774         local value=$(getfattr -n trusted.lov -e hex $testfile | grep trusted)
10775         [[ "$value" =~ "trusted.lov" ]] ||
10776                 error "can't get trusted.lov from $testfile"
10777         local stripe_count_orig=$($LFS getstripe -c $testfile) ||
10778                 error "getstripe failed"
10779
10780         $MCREATE $testfile.2 || error "mcreate $testfile.2 failed"
10781
10782         value=$(cut -d= -f2 <<<$value)
10783         # LU-13168: truncated xattr should fail if short lov_user_md header
10784         [ $CLIENT_VERSION -lt $(version_code 2.13.53) ] &&
10785                 lens="${#value}" || lens="$(seq 4 2 ${#value})"
10786         for len in $lens; do
10787                 echo "setfattr $len $testfile.2"
10788                 setfattr -n trusted.lov -v ${value:0:$len} $testfile.2 &&
10789                         [ $len -lt 66 ] && error "short xattr len=$len worked"
10790         done
10791         local stripe_size=$($LFS getstripe -S $testfile.2)
10792         local stripe_count=$($LFS getstripe -c $testfile.2)
10793         [[ $stripe_size -eq 65536 ]] ||
10794                 error "stripe size $stripe_size != 65536"
10795         [[ $stripe_count -eq $stripe_count_orig ]] ||
10796                 error "stripe count $stripe_count != $stripe_count_orig"
10797         rm $testfile $testfile.2
10798 }
10799
10800 test_102b() {
10801         [ -z "$(which setfattr 2>/dev/null)" ] &&
10802                 skip_env "could not find setfattr"
10803         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
10804
10805         # check plain layout
10806         check_102b_layout -S 65536 -i 1 -c $OSTCOUNT
10807
10808         # and also check composite layout
10809         check_102b_layout -E 1M -S 65536 -i 1 -c $OSTCOUNT -Eeof -S4M
10810
10811 }
10812 run_test 102b "getfattr/setfattr for trusted.lov EAs"
10813
10814 test_102c() {
10815         [ -z "$(which setfattr 2>/dev/null)" ] &&
10816                 skip_env "could not find setfattr"
10817         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
10818
10819         # b10930: get/set/list lustre.lov xattr
10820         echo "get/set/list lustre.lov xattr ..."
10821         test_mkdir $DIR/$tdir
10822         chown $RUNAS_ID $DIR/$tdir
10823         local testfile=$DIR/$tdir/$tfile
10824         $RUNAS $LFS setstripe -S 65536 -i 1 -c $OSTCOUNT $testfile ||
10825                 error "setstripe failed"
10826         local STRIPECOUNT=$($RUNAS $LFS getstripe -c $testfile) ||
10827                 error "getstripe failed"
10828         $RUNAS getfattr -d -m "^lustre" $testfile 2> /dev/null | \
10829         grep "lustre.lov" || error "can't get lustre.lov from $testfile"
10830
10831         local testfile2=${testfile}2
10832         local value=`getfattr -n lustre.lov $testfile 2> /dev/null | \
10833                      grep "lustre.lov" |sed -e 's/[^=]\+=//'  `
10834
10835         $RUNAS $MCREATE $testfile2
10836         $RUNAS setfattr -n lustre.lov -v $value $testfile2
10837         local stripe_size=$($RUNAS $LFS getstripe -S $testfile2)
10838         local stripe_count=$($RUNAS $LFS getstripe -c $testfile2)
10839         [ $stripe_size -eq 65536 ] || error "stripe size $stripe_size != 65536"
10840         [ $stripe_count -eq $STRIPECOUNT ] ||
10841                 error "stripe count $stripe_count != $STRIPECOUNT"
10842 }
10843 run_test 102c "non-root getfattr/setfattr for lustre.lov EAs ==========="
10844
10845 compare_stripe_info1() {
10846         local stripe_index_all_zero=true
10847
10848         for num in 1 2 3 4; do
10849                 for count in $(seq 1 $STRIPE_COUNT); do
10850                         for offset in $(seq 0 $[$STRIPE_COUNT - 1]); do
10851                                 local size=$((STRIPE_SIZE * num))
10852                                 local file=file"$num-$offset-$count"
10853                                 stripe_size=$($LFS getstripe -S $PWD/$file)
10854                                 [[ $stripe_size -ne $size ]] &&
10855                                     error "$file: size $stripe_size != $size"
10856                                 stripe_count=$($LFS getstripe -c $PWD/$file)
10857                                 # allow fewer stripes to be created, ORI-601
10858                                 [[ $stripe_count -lt $(((3 * count + 3) / 4)) ]] &&
10859                                     error "$file: count $stripe_count != $count"
10860                                 stripe_index=$($LFS getstripe -i $PWD/$file)
10861                                 [[ $stripe_index -ne 0 ]] &&
10862                                         stripe_index_all_zero=false
10863                         done
10864                 done
10865         done
10866         $stripe_index_all_zero &&
10867                 error "all files are being extracted starting from OST index 0"
10868         return 0
10869 }
10870
10871 have_xattrs_include() {
10872         tar --help | grep -q xattrs-include &&
10873                 echo --xattrs-include="lustre.*"
10874 }
10875
10876 test_102d() {
10877         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10878         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
10879
10880         XINC=$(have_xattrs_include)
10881         setup_test102
10882         tar xf $TMP/f102.tar -C $DIR/$tdir --xattrs $XINC
10883         cd $DIR/$tdir/$tdir
10884         compare_stripe_info1
10885 }
10886 run_test 102d "tar restore stripe info from tarfile,not keep osts"
10887
10888 test_102f() {
10889         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10890         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
10891
10892         XINC=$(have_xattrs_include)
10893         setup_test102
10894         test_mkdir $DIR/$tdir.restore
10895         cd $DIR
10896         tar cf - --xattrs $tdir | tar xf - \
10897                 -C $DIR/$tdir.restore --xattrs $XINC
10898         cd $DIR/$tdir.restore/$tdir
10899         compare_stripe_info1
10900 }
10901 run_test 102f "tar copy files, not keep osts"
10902
10903 grow_xattr() {
10904         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep xattr)" ] &&
10905                 skip "must have user_xattr"
10906         [ -z "$(which setfattr 2>/dev/null)" ] &&
10907                 skip_env "could not find setfattr"
10908         [ -z "$(which getfattr 2>/dev/null)" ] &&
10909                 skip_env "could not find getfattr"
10910
10911         local xsize=${1:-1024}  # in bytes
10912         local file=$DIR/$tfile
10913         local value="$(generate_string $xsize)"
10914         local xbig=trusted.big
10915         local toobig=$2
10916
10917         touch $file
10918         log "save $xbig on $file"
10919         if [ -z "$toobig" ]
10920         then
10921                 setfattr -n $xbig -v $value $file ||
10922                         error "saving $xbig on $file failed"
10923         else
10924                 setfattr -n $xbig -v $value $file &&
10925                         error "saving $xbig on $file succeeded"
10926                 return 0
10927         fi
10928
10929         local orig=$(get_xattr_value $xbig $file)
10930         [[ "$orig" != "$value" ]] && error "$xbig different after saving $xbig"
10931
10932         local xsml=trusted.sml
10933         log "save $xsml on $file"
10934         setfattr -n $xsml -v val $file || error "saving $xsml on $file failed"
10935
10936         local new=$(get_xattr_value $xbig $file)
10937         [[ "$new" != "$orig" ]] && error "$xbig different after saving $xsml"
10938
10939         log "grow $xsml on $file"
10940         setfattr -n $xsml -v "$value" $file ||
10941                 error "growing $xsml on $file failed"
10942
10943         new=$(get_xattr_value $xbig $file)
10944         [[ "$new" != "$orig" ]] && error "$xbig different after growing $xsml"
10945         log "$xbig still valid after growing $xsml"
10946
10947         rm -f $file
10948 }
10949
10950 test_102h() { # bug 15777
10951         grow_xattr 1024
10952 }
10953 run_test 102h "grow xattr from inside inode to external block"
10954
10955 test_102ha() {
10956         large_xattr_enabled || skip_env "ea_inode feature disabled"
10957
10958         echo "setting xattr of max xattr size: $(max_xattr_size)"
10959         grow_xattr $(max_xattr_size)
10960
10961         echo "setting xattr of > max xattr size: $(max_xattr_size) + 10"
10962         echo "This should fail:"
10963         grow_xattr $(($(max_xattr_size) + 10)) 1
10964 }
10965 run_test 102ha "grow xattr from inside inode to external inode"
10966
10967 test_102i() { # bug 17038
10968         [ -z "$(which getfattr 2>/dev/null)" ] &&
10969                 skip "could not find getfattr"
10970
10971         touch $DIR/$tfile
10972         ln -s $DIR/$tfile $DIR/${tfile}link
10973         getfattr -n trusted.lov $DIR/$tfile ||
10974                 error "lgetxattr on $DIR/$tfile failed"
10975         getfattr -h -n trusted.lov $DIR/${tfile}link 2>&1 |
10976                 grep -i "no such attr" ||
10977                 error "error for lgetxattr on $DIR/${tfile}link is not ENODATA"
10978         rm -f $DIR/$tfile $DIR/${tfile}link
10979 }
10980 run_test 102i "lgetxattr test on symbolic link ============"
10981
10982 test_102j() {
10983         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10984         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
10985
10986         XINC=$(have_xattrs_include)
10987         setup_test102 "$RUNAS"
10988         chown $RUNAS_ID $DIR/$tdir
10989         $RUNAS tar xf $TMP/f102.tar -C $DIR/$tdir --xattrs $XINC
10990         cd $DIR/$tdir/$tdir
10991         compare_stripe_info1 "$RUNAS"
10992 }
10993 run_test 102j "non-root tar restore stripe info from tarfile, not keep osts ==="
10994
10995 test_102k() {
10996         [ -z "$(which setfattr 2>/dev/null)" ] &&
10997                 skip "could not find setfattr"
10998
10999         touch $DIR/$tfile
11000         # b22187 just check that does not crash for regular file.
11001         setfattr -n trusted.lov $DIR/$tfile
11002         # b22187 'setfattr -n trusted.lov' should remove LOV EA for directories
11003         local test_kdir=$DIR/$tdir
11004         test_mkdir $test_kdir
11005         local default_size=$($LFS getstripe -S $test_kdir)
11006         local default_count=$($LFS getstripe -c $test_kdir)
11007         local default_offset=$($LFS getstripe -i $test_kdir)
11008         $LFS setstripe -S 65536 -i 0 -c $OSTCOUNT $test_kdir ||
11009                 error 'dir setstripe failed'
11010         setfattr -n trusted.lov $test_kdir
11011         local stripe_size=$($LFS getstripe -S $test_kdir)
11012         local stripe_count=$($LFS getstripe -c $test_kdir)
11013         local stripe_offset=$($LFS getstripe -i $test_kdir)
11014         [ $stripe_size -eq $default_size ] ||
11015                 error "stripe size $stripe_size != $default_size"
11016         [ $stripe_count -eq $default_count ] ||
11017                 error "stripe count $stripe_count != $default_count"
11018         [ $stripe_offset -eq $default_offset ] ||
11019                 error "stripe offset $stripe_offset != $default_offset"
11020         rm -rf $DIR/$tfile $test_kdir
11021 }
11022 run_test 102k "setfattr without parameter of value shouldn't cause a crash"
11023
11024 test_102l() {
11025         [ -z "$(which getfattr 2>/dev/null)" ] &&
11026                 skip "could not find getfattr"
11027
11028         # LU-532 trusted. xattr is invisible to non-root
11029         local testfile=$DIR/$tfile
11030
11031         touch $testfile
11032
11033         echo "listxattr as user..."
11034         chown $RUNAS_ID $testfile
11035         $RUNAS getfattr -d -m '.*' $testfile 2>&1 |
11036             grep -q "trusted" &&
11037                 error "$testfile trusted xattrs are user visible"
11038
11039         return 0;
11040 }
11041 run_test 102l "listxattr size test =================================="
11042
11043 test_102m() { # LU-3403 llite: error of listxattr when buffer is small
11044         local path=$DIR/$tfile
11045         touch $path
11046
11047         listxattr_size_check $path || error "listattr_size_check $path failed"
11048 }
11049 run_test 102m "Ensure listxattr fails on small bufffer ========"
11050
11051 cleanup_test102
11052
11053 getxattr() { # getxattr path name
11054         # Return the base64 encoding of the value of xattr name on path.
11055         local path=$1
11056         local name=$2
11057
11058         # # getfattr --absolute-names --encoding=base64 --name=trusted.lov $path
11059         # file: $path
11060         # trusted.lov=0s0AvRCwEAAAAGAAAAAAAAAAAEAAACAAAAAAAQAAEAA...AAAAAAAAA=
11061         #
11062         # We print just 0s0AvRCwEAAAAGAAAAAAAAAAAEAAACAAAAAAAQAAEAA...AAAAAAAAA=
11063
11064         getfattr --absolute-names --encoding=base64 --name=$name $path |
11065                 awk -F= -v name=$name '$1 == name {
11066                         print substr($0, index($0, "=") + 1);
11067         }'
11068 }
11069
11070 test_102n() { # LU-4101 mdt: protect internal xattrs
11071         [ -z "$(which setfattr 2>/dev/null)" ] &&
11072                 skip "could not find setfattr"
11073         if [ $MDS1_VERSION -lt $(version_code 2.5.50) ]
11074         then
11075                 skip "MDT < 2.5.50 allows setxattr on internal trusted xattrs"
11076         fi
11077
11078         local file0=$DIR/$tfile.0
11079         local file1=$DIR/$tfile.1
11080         local xattr0=$TMP/$tfile.0
11081         local xattr1=$TMP/$tfile.1
11082         local namelist="lov lma lmv link fid version som hsm"
11083         local name
11084         local value
11085
11086         rm -rf $file0 $file1 $xattr0 $xattr1
11087         touch $file0 $file1
11088
11089         # Get 'before' xattrs of $file1.
11090         getfattr --absolute-names --dump --match=- $file1 > $xattr0
11091
11092         [ $MDS1_VERSION -lt $(version_code 2.8.53) ] &&
11093                 namelist+=" lfsck_namespace"
11094         for name in $namelist; do
11095                 # Try to copy xattr from $file0 to $file1.
11096                 value=$(getxattr $file0 trusted.$name 2> /dev/null)
11097
11098                 setfattr --name=trusted.$name --value="$value" $file1 ||
11099                         error "setxattr 'trusted.$name' failed"
11100
11101                 # Try to set a garbage xattr.
11102                 value=0sVGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIGl0c2VsZi4=
11103
11104                 if [[ x$name == "xlov" ]]; then
11105                         setfattr --name=trusted.lov --value="$value" $file1 &&
11106                         error "setxattr invalid 'trusted.lov' success"
11107                 else
11108                         setfattr --name=trusted.$name --value="$value" $file1 ||
11109                                 error "setxattr invalid 'trusted.$name' failed"
11110                 fi
11111
11112                 # Try to remove the xattr from $file1. We don't care if this
11113                 # appears to succeed or fail, we just don't want there to be
11114                 # any changes or crashes.
11115                 setfattr --remove=$trusted.$name $file1 2> /dev/null
11116         done
11117
11118         if [ $MDS1_VERSION -gt $(version_code 2.6.50) ]
11119         then
11120                 name="lfsck_ns"
11121                 # Try to copy xattr from $file0 to $file1.
11122                 value=$(getxattr $file0 trusted.$name 2> /dev/null)
11123
11124                 setfattr --name=trusted.$name --value="$value" $file1 ||
11125                         error "setxattr 'trusted.$name' failed"
11126
11127                 # Try to set a garbage xattr.
11128                 value=0sVGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIGl0c2VsZi4=
11129
11130                 setfattr --name=trusted.$name --value="$value" $file1 ||
11131                         error "setxattr 'trusted.$name' failed"
11132
11133                 # Try to remove the xattr from $file1. We don't care if this
11134                 # appears to succeed or fail, we just don't want there to be
11135                 # any changes or crashes.
11136                 setfattr --remove=$trusted.$name $file1 2> /dev/null
11137         fi
11138
11139         # Get 'after' xattrs of file1.
11140         getfattr --absolute-names --dump --match=- $file1 > $xattr1
11141
11142         if ! diff $xattr0 $xattr1; then
11143                 error "before and after xattrs of '$file1' differ"
11144         fi
11145
11146         rm -rf $file0 $file1 $xattr0 $xattr1
11147
11148         return 0
11149 }
11150 run_test 102n "silently ignore setxattr on internal trusted xattrs"
11151
11152 test_102p() { # LU-4703 setxattr did not check ownership
11153         [ $MDS1_VERSION -lt $(version_code 2.5.56) ] &&
11154                 skip "MDS needs to be at least 2.5.56"
11155
11156         local testfile=$DIR/$tfile
11157
11158         touch $testfile
11159
11160         echo "setfacl as user..."
11161         $RUNAS setfacl -m "u:$RUNAS_ID:rwx" $testfile
11162         [ $? -ne 0 ] || error "setfacl by $RUNAS_ID was allowed on $testfile"
11163
11164         echo "setfattr as user..."
11165         setfacl -m "u:$RUNAS_ID:---" $testfile
11166         $RUNAS setfattr -x system.posix_acl_access $testfile
11167         [ $? -ne 0 ] || error "setfattr by $RUNAS_ID was allowed on $testfile"
11168 }
11169 run_test 102p "check setxattr(2) correctly fails without permission"
11170
11171 test_102q() {
11172         [ $MDS1_VERSION -lt $(version_code 2.6.92) ] &&
11173                 skip "MDS needs to be at least 2.6.92"
11174
11175         orphan_linkea_check $DIR/$tfile || error "orphan_linkea_check"
11176 }
11177 run_test 102q "flistxattr should not return trusted.link EAs for orphans"
11178
11179 test_102r() {
11180         [ $MDS1_VERSION -lt $(version_code 2.6.93) ] &&
11181                 skip "MDS needs to be at least 2.6.93"
11182
11183         touch $DIR/$tfile || error "touch"
11184         setfattr -n user.$(basename $tfile) $DIR/$tfile || error "setfattr"
11185         getfattr -n user.$(basename $tfile) $DIR/$tfile || error "getfattr"
11186         rm $DIR/$tfile || error "rm"
11187
11188         #normal directory
11189         mkdir -p $DIR/$tdir || error "mkdir"
11190         setfattr -n user.$(basename $tdir) $DIR/$tdir || error "setfattr dir"
11191         getfattr -n user.$(basename $tdir) $DIR/$tdir || error "getfattr dir"
11192         setfattr -x user.$(basename $tdir) $DIR/$tdir ||
11193                 error "$testfile error deleting user.author1"
11194         getfattr -d -m user.$(basename $tdir) 2> /dev/null |
11195                 grep "user.$(basename $tdir)" &&
11196                 error "$tdir did not delete user.$(basename $tdir)"
11197         rmdir $DIR/$tdir || error "rmdir"
11198
11199         #striped directory
11200         test_mkdir $DIR/$tdir
11201         setfattr -n user.$(basename $tdir) $DIR/$tdir || error "setfattr dir"
11202         getfattr -n user.$(basename $tdir) $DIR/$tdir || error "getfattr dir"
11203         setfattr -x user.$(basename $tdir) $DIR/$tdir ||
11204                 error "$testfile error deleting user.author1"
11205         getfattr -d -m user.$(basename $tdir) 2> /dev/null |
11206                 grep "user.$(basename $tdir)" &&
11207                 error "$tdir did not delete user.$(basename $tdir)"
11208         rmdir $DIR/$tdir || error "rm striped dir"
11209 }
11210 run_test 102r "set EAs with empty values"
11211
11212 test_102s() {
11213         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
11214                 skip "MDS needs to be at least 2.11.52"
11215
11216         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
11217
11218         save_lustre_params client "llite.*.xattr_cache" > $save
11219
11220         for cache in 0 1; do
11221                 lctl set_param llite.*.xattr_cache=$cache
11222
11223                 rm -f $DIR/$tfile
11224                 touch $DIR/$tfile || error "touch"
11225                 for prefix in lustre security system trusted user; do
11226                         # Note getxattr() may fail with 'Operation not
11227                         # supported' or 'No such attribute' depending
11228                         # on prefix and cache.
11229                         getfattr -n $prefix.n102s $DIR/$tfile &&
11230                                 error "getxattr '$prefix.n102s' should fail (cache = $cache)"
11231                 done
11232         done
11233
11234         restore_lustre_params < $save
11235 }
11236 run_test 102s "getting nonexistent xattrs should fail"
11237
11238 test_102t() {
11239         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
11240                 skip "MDS needs to be at least 2.11.52"
11241
11242         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
11243
11244         save_lustre_params client "llite.*.xattr_cache" > $save
11245
11246         for cache in 0 1; do
11247                 lctl set_param llite.*.xattr_cache=$cache
11248
11249                 for buf_size in 0 256; do
11250                         rm -f $DIR/$tfile
11251                         touch $DIR/$tfile || error "touch"
11252                         setfattr -n user.multiop $DIR/$tfile
11253                         $MULTIOP $DIR/$tfile oa$buf_size ||
11254                                 error "cannot get zero length xattr value (buf_size = $buf_size)"
11255                 done
11256         done
11257
11258         restore_lustre_params < $save
11259 }
11260 run_test 102t "zero length xattr values handled correctly"
11261
11262 run_acl_subtest()
11263 {
11264     $LUSTRE/tests/acl/run $LUSTRE/tests/acl/$1.test
11265     return $?
11266 }
11267
11268 test_103a() {
11269         [ "$UID" != 0 ] && skip "must run as root"
11270         $GSS && skip_env "could not run under gss"
11271         [ -z "$(lctl get_param -n mdc.*-mdc-*.connect_flags | grep acl)" ] &&
11272                 skip_env "must have acl enabled"
11273         [ -z "$(which setfacl 2>/dev/null)" ] &&
11274                 skip_env "could not find setfacl"
11275         remote_mds_nodsh && skip "remote MDS with nodsh"
11276
11277         gpasswd -a daemon bin                           # LU-5641
11278         do_facet $SINGLEMDS gpasswd -a daemon bin       # LU-5641
11279
11280         declare -a identity_old
11281
11282         for num in $(seq $MDSCOUNT); do
11283                 switch_identity $num true || identity_old[$num]=$?
11284         done
11285
11286         SAVE_UMASK=$(umask)
11287         umask 0022
11288         mkdir -p $DIR/$tdir
11289         cd $DIR/$tdir
11290
11291         echo "performing cp ..."
11292         run_acl_subtest cp || error "run_acl_subtest cp failed"
11293         echo "performing getfacl-noacl..."
11294         run_acl_subtest getfacl-noacl || error "getfacl-noacl test failed"
11295         echo "performing misc..."
11296         run_acl_subtest misc || error  "misc test failed"
11297         echo "performing permissions..."
11298         run_acl_subtest permissions || error "permissions failed"
11299         # LU-1482 mdd: Setting xattr are properly checked with and without ACLs
11300         if [ $MDS1_VERSION -gt $(version_code 2.8.55) ] ||
11301                 { [ $MDS1_VERSION -lt $(version_code 2.6) ] &&
11302                         [ $MDS1_VERSION -ge $(version_code 2.5.29) ]; }
11303         then
11304                 echo "performing permissions xattr..."
11305                 run_acl_subtest permissions_xattr ||
11306                         error "permissions_xattr failed"
11307         fi
11308         echo "performing setfacl..."
11309         run_acl_subtest setfacl || error  "setfacl test failed"
11310
11311         # inheritance test got from HP
11312         echo "performing inheritance..."
11313         cp $LUSTRE/tests/acl/make-tree . || error "cannot copy make-tree"
11314         chmod +x make-tree || error "chmod +x failed"
11315         run_acl_subtest inheritance || error "inheritance test failed"
11316         rm -f make-tree
11317
11318         echo "LU-974 ignore umask when acl is enabled..."
11319         run_acl_subtest 974 || error "LU-974 umask test failed"
11320         if [ $MDSCOUNT -ge 2 ]; then
11321                 run_acl_subtest 974_remote ||
11322                         error "LU-974 umask test failed under remote dir"
11323         fi
11324
11325         echo "LU-2561 newly created file is same size as directory..."
11326         if [ "$mds1_FSTYPE" != "zfs" ]; then
11327                 run_acl_subtest 2561 || error "LU-2561 test failed"
11328         else
11329                 run_acl_subtest 2561_zfs || error "LU-2561 zfs test failed"
11330         fi
11331
11332         run_acl_subtest 4924 || error "LU-4924 test failed"
11333
11334         cd $SAVE_PWD
11335         umask $SAVE_UMASK
11336
11337         for num in $(seq $MDSCOUNT); do
11338                 if [ "${identity_old[$num]}" = 1 ]; then
11339                         switch_identity $num false || identity_old[$num]=$?
11340                 fi
11341         done
11342 }
11343 run_test 103a "acl test"
11344
11345 test_103b() {
11346         declare -a pids
11347         local U
11348
11349         for U in {0..511}; do
11350                 {
11351                 local O=$(printf "%04o" $U)
11352
11353                 umask $(printf "%04o" $((511 ^ $O)))
11354                 $LFS setstripe -c 1 $DIR/$tfile.s$O
11355                 local S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.s$O))
11356
11357                 (( $S == ($O & 0666) )) ||
11358                         error "lfs setstripe $DIR/$tfile.s$O '$S' != '$O'"
11359
11360                 $LFS setstripe -E16M -c 1 -E1G -S4M $DIR/$tfile.p$O
11361                 S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.p$O))
11362                 (( $S == ($O & 0666) )) ||
11363                         error "lfs setstripe -E $DIR/$tfile.p$O '$S' != '$O'"
11364
11365                 $LFS setstripe -N2 -c 1 $DIR/$tfile.m$O
11366                 S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.m$O))
11367                 (( $S == ($O & 0666) )) ||
11368                         error "lfs setstripe -N2 $DIR/$tfile.m$O '$S' != '$O'"
11369                 rm -f $DIR/$tfile.[smp]$0
11370                 } &
11371                 local pid=$!
11372
11373                 # limit the concurrently running threads to 64. LU-11878
11374                 local idx=$((U % 64))
11375                 [ -z "${pids[idx]}" ] || wait ${pids[idx]}
11376                 pids[idx]=$pid
11377         done
11378         wait
11379 }
11380 run_test 103b "umask lfs setstripe"
11381
11382 test_103c() {
11383         mkdir -p $DIR/$tdir
11384         cp -rp $DIR/$tdir $DIR/$tdir.bak
11385
11386         [ -n "$(getfattr -d -m. $DIR/$tdir | grep posix_acl_default)" ] &&
11387                 error "$DIR/$tdir shouldn't contain default ACL"
11388         [ -n "$(getfattr -d -m. $DIR/$tdir.bak | grep posix_acl_default)" ] &&
11389                 error "$DIR/$tdir.bak shouldn't contain default ACL"
11390         true
11391 }
11392 run_test 103c "'cp -rp' won't set empty acl"
11393
11394 test_103e() {
11395         local numacl
11396         local fileacl
11397         local saved_debug=$($LCTL get_param -n debug)
11398
11399         (( $MDS1_VERSION >= $(version_code 2.14.0) )) ||
11400                 skip "MDS needs to be at least 2.14.0"
11401
11402         large_xattr_enabled || skip_env "ea_inode feature disabled"
11403
11404         mkdir -p $DIR/$tdir
11405         # add big LOV EA to cause reply buffer overflow earlier
11406         $LFS setstripe -C 1000 $DIR/$tdir
11407         lctl set_param mdc.*-mdc*.stats=clear
11408
11409         $LCTL set_param debug=0
11410         stack_trap "$LCTL set_param debug=\"$saved_debug\"" EXIT
11411         stack_trap "$LCTL get_param mdc.*-mdc*.stats" EXIT
11412
11413         # add a large number of default ACLs (expect 8000+ for 2.13+)
11414         for U in {2..7000}; do
11415                 setfacl -d -m user:$U:rwx $DIR/$tdir ||
11416                         error "Able to add just $U default ACLs"
11417         done
11418         numacl=$(getfacl $DIR/$tdir |& grep -c "default:user")
11419         echo "$numacl default ACLs created"
11420
11421         stat $DIR/$tdir || error "Cannot stat directory"
11422         # check file creation
11423         touch $DIR/$tdir/$tfile ||
11424                 error "failed to create $tfile with $numacl default ACLs"
11425         stat $DIR/$tdir/$tfile  || error "Cannot stat file"
11426         fileacl=$(getfacl $DIR/$tdir/$tfile |& grep -c "user:")
11427         echo "$fileacl ACLs were inherited"
11428         (( $fileacl == $numacl )) ||
11429                 error "Not all default ACLs were inherited: $numacl != $fileacl"
11430         # check that new ACLs creation adds new ACLs to inherited ACLs
11431         setfacl -m user:19000:rwx $DIR/$tdir/$tfile ||
11432                 error "Cannot set new ACL"
11433         numacl=$((numacl + 1))
11434         fileacl=$(getfacl $DIR/$tdir/$tfile |& grep -c "user:")
11435         (( $fileacl == $numacl )) ||
11436                 error "failed to add new ACL: $fileacl != $numacl as expected"
11437         # adds more ACLs to a file to reach their maximum at 8000+
11438         numacl=0
11439         for U in {20000..25000}; do
11440                 setfacl -m user:$U:rwx $DIR/$tdir/$tfile || break
11441                 numacl=$((numacl + 1))
11442         done
11443         echo "Added $numacl more ACLs to the file"
11444         fileacl=$(getfacl $DIR/$tdir/$tfile |& grep -c "user:")
11445         echo "Total $fileacl ACLs in file"
11446         stat $DIR/$tdir/$tfile > /dev/null || error "Cannot stat file"
11447         rm -f $DIR/$tdir/$tfile || error "Cannot remove file"
11448         rmdir $DIR/$tdir || error "Cannot remove directory"
11449 }
11450 run_test 103e "inheritance of big amount of default ACLs"
11451
11452 test_103f() {
11453         (( $MDS1_VERSION >= $(version_code 2.14.51) )) ||
11454                 skip "MDS needs to be at least 2.14.51"
11455
11456         large_xattr_enabled || skip_env "ea_inode feature disabled"
11457
11458         # enable changelog to consume more internal MDD buffers
11459         changelog_register
11460
11461         mkdir -p $DIR/$tdir
11462         # add big LOV EA
11463         $LFS setstripe -C 1000 $DIR/$tdir
11464         setfacl -d -m user:$U:rwx $DIR/$tdir || error "Cannot add default ACLs"
11465         mkdir $DIR/$tdir/inherited || error "failed to create subdirectory"
11466         rmdir $DIR/$tdir/inherited || error "Cannot remove subdirectory"
11467         rmdir $DIR/$tdir || error "Cannot remove directory"
11468 }
11469 run_test 103f "changelog doesn't interfere with default ACLs buffers"
11470
11471 test_104a() {
11472         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11473
11474         touch $DIR/$tfile
11475         lfs df || error "lfs df failed"
11476         lfs df -ih || error "lfs df -ih failed"
11477         lfs df -h $DIR || error "lfs df -h $DIR failed"
11478         lfs df -i $DIR || error "lfs df -i $DIR failed"
11479         lfs df $DIR/$tfile || error "lfs df $DIR/$tfile failed"
11480         lfs df -ih $DIR/$tfile || error "lfs df -ih $DIR/$tfile failed"
11481
11482         local OSC=$(lctl dl | grep OST0000-osc-[^M] | awk '{ print $4 }')
11483         lctl --device %$OSC deactivate
11484         lfs df || error "lfs df with deactivated OSC failed"
11485         lctl --device %$OSC activate
11486         # wait the osc back to normal
11487         wait_osc_import_ready client ost
11488
11489         lfs df || error "lfs df with reactivated OSC failed"
11490         rm -f $DIR/$tfile
11491 }
11492 run_test 104a "lfs df [-ih] [path] test ========================="
11493
11494 test_104b() {
11495         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11496         [ $RUNAS_ID -eq $UID ] &&
11497                 skip_env "RUNAS_ID = UID = $UID -- skipping"
11498
11499         denied_cnt=$(($($RUNAS $LFS check servers 2>&1 |
11500                         grep "Permission denied" | wc -l)))
11501         if [ $denied_cnt -ne 0 ]; then
11502                 error "lfs check servers test failed"
11503         fi
11504 }
11505 run_test 104b "$RUNAS lfs check servers test ===================="
11506
11507 #
11508 # Verify $1 is within range of $2.
11509 # Success when $1 is within range. That is, when $1 is >= 2% of $2 and
11510 # $1 is <= 2% of $2. Else Fail.
11511 #
11512 value_in_range() {
11513         # Strip all units (M, G, T)
11514         actual=$(echo $1 | tr -d A-Z)
11515         expect=$(echo $2 | tr -d A-Z)
11516
11517         expect_lo=$(($expect * 98 / 100)) # 2% below
11518         expect_hi=$(($expect * 102 / 100)) # 2% above
11519
11520         # permit 2% drift above and below
11521         (( $actual >= $expect_lo && $actual <= $expect_hi ))
11522 }
11523
11524 test_104c() {
11525         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11526         [ "$ost1_FSTYPE" == "zfs" ] || skip "zfs only test"
11527
11528         local ost_param="osd-zfs.$FSNAME-OST0000."
11529         local mdt_param="osd-zfs.$FSNAME-MDT0000."
11530         local ofacets=$(get_facets OST)
11531         local mfacets=$(get_facets MDS)
11532         local saved_ost_blocks=
11533         local saved_mdt_blocks=
11534
11535         echo "Before recordsize change"
11536         lfs_df=($($LFS df -h | grep "filesystem_summary:"))
11537         df=($(df -h | grep "/mnt/lustre"$))
11538
11539         # For checking.
11540         echo "lfs output : ${lfs_df[*]}"
11541         echo "df  output : ${df[*]}"
11542
11543         for facet in ${ofacets//,/ }; do
11544                 if [ -z $saved_ost_blocks ]; then
11545                         saved_ost_blocks=$(do_facet $facet \
11546                                 lctl get_param -n $ost_param.blocksize)
11547                         echo "OST Blocksize: $saved_ost_blocks"
11548                 fi
11549                 ost=$(do_facet $facet lctl get_param -n $ost_param.mntdev)
11550                 do_facet $facet zfs set recordsize=32768 $ost
11551         done
11552
11553         # BS too small. Sufficient for functional testing.
11554         for facet in ${mfacets//,/ }; do
11555                 if [ -z $saved_mdt_blocks ]; then
11556                         saved_mdt_blocks=$(do_facet $facet \
11557                                 lctl get_param -n $mdt_param.blocksize)
11558                         echo "MDT Blocksize: $saved_mdt_blocks"
11559                 fi
11560                 mdt=$(do_facet $facet lctl get_param -n $mdt_param.mntdev)
11561                 do_facet $facet zfs set recordsize=32768 $mdt
11562         done
11563
11564         # Give new values chance to reflect change
11565         sleep 2
11566
11567         echo "After recordsize change"
11568         lfs_df_after=($($LFS df -h | grep "filesystem_summary:"))
11569         df_after=($(df -h | grep "/mnt/lustre"$))
11570
11571         # For checking.
11572         echo "lfs output : ${lfs_df_after[*]}"
11573         echo "df  output : ${df_after[*]}"
11574
11575         # Verify lfs df
11576         value_in_range ${lfs_df_after[1]%.*} ${lfs_df[1]%.*} ||
11577                 error "lfs_df bytes: ${lfs_df_after[1]%.*} != ${lfs_df[1]%.*}"
11578         value_in_range ${lfs_df_after[2]%.*} ${lfs_df[2]%.*} ||
11579                 error "lfs_df used: ${lfs_df_after[2]%.*} != ${lfs_df[2]%.*}"
11580         value_in_range ${lfs_df_after[3]%.*} ${lfs_df[3]%.*} ||
11581                 error "lfs_df avail: ${lfs_df_after[3]%.*} != ${lfs_df[3]%.*}"
11582
11583         # Verify df
11584         value_in_range ${df_after[1]%.*} ${df[1]%.*} ||
11585                 error "df bytes: ${df_after[1]%.*} != ${df[1]%.*}"
11586         value_in_range ${df_after[2]%.*} ${df[2]%.*} ||
11587                 error "df used: ${df_after[2]%.*} != ${df[2]%.*}"
11588         value_in_range ${df_after[3]%.*} ${df[3]%.*} ||
11589                 error "df avail: ${df_after[3]%.*} != ${df[3]%.*}"
11590
11591         # Restore MDT recordize back to original
11592         for facet in ${mfacets//,/ }; do
11593                 mdt=$(do_facet $facet lctl get_param -n $mdt_param.mntdev)
11594                 do_facet $facet zfs set recordsize=$saved_mdt_blocks $mdt
11595         done
11596
11597         # Restore OST recordize back to original
11598         for facet in ${ofacets//,/ }; do
11599                 ost=$(do_facet $facet lctl get_param -n $ost_param.mntdev)
11600                 do_facet $facet zfs set recordsize=$saved_ost_blocks $ost
11601         done
11602
11603         return 0
11604 }
11605 run_test 104c "Verify df vs lfs_df stays same after recordsize change"
11606
11607 test_105a() {
11608         # doesn't work on 2.4 kernels
11609         touch $DIR/$tfile
11610         if $(flock_is_enabled); then
11611                 flocks_test 1 on -f $DIR/$tfile || error "fail flock on"
11612         else
11613                 flocks_test 1 off -f $DIR/$tfile || error "fail flock off"
11614         fi
11615         rm -f $DIR/$tfile
11616 }
11617 run_test 105a "flock when mounted without -o flock test ========"
11618
11619 test_105b() {
11620         touch $DIR/$tfile
11621         if $(flock_is_enabled); then
11622                 flocks_test 1 on -c $DIR/$tfile || error "fail flock on"
11623         else
11624                 flocks_test 1 off -c $DIR/$tfile || error "fail flock off"
11625         fi
11626         rm -f $DIR/$tfile
11627 }
11628 run_test 105b "fcntl when mounted without -o flock test ========"
11629
11630 test_105c() {
11631         touch $DIR/$tfile
11632         if $(flock_is_enabled); then
11633                 flocks_test 1 on -l $DIR/$tfile || error "fail flock on"
11634         else
11635                 flocks_test 1 off -l $DIR/$tfile || error "fail flock off"
11636         fi
11637         rm -f $DIR/$tfile
11638 }
11639 run_test 105c "lockf when mounted without -o flock test"
11640
11641 test_105d() { # bug 15924
11642         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11643
11644         test_mkdir $DIR/$tdir
11645         flock_is_enabled || skip_env "mount w/o flock enabled"
11646         #define OBD_FAIL_LDLM_CP_CB_WAIT  0x315
11647         $LCTL set_param fail_loc=0x80000315
11648         flocks_test 2 $DIR/$tdir
11649 }
11650 run_test 105d "flock race (should not freeze) ========"
11651
11652 test_105e() { # bug 22660 && 22040
11653         flock_is_enabled || skip_env "mount w/o flock enabled"
11654
11655         touch $DIR/$tfile
11656         flocks_test 3 $DIR/$tfile
11657 }
11658 run_test 105e "Two conflicting flocks from same process"
11659
11660 test_106() { #bug 10921
11661         test_mkdir $DIR/$tdir
11662         $DIR/$tdir && error "exec $DIR/$tdir succeeded"
11663         chmod 777 $DIR/$tdir || error "chmod $DIR/$tdir failed"
11664 }
11665 run_test 106 "attempt exec of dir followed by chown of that dir"
11666
11667 test_107() {
11668         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11669
11670         CDIR=`pwd`
11671         local file=core
11672
11673         cd $DIR
11674         rm -f $file
11675
11676         local save_pattern=$(sysctl -n kernel.core_pattern)
11677         local save_uses_pid=$(sysctl -n kernel.core_uses_pid)
11678         sysctl -w kernel.core_pattern=$file
11679         sysctl -w kernel.core_uses_pid=0
11680
11681         ulimit -c unlimited
11682         sleep 60 &
11683         SLEEPPID=$!
11684
11685         sleep 1
11686
11687         kill -s 11 $SLEEPPID
11688         wait $SLEEPPID
11689         if [ -e $file ]; then
11690                 size=`stat -c%s $file`
11691                 [ $size -eq 0 ] && error "Fail to create core file $file"
11692         else
11693                 error "Fail to create core file $file"
11694         fi
11695         rm -f $file
11696         sysctl -w kernel.core_pattern=$save_pattern
11697         sysctl -w kernel.core_uses_pid=$save_uses_pid
11698         cd $CDIR
11699 }
11700 run_test 107 "Coredump on SIG"
11701
11702 test_110() {
11703         test_mkdir $DIR/$tdir
11704         test_mkdir $DIR/$tdir/$(str_repeat 'a' 255)
11705         $LFS mkdir -c $MDSCOUNT $DIR/$tdir/$(str_repeat 'b' 256) &&
11706                 error "mkdir with 256 char should fail, but did not"
11707         touch $DIR/$tdir/$(str_repeat 'x' 255) ||
11708                 error "create with 255 char failed"
11709         touch $DIR/$tdir/$(str_repeat 'y' 256) &&
11710                 error "create with 256 char should fail, but did not"
11711
11712         ls -l $DIR/$tdir
11713         rm -rf $DIR/$tdir
11714 }
11715 run_test 110 "filename length checking"
11716
11717 #
11718 # Purpose: To verify dynamic thread (OSS) creation.
11719 #
11720 test_115() {
11721         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11722         remote_ost_nodsh && skip "remote OST with nodsh"
11723
11724         # Lustre does not stop service threads once they are started.
11725         # Reset number of running threads to default.
11726         stopall
11727         setupall
11728
11729         local OSTIO_pre
11730         local save_params="$TMP/sanity-$TESTNAME.parameters"
11731
11732         # Get ll_ost_io count before I/O
11733         OSTIO_pre=$(do_facet ost1 \
11734                 "$LCTL get_param ost.OSS.ost_io.threads_started | cut -d= -f2")
11735         # Exit if lustre is not running (ll_ost_io not running).
11736         [ -z "$OSTIO_pre" ] && error "no OSS threads"
11737
11738         echo "Starting with $OSTIO_pre threads"
11739         local thread_max=$((OSTIO_pre * 2))
11740         local rpc_in_flight=$((thread_max * 2))
11741         # Number of I/O Process proposed to be started.
11742         local nfiles
11743         local facets=$(get_facets OST)
11744
11745         save_lustre_params client "osc.*OST*.max_rpcs_in_flight" > $save_params
11746         save_lustre_params $facets "ost.OSS.ost_io.threads_max" >> $save_params
11747
11748         # Set in_flight to $rpc_in_flight
11749         $LCTL set_param osc.*OST*.max_rpcs_in_flight=$rpc_in_flight ||
11750                 error "Failed to set max_rpcs_in_flight to $rpc_in_flight"
11751         nfiles=${rpc_in_flight}
11752         # Set ost thread_max to $thread_max
11753         do_facet ost1 "$LCTL set_param ost.OSS.ost_io.threads_max=$thread_max"
11754
11755         # 5 Minutes should be sufficient for max number of OSS
11756         # threads(thread_max) to be created.
11757         local timeout=300
11758
11759         # Start I/O.
11760         local WTL=${WTL:-"$LUSTRE/tests/write_time_limit"}
11761         test_mkdir $DIR/$tdir
11762         for i in $(seq $nfiles); do
11763                 local file=$DIR/$tdir/${tfile}-$i
11764                 $LFS setstripe -c -1 -i 0 $file
11765                 ($WTL $file $timeout)&
11766         done
11767
11768         # I/O Started - Wait for thread_started to reach thread_max or report
11769         # error if thread_started is more than thread_max.
11770         echo "Waiting for thread_started to reach thread_max"
11771         local thread_started=0
11772         local end_time=$((SECONDS + timeout))
11773
11774         while [ $SECONDS -le $end_time ] ; do
11775                 echo -n "."
11776                 # Get ost i/o thread_started count.
11777                 thread_started=$(do_facet ost1 \
11778                         "$LCTL get_param \
11779                         ost.OSS.ost_io.threads_started | cut -d= -f2")
11780                 # Break out if thread_started is equal/greater than thread_max
11781                 if [[ $thread_started -ge $thread_max ]]; then
11782                         echo ll_ost_io thread_started $thread_started, \
11783                                 equal/greater than thread_max $thread_max
11784                         break
11785                 fi
11786                 sleep 1
11787         done
11788
11789         # Cleanup - We have the numbers, Kill i/o jobs if running.
11790         jobcount=($(jobs -p))
11791         for i in $(seq 0 $((${#jobcount[@]}-1)))
11792         do
11793                 kill -9 ${jobcount[$i]}
11794                 if [ $? -ne 0 ] ; then
11795                         echo Warning: \
11796                         Failed to Kill \'WTL\(I/O\)\' with pid ${jobcount[$i]}
11797                 fi
11798         done
11799
11800         # Cleanup files left by WTL binary.
11801         for i in $(seq $nfiles); do
11802                 local file=$DIR/$tdir/${tfile}-$i
11803                 rm -rf $file
11804                 if [ $? -ne 0 ] ; then
11805                         echo "Warning: Failed to delete file $file"
11806                 fi
11807         done
11808
11809         restore_lustre_params <$save_params
11810         rm -f $save_params || echo "Warning: delete file '$save_params' failed"
11811
11812         # Error out if no new thread has started or Thread started is greater
11813         # than thread max.
11814         if [[ $thread_started -le $OSTIO_pre ||
11815                         $thread_started -gt $thread_max ]]; then
11816                 error "ll_ost_io: thread_started $thread_started" \
11817                       "OSTIO_pre $OSTIO_pre, thread_max $thread_max." \
11818                       "No new thread started or thread started greater " \
11819                       "than thread_max."
11820         fi
11821 }
11822 run_test 115 "verify dynamic thread creation===================="
11823
11824 free_min_max () {
11825         wait_delete_completed
11826         AVAIL=($(lctl get_param -n osc.*[oO][sS][cC]-[^M]*.kbytesavail))
11827         echo "OST kbytes available: ${AVAIL[@]}"
11828         MAXV=${AVAIL[0]}
11829         MAXI=0
11830         MINV=${AVAIL[0]}
11831         MINI=0
11832         for ((i = 0; i < ${#AVAIL[@]}; i++)); do
11833                 #echo OST $i: ${AVAIL[i]}kb
11834                 if [[ ${AVAIL[i]} -gt $MAXV ]]; then
11835                         MAXV=${AVAIL[i]}
11836                         MAXI=$i
11837                 fi
11838                 if [[ ${AVAIL[i]} -lt $MINV ]]; then
11839                         MINV=${AVAIL[i]}
11840                         MINI=$i
11841                 fi
11842         done
11843         echo "Min free space: OST $MINI: $MINV"
11844         echo "Max free space: OST $MAXI: $MAXV"
11845 }
11846
11847 test_116a() { # was previously test_116()
11848         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11849         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11850         remote_mds_nodsh && skip "remote MDS with nodsh"
11851
11852         echo -n "Free space priority "
11853         do_facet $SINGLEMDS lctl get_param -n lo[vd].*-mdtlov.qos_prio_free |
11854                 head -n1
11855         declare -a AVAIL
11856         free_min_max
11857
11858         [ $MINV -eq 0 ] && skip "no free space in OST$MINI, skip"
11859         [ $MINV -gt 10000000 ] && skip "too much free space in OST$MINI, skip"
11860         trap simple_cleanup_common EXIT
11861
11862         # Check if we need to generate uneven OSTs
11863         test_mkdir -p $DIR/$tdir/OST${MINI}
11864         local FILL=$((MINV / 4))
11865         local DIFF=$((MAXV - MINV))
11866         local DIFF2=$((DIFF * 100 / MINV))
11867
11868         local threshold=$(do_facet $SINGLEMDS \
11869                 lctl get_param -n *.*MDT0000-mdtlov.qos_threshold_rr | head -n1)
11870         threshold=${threshold%%%}
11871         echo -n "Check for uneven OSTs: "
11872         echo -n "diff=${DIFF}KB (${DIFF2}%) must be > ${threshold}% ..."
11873
11874         if [[ $DIFF2 -gt $threshold ]]; then
11875                 echo "ok"
11876                 echo "Don't need to fill OST$MINI"
11877         else
11878                 # generate uneven OSTs. Write 2% over the QOS threshold value
11879                 echo "no"
11880                 DIFF=$((threshold - DIFF2 + 2))
11881                 DIFF2=$((MINV * DIFF / 100))
11882                 echo "Fill $DIFF% remaining space in OST$MINI with ${DIFF2}KB"
11883                 $LFS setstripe -i $MINI -c 1 $DIR/$tdir/OST${MINI} ||
11884                         error "setstripe failed"
11885                 DIFF=$((DIFF2 / 2048))
11886                 i=0
11887                 while [ $i -lt $DIFF ]; do
11888                         i=$((i + 1))
11889                         dd if=/dev/zero of=$DIR/$tdir/OST${MINI}/$tfile-$i \
11890                                 bs=2M count=1 2>/dev/null
11891                         echo -n .
11892                 done
11893                 echo .
11894                 sync
11895                 sleep_maxage
11896                 free_min_max
11897         fi
11898
11899         DIFF=$((MAXV - MINV))
11900         DIFF2=$((DIFF * 100 / MINV))
11901         echo -n "diff=$DIFF=$DIFF2% must be > $threshold% for QOS mode..."
11902         if [ $DIFF2 -gt $threshold ]; then
11903                 echo "ok"
11904         else
11905                 echo "failed - QOS mode won't be used"
11906                 simple_cleanup_common
11907                 skip "QOS imbalance criteria not met"
11908         fi
11909
11910         MINI1=$MINI
11911         MINV1=$MINV
11912         MAXI1=$MAXI
11913         MAXV1=$MAXV
11914
11915         # now fill using QOS
11916         $LFS setstripe -c 1 $DIR/$tdir
11917         FILL=$((FILL / 200))
11918         if [ $FILL -gt 600 ]; then
11919                 FILL=600
11920         fi
11921         echo "writing $FILL files to QOS-assigned OSTs"
11922         i=0
11923         while [ $i -lt $FILL ]; do
11924                 i=$((i + 1))
11925                 dd if=/dev/zero of=$DIR/$tdir/$tfile-$i bs=200k \
11926                         count=1 2>/dev/null
11927                 echo -n .
11928         done
11929         echo "wrote $i 200k files"
11930         sync
11931         sleep_maxage
11932
11933         echo "Note: free space may not be updated, so measurements might be off"
11934         free_min_max
11935         DIFF2=$((MAXV - MINV))
11936         echo "free space delta: orig $DIFF final $DIFF2"
11937         [ $DIFF2 -gt $DIFF ] && echo "delta got worse!"
11938         DIFF=$((MINV1 - ${AVAIL[$MINI1]}))
11939         echo "Wrote ${DIFF}KB to smaller OST $MINI1"
11940         DIFF2=$((MAXV1 - ${AVAIL[$MAXI1]}))
11941         echo "Wrote ${DIFF2}KB to larger OST $MAXI1"
11942         if [[ $DIFF -gt 0 ]]; then
11943                 FILL=$((DIFF2 * 100 / DIFF - 100))
11944                 echo "Wrote ${FILL}% more data to larger OST $MAXI1"
11945         fi
11946
11947         # Figure out which files were written where
11948         UUID=$(lctl get_param -n lov.${FSNAME}-clilov-*.target_obd |
11949                awk '/'$MINI1': / {print $2; exit}')
11950         echo $UUID
11951         MINC=$($LFS getstripe --ost $UUID $DIR/$tdir | grep $DIR | wc -l)
11952         echo "$MINC files created on smaller OST $MINI1"
11953         UUID=$(lctl get_param -n lov.${FSNAME}-clilov-*.target_obd |
11954                awk '/'$MAXI1': / {print $2; exit}')
11955         echo $UUID
11956         MAXC=$($LFS getstripe --ost $UUID $DIR/$tdir | grep $DIR | wc -l)
11957         echo "$MAXC files created on larger OST $MAXI1"
11958         if [[ $MINC -gt 0 ]]; then
11959                 FILL=$((MAXC * 100 / MINC - 100))
11960                 echo "Wrote ${FILL}% more files to larger OST $MAXI1"
11961         fi
11962         [[ $MAXC -gt $MINC ]] ||
11963                 error_ignore LU-9 "stripe QOS didn't balance free space"
11964         simple_cleanup_common
11965 }
11966 run_test 116a "stripe QOS: free space balance ==================="
11967
11968 test_116b() { # LU-2093
11969         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11970         remote_mds_nodsh && skip "remote MDS with nodsh"
11971
11972 #define OBD_FAIL_MDS_OSC_CREATE_FAIL     0x147
11973         local old_rr=$(do_facet $SINGLEMDS lctl get_param -n \
11974                        lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr | head -1)
11975         [ -z "$old_rr" ] && skip "no QOS"
11976         do_facet $SINGLEMDS lctl set_param \
11977                 lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr=0
11978         mkdir -p $DIR/$tdir
11979         do_facet $SINGLEMDS lctl set_param fail_loc=0x147
11980         createmany -o $DIR/$tdir/f- 20 || error "can't create"
11981         do_facet $SINGLEMDS lctl set_param fail_loc=0
11982         rm -rf $DIR/$tdir
11983         do_facet $SINGLEMDS lctl set_param \
11984                 lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr=$old_rr
11985 }
11986 run_test 116b "QoS shouldn't LBUG if not enough OSTs found on the 2nd pass"
11987
11988 test_117() # bug 10891
11989 {
11990         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11991
11992         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
11993         #define OBD_FAIL_OST_SETATTR_CREDITS 0x21e
11994         lctl set_param fail_loc=0x21e
11995         > $DIR/$tfile || error "truncate failed"
11996         lctl set_param fail_loc=0
11997         echo "Truncate succeeded."
11998         rm -f $DIR/$tfile
11999 }
12000 run_test 117 "verify osd extend =========="
12001
12002 NO_SLOW_RESENDCOUNT=4
12003 export OLD_RESENDCOUNT=""
12004 set_resend_count () {
12005         local PROC_RESENDCOUNT="osc.${FSNAME}-OST*-osc-*.resend_count"
12006         OLD_RESENDCOUNT=$(lctl get_param -n $PROC_RESENDCOUNT | head -n1)
12007         lctl set_param -n $PROC_RESENDCOUNT $1
12008         echo resend_count is set to $(lctl get_param -n $PROC_RESENDCOUNT)
12009 }
12010
12011 # for reduce test_118* time (b=14842)
12012 [ "$SLOW" = "no" ] && set_resend_count $NO_SLOW_RESENDCOUNT
12013
12014 # Reset async IO behavior after error case
12015 reset_async() {
12016         FILE=$DIR/reset_async
12017
12018         # Ensure all OSCs are cleared
12019         $LFS setstripe -c -1 $FILE
12020         dd if=/dev/zero of=$FILE bs=64k count=$OSTCOUNT
12021         sync
12022         rm $FILE
12023 }
12024
12025 test_118a() #bug 11710
12026 {
12027         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12028
12029         reset_async
12030
12031         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
12032         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12033         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
12034
12035         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12036                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12037                 return 1;
12038         fi
12039         rm -f $DIR/$tfile
12040 }
12041 run_test 118a "verify O_SYNC works =========="
12042
12043 test_118b()
12044 {
12045         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12046         remote_ost_nodsh && skip "remote OST with nodsh"
12047
12048         reset_async
12049
12050         #define OBD_FAIL_SRV_ENOENT 0x217
12051         set_nodes_failloc "$(osts_nodes)" 0x217
12052         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
12053         RC=$?
12054         set_nodes_failloc "$(osts_nodes)" 0
12055         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12056         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12057                     grep -c writeback)
12058
12059         if [[ $RC -eq 0 ]]; then
12060                 error "Must return error due to dropped pages, rc=$RC"
12061                 return 1;
12062         fi
12063
12064         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12065                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12066                 return 1;
12067         fi
12068
12069         echo "Dirty pages not leaked on ENOENT"
12070
12071         # Due to the above error the OSC will issue all RPCs syncronously
12072         # until a subsequent RPC completes successfully without error.
12073         $MULTIOP $DIR/$tfile Ow4096yc
12074         rm -f $DIR/$tfile
12075
12076         return 0
12077 }
12078 run_test 118b "Reclaim dirty pages on fatal error =========="
12079
12080 test_118c()
12081 {
12082         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12083
12084         # for 118c, restore the original resend count, LU-1940
12085         [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] &&
12086                                 set_resend_count $OLD_RESENDCOUNT
12087         remote_ost_nodsh && skip "remote OST with nodsh"
12088
12089         reset_async
12090
12091         #define OBD_FAIL_OST_EROFS               0x216
12092         set_nodes_failloc "$(osts_nodes)" 0x216
12093
12094         # multiop should block due to fsync until pages are written
12095         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
12096         MULTIPID=$!
12097         sleep 1
12098
12099         if [[ `ps h -o comm -p $MULTIPID` != "multiop" ]]; then
12100                 error "Multiop failed to block on fsync, pid=$MULTIPID"
12101         fi
12102
12103         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12104                     grep -c writeback)
12105         if [[ $WRITEBACK -eq 0 ]]; then
12106                 error "No page in writeback, writeback=$WRITEBACK"
12107         fi
12108
12109         set_nodes_failloc "$(osts_nodes)" 0
12110         wait $MULTIPID
12111         RC=$?
12112         if [[ $RC -ne 0 ]]; then
12113                 error "Multiop fsync failed, rc=$RC"
12114         fi
12115
12116         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12117         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12118                     grep -c writeback)
12119         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12120                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12121         fi
12122
12123         rm -f $DIR/$tfile
12124         echo "Dirty pages flushed via fsync on EROFS"
12125         return 0
12126 }
12127 run_test 118c "Fsync blocks on EROFS until dirty pages are flushed =========="
12128
12129 # continue to use small resend count to reduce test_118* time (b=14842)
12130 [ "$SLOW" = "no" ] && set_resend_count $NO_SLOW_RESENDCOUNT
12131
12132 test_118d()
12133 {
12134         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12135         remote_ost_nodsh && skip "remote OST with nodsh"
12136
12137         reset_async
12138
12139         #define OBD_FAIL_OST_BRW_PAUSE_BULK
12140         set_nodes_failloc "$(osts_nodes)" 0x214
12141         # multiop should block due to fsync until pages are written
12142         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
12143         MULTIPID=$!
12144         sleep 1
12145
12146         if [[ `ps h -o comm -p $MULTIPID` != "multiop" ]]; then
12147                 error "Multiop failed to block on fsync, pid=$MULTIPID"
12148         fi
12149
12150         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12151                     grep -c writeback)
12152         if [[ $WRITEBACK -eq 0 ]]; then
12153                 error "No page in writeback, writeback=$WRITEBACK"
12154         fi
12155
12156         wait $MULTIPID || error "Multiop fsync failed, rc=$?"
12157         set_nodes_failloc "$(osts_nodes)" 0
12158
12159         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12160         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12161                     grep -c writeback)
12162         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12163                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12164         fi
12165
12166         rm -f $DIR/$tfile
12167         echo "Dirty pages gaurenteed flushed via fsync"
12168         return 0
12169 }
12170 run_test 118d "Fsync validation inject a delay of the bulk =========="
12171
12172 test_118f() {
12173         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12174
12175         reset_async
12176
12177         #define OBD_FAIL_OSC_BRW_PREP_REQ2        0x40a
12178         lctl set_param fail_loc=0x8000040a
12179
12180         # Should simulate EINVAL error which is fatal
12181         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
12182         RC=$?
12183         if [[ $RC -eq 0 ]]; then
12184                 error "Must return error due to dropped pages, rc=$RC"
12185         fi
12186
12187         lctl set_param fail_loc=0x0
12188
12189         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
12190         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12191         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12192                     grep -c writeback)
12193         if [[ $LOCKED -ne 0 ]]; then
12194                 error "Locked pages remain in cache, locked=$LOCKED"
12195         fi
12196
12197         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12198                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12199         fi
12200
12201         rm -f $DIR/$tfile
12202         echo "No pages locked after fsync"
12203
12204         reset_async
12205         return 0
12206 }
12207 run_test 118f "Simulate unrecoverable OSC side error =========="
12208
12209 test_118g() {
12210         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12211
12212         reset_async
12213
12214         #define OBD_FAIL_OSC_BRW_PREP_REQ        0x406
12215         lctl set_param fail_loc=0x406
12216
12217         # simulate local -ENOMEM
12218         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
12219         RC=$?
12220
12221         lctl set_param fail_loc=0
12222         if [[ $RC -eq 0 ]]; then
12223                 error "Must return error due to dropped pages, rc=$RC"
12224         fi
12225
12226         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
12227         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12228         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12229                         grep -c writeback)
12230         if [[ $LOCKED -ne 0 ]]; then
12231                 error "Locked pages remain in cache, locked=$LOCKED"
12232         fi
12233
12234         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12235                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12236         fi
12237
12238         rm -f $DIR/$tfile
12239         echo "No pages locked after fsync"
12240
12241         reset_async
12242         return 0
12243 }
12244 run_test 118g "Don't stay in wait if we got local -ENOMEM  =========="
12245
12246 test_118h() {
12247         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12248         remote_ost_nodsh && skip "remote OST with nodsh"
12249
12250         reset_async
12251
12252         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
12253         set_nodes_failloc "$(osts_nodes)" 0x20e
12254         # Should simulate ENOMEM error which is recoverable and should be handled by timeout
12255         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
12256         RC=$?
12257
12258         set_nodes_failloc "$(osts_nodes)" 0
12259         if [[ $RC -eq 0 ]]; then
12260                 error "Must return error due to dropped pages, rc=$RC"
12261         fi
12262
12263         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
12264         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12265         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12266                     grep -c writeback)
12267         if [[ $LOCKED -ne 0 ]]; then
12268                 error "Locked pages remain in cache, locked=$LOCKED"
12269         fi
12270
12271         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12272                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12273         fi
12274
12275         rm -f $DIR/$tfile
12276         echo "No pages locked after fsync"
12277
12278         return 0
12279 }
12280 run_test 118h "Verify timeout in handling recoverables errors  =========="
12281
12282 [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] && set_resend_count $OLD_RESENDCOUNT
12283
12284 test_118i() {
12285         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12286         remote_ost_nodsh && skip "remote OST with nodsh"
12287
12288         reset_async
12289
12290         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
12291         set_nodes_failloc "$(osts_nodes)" 0x20e
12292
12293         # Should simulate ENOMEM error which is recoverable and should be handled by timeout
12294         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
12295         PID=$!
12296         sleep 5
12297         set_nodes_failloc "$(osts_nodes)" 0
12298
12299         wait $PID
12300         RC=$?
12301         if [[ $RC -ne 0 ]]; then
12302                 error "got error, but should be not, rc=$RC"
12303         fi
12304
12305         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
12306         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12307         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
12308         if [[ $LOCKED -ne 0 ]]; then
12309                 error "Locked pages remain in cache, locked=$LOCKED"
12310         fi
12311
12312         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12313                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12314         fi
12315
12316         rm -f $DIR/$tfile
12317         echo "No pages locked after fsync"
12318
12319         return 0
12320 }
12321 run_test 118i "Fix error before timeout in recoverable error  =========="
12322
12323 [ "$SLOW" = "no" ] && set_resend_count 4
12324
12325 test_118j() {
12326         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12327         remote_ost_nodsh && skip "remote OST with nodsh"
12328
12329         reset_async
12330
12331         #define OBD_FAIL_OST_BRW_WRITE_BULK2     0x220
12332         set_nodes_failloc "$(osts_nodes)" 0x220
12333
12334         # return -EIO from OST
12335         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
12336         RC=$?
12337         set_nodes_failloc "$(osts_nodes)" 0x0
12338         if [[ $RC -eq 0 ]]; then
12339                 error "Must return error due to dropped pages, rc=$RC"
12340         fi
12341
12342         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
12343         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12344         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
12345         if [[ $LOCKED -ne 0 ]]; then
12346                 error "Locked pages remain in cache, locked=$LOCKED"
12347         fi
12348
12349         # in recoverable error on OST we want resend and stay until it finished
12350         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12351                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12352         fi
12353
12354         rm -f $DIR/$tfile
12355         echo "No pages locked after fsync"
12356
12357         return 0
12358 }
12359 run_test 118j "Simulate unrecoverable OST side error =========="
12360
12361 test_118k()
12362 {
12363         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12364         remote_ost_nodsh && skip "remote OSTs with nodsh"
12365
12366         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
12367         set_nodes_failloc "$(osts_nodes)" 0x20e
12368         test_mkdir $DIR/$tdir
12369
12370         for ((i=0;i<10;i++)); do
12371                 (dd if=/dev/zero of=$DIR/$tdir/$tfile-$i bs=1M count=10 || \
12372                         error "dd to $DIR/$tdir/$tfile-$i failed" )&
12373                 SLEEPPID=$!
12374                 sleep 0.500s
12375                 kill $SLEEPPID
12376                 wait $SLEEPPID
12377         done
12378
12379         set_nodes_failloc "$(osts_nodes)" 0
12380         rm -rf $DIR/$tdir
12381 }
12382 run_test 118k "bio alloc -ENOMEM and IO TERM handling ========="
12383
12384 test_118l() # LU-646
12385 {
12386         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12387
12388         test_mkdir $DIR/$tdir
12389         $MULTIOP $DIR/$tdir Dy || error "fsync dir failed"
12390         rm -rf $DIR/$tdir
12391 }
12392 run_test 118l "fsync dir"
12393
12394 test_118m() # LU-3066
12395 {
12396         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12397
12398         test_mkdir $DIR/$tdir
12399         $MULTIOP $DIR/$tdir DY || error "fdatasync dir failed"
12400         rm -rf $DIR/$tdir
12401 }
12402 run_test 118m "fdatasync dir ========="
12403
12404 [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] && set_resend_count $OLD_RESENDCOUNT
12405
12406 test_118n()
12407 {
12408         local begin
12409         local end
12410
12411         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12412         remote_ost_nodsh && skip "remote OSTs with nodsh"
12413
12414         # Sleep to avoid a cached response.
12415         #define OBD_STATFS_CACHE_SECONDS 1
12416         sleep 2
12417
12418         # Inject a 10 second delay in the OST_STATFS handler.
12419         #define OBD_FAIL_OST_STATFS_DELAY 0x242
12420         set_nodes_failloc "$(osts_nodes)" 0x242
12421
12422         begin=$SECONDS
12423         stat --file-system $MOUNT > /dev/null
12424         end=$SECONDS
12425
12426         set_nodes_failloc "$(osts_nodes)" 0
12427
12428         if ((end - begin > 20)); then
12429             error "statfs took $((end - begin)) seconds, expected 10"
12430         fi
12431 }
12432 run_test 118n "statfs() sends OST_STATFS requests in parallel"
12433
12434 test_119a() # bug 11737
12435 {
12436         BSIZE=$((512 * 1024))
12437         directio write $DIR/$tfile 0 1 $BSIZE
12438         # We ask to read two blocks, which is more than a file size.
12439         # directio will indicate an error when requested and actual
12440         # sizes aren't equeal (a normal situation in this case) and
12441         # print actual read amount.
12442         NOB=`directio read $DIR/$tfile 0 2 $BSIZE | awk '/error/ {print $6}'`
12443         if [ "$NOB" != "$BSIZE" ]; then
12444                 error "read $NOB bytes instead of $BSIZE"
12445         fi
12446         rm -f $DIR/$tfile
12447 }
12448 run_test 119a "Short directIO read must return actual read amount"
12449
12450 test_119b() # bug 11737
12451 {
12452         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
12453
12454         $LFS setstripe -c 2 $DIR/$tfile || error "setstripe failed"
12455         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=1 || error "dd failed"
12456         sync
12457         $MULTIOP $DIR/$tfile oO_RDONLY:O_DIRECT:r$((2048 * 1024)) ||
12458                 error "direct read failed"
12459         rm -f $DIR/$tfile
12460 }
12461 run_test 119b "Sparse directIO read must return actual read amount"
12462
12463 test_119c() # bug 13099
12464 {
12465         BSIZE=1048576
12466         directio write $DIR/$tfile 3 1 $BSIZE || error "direct write failed"
12467         directio readhole $DIR/$tfile 0 2 $BSIZE || error "reading hole failed"
12468         rm -f $DIR/$tfile
12469 }
12470 run_test 119c "Testing for direct read hitting hole"
12471
12472 test_119d() # bug 15950
12473 {
12474         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12475
12476         MAX_RPCS_IN_FLIGHT=`$LCTL get_param -n osc.*OST0000-osc-[^mM]*.max_rpcs_in_flight`
12477         $LCTL set_param -n osc.*OST0000-osc-[^mM]*.max_rpcs_in_flight 1
12478         BSIZE=1048576
12479         $LFS setstripe $DIR/$tfile -i 0 -c 1 || error "setstripe failed"
12480         $DIRECTIO write $DIR/$tfile 0 1 $BSIZE || error "first directio failed"
12481         #define OBD_FAIL_OSC_DIO_PAUSE           0x40d
12482         lctl set_param fail_loc=0x40d
12483         $DIRECTIO write $DIR/$tfile 1 4 $BSIZE &
12484         pid_dio=$!
12485         sleep 1
12486         cat $DIR/$tfile > /dev/null &
12487         lctl set_param fail_loc=0
12488         pid_reads=$!
12489         wait $pid_dio
12490         log "the DIO writes have completed, now wait for the reads (should not block very long)"
12491         sleep 2
12492         [ -n "`ps h -p $pid_reads -o comm`" ] && \
12493         error "the read rpcs have not completed in 2s"
12494         rm -f $DIR/$tfile
12495         $LCTL set_param -n osc.*OST0000-osc-[^mM]*.max_rpcs_in_flight $MAX_RPCS_IN_FLIGHT
12496 }
12497 run_test 119d "The DIO path should try to send a new rpc once one is completed"
12498
12499 test_120a() {
12500         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12501         remote_mds_nodsh && skip "remote MDS with nodsh"
12502         test_mkdir -i0 -c1 $DIR/$tdir
12503         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
12504                 skip_env "no early lock cancel on server"
12505
12506         lru_resize_disable mdc
12507         lru_resize_disable osc
12508         cancel_lru_locks mdc
12509         # asynchronous object destroy at MDT could cause bl ast to client
12510         cancel_lru_locks osc
12511
12512         stat $DIR/$tdir > /dev/null
12513         can1=$(do_facet mds1 \
12514                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12515                awk '/ldlm_cancel/ {print $2}')
12516         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12517                awk '/ldlm_bl_callback/ {print $2}')
12518         test_mkdir -i0 -c1 $DIR/$tdir/d1
12519         can2=$(do_facet mds1 \
12520                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12521                awk '/ldlm_cancel/ {print $2}')
12522         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12523                awk '/ldlm_bl_callback/ {print $2}')
12524         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
12525         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
12526         lru_resize_enable mdc
12527         lru_resize_enable osc
12528 }
12529 run_test 120a "Early Lock Cancel: mkdir test"
12530
12531 test_120b() {
12532         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12533         remote_mds_nodsh && skip "remote MDS with nodsh"
12534         test_mkdir $DIR/$tdir
12535         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
12536                 skip_env "no early lock cancel on server"
12537
12538         lru_resize_disable mdc
12539         lru_resize_disable osc
12540         cancel_lru_locks mdc
12541         stat $DIR/$tdir > /dev/null
12542         can1=$(do_facet $SINGLEMDS \
12543                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12544                awk '/ldlm_cancel/ {print $2}')
12545         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12546                awk '/ldlm_bl_callback/ {print $2}')
12547         touch $DIR/$tdir/f1
12548         can2=$(do_facet $SINGLEMDS \
12549                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12550                awk '/ldlm_cancel/ {print $2}')
12551         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12552                awk '/ldlm_bl_callback/ {print $2}')
12553         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
12554         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
12555         lru_resize_enable mdc
12556         lru_resize_enable osc
12557 }
12558 run_test 120b "Early Lock Cancel: create test"
12559
12560 test_120c() {
12561         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12562         remote_mds_nodsh && skip "remote MDS with nodsh"
12563         test_mkdir -i0 -c1 $DIR/$tdir
12564         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
12565                 skip "no early lock cancel on server"
12566
12567         lru_resize_disable mdc
12568         lru_resize_disable osc
12569         test_mkdir -i0 -c1 $DIR/$tdir/d1
12570         test_mkdir -i0 -c1 $DIR/$tdir/d2
12571         touch $DIR/$tdir/d1/f1
12572         cancel_lru_locks mdc
12573         stat $DIR/$tdir/d1 $DIR/$tdir/d2 $DIR/$tdir/d1/f1 > /dev/null
12574         can1=$(do_facet mds1 \
12575                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12576                awk '/ldlm_cancel/ {print $2}')
12577         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12578                awk '/ldlm_bl_callback/ {print $2}')
12579         ln $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2
12580         can2=$(do_facet mds1 \
12581                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12582                awk '/ldlm_cancel/ {print $2}')
12583         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12584                awk '/ldlm_bl_callback/ {print $2}')
12585         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
12586         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
12587         lru_resize_enable mdc
12588         lru_resize_enable osc
12589 }
12590 run_test 120c "Early Lock Cancel: link test"
12591
12592 test_120d() {
12593         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12594         remote_mds_nodsh && skip "remote MDS with nodsh"
12595         test_mkdir -i0 -c1 $DIR/$tdir
12596         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
12597                 skip_env "no early lock cancel on server"
12598
12599         lru_resize_disable mdc
12600         lru_resize_disable osc
12601         touch $DIR/$tdir
12602         cancel_lru_locks mdc
12603         stat $DIR/$tdir > /dev/null
12604         can1=$(do_facet mds1 \
12605                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12606                awk '/ldlm_cancel/ {print $2}')
12607         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12608                awk '/ldlm_bl_callback/ {print $2}')
12609         chmod a+x $DIR/$tdir
12610         can2=$(do_facet mds1 \
12611                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12612                awk '/ldlm_cancel/ {print $2}')
12613         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12614                awk '/ldlm_bl_callback/ {print $2}')
12615         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
12616         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
12617         lru_resize_enable mdc
12618         lru_resize_enable osc
12619 }
12620 run_test 120d "Early Lock Cancel: setattr test"
12621
12622 test_120e() {
12623         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12624         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
12625                 skip_env "no early lock cancel on server"
12626         remote_mds_nodsh && skip "remote MDS with nodsh"
12627
12628         local dlmtrace_set=false
12629
12630         test_mkdir -i0 -c1 $DIR/$tdir
12631         lru_resize_disable mdc
12632         lru_resize_disable osc
12633         ! $LCTL get_param debug | grep -q dlmtrace &&
12634                 $LCTL set_param debug=+dlmtrace && dlmtrace_set=true
12635         dd if=/dev/zero of=$DIR/$tdir/f1 count=1
12636         cancel_lru_locks mdc
12637         cancel_lru_locks osc
12638         dd if=$DIR/$tdir/f1 of=/dev/null
12639         stat $DIR/$tdir $DIR/$tdir/f1 > /dev/null
12640         # XXX client can not do early lock cancel of OST lock
12641         # during unlink (LU-4206), so cancel osc lock now.
12642         sleep 2
12643         cancel_lru_locks osc
12644         can1=$(do_facet mds1 \
12645                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12646                awk '/ldlm_cancel/ {print $2}')
12647         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12648                awk '/ldlm_bl_callback/ {print $2}')
12649         unlink $DIR/$tdir/f1
12650         sleep 5
12651         can2=$(do_facet mds1 \
12652                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12653                awk '/ldlm_cancel/ {print $2}')
12654         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12655                awk '/ldlm_bl_callback/ {print $2}')
12656         [ $can1 -ne $can2 ] && error "$((can2 - can1)) cancel RPC occured" &&
12657                 $LCTL dk $TMP/cancel.debug.txt
12658         [ $blk1 -ne $blk2 ] && error "$((blk2 - blk1)) blocking RPC occured" &&
12659                 $LCTL dk $TMP/blocking.debug.txt
12660         $dlmtrace_set && $LCTL set_param debug=-dlmtrace
12661         lru_resize_enable mdc
12662         lru_resize_enable osc
12663 }
12664 run_test 120e "Early Lock Cancel: unlink test"
12665
12666 test_120f() {
12667         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12668         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
12669                 skip_env "no early lock cancel on server"
12670         remote_mds_nodsh && skip "remote MDS with nodsh"
12671
12672         test_mkdir -i0 -c1 $DIR/$tdir
12673         lru_resize_disable mdc
12674         lru_resize_disable osc
12675         test_mkdir -i0 -c1 $DIR/$tdir/d1
12676         test_mkdir -i0 -c1 $DIR/$tdir/d2
12677         dd if=/dev/zero of=$DIR/$tdir/d1/f1 count=1
12678         dd if=/dev/zero of=$DIR/$tdir/d2/f2 count=1
12679         cancel_lru_locks mdc
12680         cancel_lru_locks osc
12681         dd if=$DIR/$tdir/d1/f1 of=/dev/null
12682         dd if=$DIR/$tdir/d2/f2 of=/dev/null
12683         stat $DIR/$tdir/d1 $DIR/$tdir/d2 $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2 > /dev/null
12684         # XXX client can not do early lock cancel of OST lock
12685         # during rename (LU-4206), so cancel osc lock now.
12686         sleep 2
12687         cancel_lru_locks osc
12688         can1=$(do_facet mds1 \
12689                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12690                awk '/ldlm_cancel/ {print $2}')
12691         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12692                awk '/ldlm_bl_callback/ {print $2}')
12693         mrename $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2
12694         sleep 5
12695         can2=$(do_facet mds1 \
12696                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12697                awk '/ldlm_cancel/ {print $2}')
12698         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12699                awk '/ldlm_bl_callback/ {print $2}')
12700         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
12701         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
12702         lru_resize_enable mdc
12703         lru_resize_enable osc
12704 }
12705 run_test 120f "Early Lock Cancel: rename test"
12706
12707 test_120g() {
12708         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12709         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
12710                 skip_env "no early lock cancel on server"
12711         remote_mds_nodsh && skip "remote MDS with nodsh"
12712
12713         lru_resize_disable mdc
12714         lru_resize_disable osc
12715         count=10000
12716         echo create $count files
12717         test_mkdir $DIR/$tdir
12718         cancel_lru_locks mdc
12719         cancel_lru_locks osc
12720         t0=$(date +%s)
12721
12722         can0=$(do_facet $SINGLEMDS \
12723                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12724                awk '/ldlm_cancel/ {print $2}')
12725         blk0=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12726                awk '/ldlm_bl_callback/ {print $2}')
12727         createmany -o $DIR/$tdir/f $count
12728         sync
12729         can1=$(do_facet $SINGLEMDS \
12730                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12731                awk '/ldlm_cancel/ {print $2}')
12732         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12733                awk '/ldlm_bl_callback/ {print $2}')
12734         t1=$(date +%s)
12735         echo total: $((can1-can0)) cancels, $((blk1-blk0)) blockings
12736         echo rm $count files
12737         rm -r $DIR/$tdir
12738         sync
12739         can2=$(do_facet $SINGLEMDS \
12740                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12741                awk '/ldlm_cancel/ {print $2}')
12742         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12743                awk '/ldlm_bl_callback/ {print $2}')
12744         t2=$(date +%s)
12745         echo total: $count removes in $((t2-t1))
12746         echo total: $((can2-can1)) cancels, $((blk2-blk1)) blockings
12747         sleep 2
12748         # wait for commitment of removal
12749         lru_resize_enable mdc
12750         lru_resize_enable osc
12751 }
12752 run_test 120g "Early Lock Cancel: performance test"
12753
12754 test_121() { #bug #10589
12755         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12756
12757         rm -rf $DIR/$tfile
12758         writes=$(LANG=C dd if=/dev/zero of=$DIR/$tfile count=1 2>&1 | awk -F '+' '/out$/ {print $1}')
12759 #define OBD_FAIL_LDLM_CANCEL_RACE        0x310
12760         lctl set_param fail_loc=0x310
12761         cancel_lru_locks osc > /dev/null
12762         reads=$(LANG=C dd if=$DIR/$tfile of=/dev/null 2>&1 | awk -F '+' '/in$/ {print $1}')
12763         lctl set_param fail_loc=0
12764         [[ $reads -eq $writes ]] ||
12765                 error "read $reads blocks, must be $writes blocks"
12766 }
12767 run_test 121 "read cancel race ========="
12768
12769 test_123a_base() { # was test 123, statahead(bug 11401)
12770         local lsx="$1"
12771
12772         SLOWOK=0
12773         if ! grep -q "processor.*: 1" /proc/cpuinfo; then
12774                 log "testing UP system. Performance may be lower than expected."
12775                 SLOWOK=1
12776         fi
12777
12778         rm -rf $DIR/$tdir
12779         test_mkdir $DIR/$tdir
12780         NUMFREE=$(df -i -P $DIR | tail -n 1 | awk '{ print $4 }')
12781         [[ $NUMFREE -gt 100000 ]] && NUMFREE=100000 || NUMFREE=$((NUMFREE-1000))
12782         MULT=10
12783         for ((i=100, j=0; i<=$NUMFREE; j=$i, i=$((i * MULT)) )); do
12784                 createmany -o $DIR/$tdir/$tfile $j $((i - j))
12785
12786                 max=$(lctl get_param -n llite.*.statahead_max | head -n 1)
12787                 lctl set_param -n llite.*.statahead_max 0
12788                 lctl get_param llite.*.statahead_max
12789                 cancel_lru_locks mdc
12790                 cancel_lru_locks osc
12791                 stime=$(date +%s)
12792                 time $lsx $DIR/$tdir | wc -l
12793                 etime=$(date +%s)
12794                 delta=$((etime - stime))
12795                 log "$lsx $i files without statahead: $delta sec"
12796                 lctl set_param llite.*.statahead_max=$max
12797
12798                 swrong=$(lctl get_param -n llite.*.statahead_stats |
12799                         grep "statahead wrong:" | awk '{print $3}')
12800                 lctl get_param -n llite.*.statahead_max | grep '[0-9]'
12801                 cancel_lru_locks mdc
12802                 cancel_lru_locks osc
12803                 stime=$(date +%s)
12804                 time $lsx $DIR/$tdir | wc -l
12805                 etime=$(date +%s)
12806                 delta_sa=$((etime - stime))
12807                 log "$lsx $i files with statahead: $delta_sa sec"
12808                 lctl get_param -n llite.*.statahead_stats
12809                 ewrong=$(lctl get_param -n llite.*.statahead_stats |
12810                         grep "statahead wrong:" | awk '{print $3}')
12811
12812                 [[ $swrong -lt $ewrong ]] &&
12813                         log "statahead was stopped, maybe too many locks held!"
12814                 [[ $delta -eq 0 || $delta_sa -eq 0 ]] && continue
12815
12816                 if [ $((delta_sa * 100)) -gt $((delta * 105)) -a $delta_sa -gt $((delta + 2)) ]; then
12817                         max=$(lctl get_param -n llite.*.statahead_max |
12818                                 head -n 1)
12819                         lctl set_param -n llite.*.statahead_max 0
12820                         lctl get_param llite.*.statahead_max
12821                         cancel_lru_locks mdc
12822                         cancel_lru_locks osc
12823                         stime=$(date +%s)
12824                         time $lsx $DIR/$tdir | wc -l
12825                         etime=$(date +%s)
12826                         delta=$((etime - stime))
12827                         log "$lsx $i files again without statahead: $delta sec"
12828                         lctl set_param llite.*.statahead_max=$max
12829                         if [ $((delta_sa * 100 > delta * 105 && delta_sa > delta + 2)) ]; then
12830                                 if [  $SLOWOK -eq 0 ]; then
12831                                         error "$lsx $i files is slower with statahead!"
12832                                 else
12833                                         log "$lsx $i files is slower with statahead!"
12834                                 fi
12835                                 break
12836                         fi
12837                 fi
12838
12839                 [ $delta -gt 20 ] && break
12840                 [ $delta -gt 8 ] && MULT=$((50 / delta))
12841                 [ "$SLOW" = "no" -a $delta -gt 5 ] && break
12842         done
12843         log "$lsx done"
12844
12845         stime=$(date +%s)
12846         rm -r $DIR/$tdir
12847         sync
12848         etime=$(date +%s)
12849         delta=$((etime - stime))
12850         log "rm -r $DIR/$tdir/: $delta seconds"
12851         log "rm done"
12852         lctl get_param -n llite.*.statahead_stats
12853 }
12854
12855 test_123aa() {
12856         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12857
12858         test_123a_base "ls -l"
12859 }
12860 run_test 123aa "verify statahead work"
12861
12862 test_123ab() {
12863         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12864
12865         statx_supported || skip_env "Test must be statx() syscall supported"
12866
12867         test_123a_base "$STATX -l"
12868 }
12869 run_test 123ab "verify statahead work by using statx"
12870
12871 test_123ac() {
12872         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12873
12874         statx_supported || skip_env "Test must be statx() syscall supported"
12875
12876         local rpcs_before
12877         local rpcs_after
12878         local agl_before
12879         local agl_after
12880
12881         cancel_lru_locks $OSC
12882         rpcs_before=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
12883         agl_before=$($LCTL get_param -n llite.*.statahead_stats |
12884                 awk '/agl.total:/ {print $3}')
12885         test_123a_base "$STATX -c \"%n %i %A %h %u %g %W %X %Z\" -D"
12886         test_123a_base "$STATX --cached=always -D"
12887         agl_after=$($LCTL get_param -n llite.*.statahead_stats |
12888                 awk '/agl.total:/ {print $3}')
12889         [ $agl_before -eq $agl_after ] ||
12890                 error "Should not trigger AGL thread - $agl_before:$agl_after"
12891         rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
12892         [ $rpcs_after -eq $rpcs_before ] ||
12893                 error "$STATX should not send glimpse RPCs to $OSC"
12894 }
12895 run_test 123ac "verify statahead work by using statx without glimpse RPCs"
12896
12897 test_123b () { # statahead(bug 15027)
12898         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12899
12900         test_mkdir $DIR/$tdir
12901         createmany -o $DIR/$tdir/$tfile-%d 1000
12902
12903         cancel_lru_locks mdc
12904         cancel_lru_locks osc
12905
12906 #define OBD_FAIL_MDC_GETATTR_ENQUEUE     0x803
12907         lctl set_param fail_loc=0x80000803
12908         ls -lR $DIR/$tdir > /dev/null
12909         log "ls done"
12910         lctl set_param fail_loc=0x0
12911         lctl get_param -n llite.*.statahead_stats
12912         rm -r $DIR/$tdir
12913         sync
12914
12915 }
12916 run_test 123b "not panic with network error in statahead enqueue (bug 15027)"
12917
12918 test_123c() {
12919         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
12920
12921         test_mkdir -i 0 -c 1 $DIR/$tdir.0
12922         test_mkdir -i 1 -c 1 $DIR/$tdir.1
12923         touch $DIR/$tdir.1/{1..3}
12924         mv $DIR/$tdir.1/{1..3} $DIR/$tdir.0
12925
12926         remount_client $MOUNT
12927
12928         $MULTIOP $DIR/$tdir.0 Q
12929
12930         # let statahead to complete
12931         ls -l $DIR/$tdir.0 > /dev/null
12932
12933         testid=$(echo $TESTNAME | tr '_' ' ')
12934         dmesg | tac | sed "/$testid/,$ d" | grep "Can not initialize inode" &&
12935                 error "statahead warning" || true
12936 }
12937 run_test 123c "Can not initialize inode warning on DNE statahead"
12938
12939 test_124a() {
12940         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12941         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
12942                 skip_env "no lru resize on server"
12943
12944         local NR=2000
12945
12946         test_mkdir $DIR/$tdir
12947
12948         log "create $NR files at $DIR/$tdir"
12949         createmany -o $DIR/$tdir/f $NR ||
12950                 error "failed to create $NR files in $DIR/$tdir"
12951
12952         cancel_lru_locks mdc
12953         ls -l $DIR/$tdir > /dev/null
12954
12955         local NSDIR=""
12956         local LRU_SIZE=0
12957         for VALUE in $($LCTL get_param ldlm.namespaces.*mdc-*.lru_size); do
12958                 local PARAM=$(echo ${VALUE[0]} | cut -d "=" -f1)
12959                 LRU_SIZE=$($LCTL get_param -n $PARAM)
12960                 if [[ $LRU_SIZE -gt $(default_lru_size) ]]; then
12961                         NSDIR=$(echo $PARAM | cut -d "." -f1-3)
12962                         log "NSDIR=$NSDIR"
12963                         log "NS=$(basename $NSDIR)"
12964                         break
12965                 fi
12966         done
12967
12968         if [[ -z "$NSDIR" || $LRU_SIZE -lt $(default_lru_size) ]]; then
12969                 skip "Not enough cached locks created!"
12970         fi
12971         log "LRU=$LRU_SIZE"
12972
12973         local SLEEP=30
12974
12975         # We know that lru resize allows one client to hold $LIMIT locks
12976         # for 10h. After that locks begin to be killed by client.
12977         local MAX_HRS=10
12978         local LIMIT=$($LCTL get_param -n $NSDIR.pool.limit)
12979         log "LIMIT=$LIMIT"
12980         if [ $LIMIT -lt $LRU_SIZE ]; then
12981                 skip "Limit is too small $LIMIT"
12982         fi
12983
12984         # Make LVF so higher that sleeping for $SLEEP is enough to _start_
12985         # killing locks. Some time was spent for creating locks. This means
12986         # that up to the moment of sleep finish we must have killed some of
12987         # them (10-100 locks). This depends on how fast ther were created.
12988         # Many of them were touched in almost the same moment and thus will
12989         # be killed in groups.
12990         local LVF=$(($MAX_HRS * 60 * 60 / $SLEEP * $LIMIT / $LRU_SIZE * 100))
12991
12992         # Use $LRU_SIZE_B here to take into account real number of locks
12993         # created in the case of CMD, LRU_SIZE_B != $NR in most of cases
12994         local LRU_SIZE_B=$LRU_SIZE
12995         log "LVF=$LVF"
12996         local OLD_LVF=$($LCTL get_param -n $NSDIR.pool.lock_volume_factor)
12997         log "OLD_LVF=$OLD_LVF"
12998         $LCTL set_param -n $NSDIR.pool.lock_volume_factor $LVF
12999
13000         # Let's make sure that we really have some margin. Client checks
13001         # cached locks every 10 sec.
13002         SLEEP=$((SLEEP+20))
13003         log "Sleep ${SLEEP} sec"
13004         local SEC=0
13005         while ((SEC<$SLEEP)); do
13006                 echo -n "..."
13007                 sleep 5
13008                 SEC=$((SEC+5))
13009                 LRU_SIZE=$($LCTL get_param -n $NSDIR/lru_size)
13010                 echo -n "$LRU_SIZE"
13011         done
13012         echo ""
13013         $LCTL set_param -n $NSDIR.pool.lock_volume_factor $OLD_LVF
13014         local LRU_SIZE_A=$($LCTL get_param -n $NSDIR.lru_size)
13015
13016         [[ $LRU_SIZE_B -gt $LRU_SIZE_A ]] || {
13017                 error "No locks dropped in ${SLEEP}s. LRU size: $LRU_SIZE_A"
13018                 unlinkmany $DIR/$tdir/f $NR
13019                 return
13020         }
13021
13022         log "Dropped "$((LRU_SIZE_B-LRU_SIZE_A))" locks in ${SLEEP}s"
13023         log "unlink $NR files at $DIR/$tdir"
13024         unlinkmany $DIR/$tdir/f $NR
13025 }
13026 run_test 124a "lru resize ======================================="
13027
13028 get_max_pool_limit()
13029 {
13030         local limit=$($LCTL get_param \
13031                       -n ldlm.namespaces.*-MDT0000-mdc-*.pool.limit)
13032         local max=0
13033         for l in $limit; do
13034                 if [[ $l -gt $max ]]; then
13035                         max=$l
13036                 fi
13037         done
13038         echo $max
13039 }
13040
13041 test_124b() {
13042         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13043         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
13044                 skip_env "no lru resize on server"
13045
13046         LIMIT=$(get_max_pool_limit)
13047
13048         NR=$(($(default_lru_size)*20))
13049         if [[ $NR -gt $LIMIT ]]; then
13050                 log "Limit lock number by $LIMIT locks"
13051                 NR=$LIMIT
13052         fi
13053
13054         IFree=$(mdsrate_inodes_available)
13055         if [ $IFree -lt $NR ]; then
13056                 log "Limit lock number by $IFree inodes"
13057                 NR=$IFree
13058         fi
13059
13060         lru_resize_disable mdc
13061         test_mkdir -p $DIR/$tdir/disable_lru_resize
13062
13063         createmany -o $DIR/$tdir/disable_lru_resize/f $NR
13064         log "doing ls -la $DIR/$tdir/disable_lru_resize 3 times"
13065         cancel_lru_locks mdc
13066         stime=`date +%s`
13067         PID=""
13068         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
13069         PID="$PID $!"
13070         sleep 2
13071         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
13072         PID="$PID $!"
13073         sleep 2
13074         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
13075         PID="$PID $!"
13076         wait $PID
13077         etime=`date +%s`
13078         nolruresize_delta=$((etime-stime))
13079         log "ls -la time: $nolruresize_delta seconds"
13080         log "lru_size = $(lctl get_param -n ldlm.namespaces.*mdc*.lru_size)"
13081         unlinkmany $DIR/$tdir/disable_lru_resize/f $NR
13082
13083         lru_resize_enable mdc
13084         test_mkdir -p $DIR/$tdir/enable_lru_resize
13085
13086         createmany -o $DIR/$tdir/enable_lru_resize/f $NR
13087         log "doing ls -la $DIR/$tdir/enable_lru_resize 3 times"
13088         cancel_lru_locks mdc
13089         stime=`date +%s`
13090         PID=""
13091         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
13092         PID="$PID $!"
13093         sleep 2
13094         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
13095         PID="$PID $!"
13096         sleep 2
13097         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
13098         PID="$PID $!"
13099         wait $PID
13100         etime=`date +%s`
13101         lruresize_delta=$((etime-stime))
13102         log "ls -la time: $lruresize_delta seconds"
13103         log "lru_size = $(lctl get_param -n ldlm.namespaces.*mdc*.lru_size)"
13104
13105         if [ $lruresize_delta -gt $nolruresize_delta ]; then
13106                 log "ls -la is $(((lruresize_delta - $nolruresize_delta) * 100 / $nolruresize_delta))% slower with lru resize enabled"
13107         elif [ $nolruresize_delta -gt $lruresize_delta ]; then
13108                 log "ls -la is $(((nolruresize_delta - $lruresize_delta) * 100 / $nolruresize_delta))% faster with lru resize enabled"
13109         else
13110                 log "lru resize performs the same with no lru resize"
13111         fi
13112         unlinkmany $DIR/$tdir/enable_lru_resize/f $NR
13113 }
13114 run_test 124b "lru resize (performance test) ======================="
13115
13116 test_124c() {
13117         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13118         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
13119                 skip_env "no lru resize on server"
13120
13121         # cache ununsed locks on client
13122         local nr=100
13123         cancel_lru_locks mdc
13124         test_mkdir $DIR/$tdir
13125         createmany -o $DIR/$tdir/f $nr ||
13126                 error "failed to create $nr files in $DIR/$tdir"
13127         ls -l $DIR/$tdir > /dev/null
13128
13129         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
13130         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
13131         local max_age=$($LCTL get_param -n $nsdir.lru_max_age)
13132         local recalc_p=$($LCTL get_param -n $nsdir.pool.recalc_period)
13133         echo "unused=$unused, max_age=$max_age, recalc_p=$recalc_p"
13134
13135         # set lru_max_age to 1 sec
13136         $LCTL set_param $nsdir.lru_max_age=1000 # milliseconds
13137         echo "sleep $((recalc_p * 2)) seconds..."
13138         sleep $((recalc_p * 2))
13139
13140         local remaining=$($LCTL get_param -n $nsdir.lock_unused_count)
13141         # restore lru_max_age
13142         $LCTL set_param -n $nsdir.lru_max_age $max_age
13143         [ $remaining -eq 0 ] || error "$remaining locks are not canceled"
13144         unlinkmany $DIR/$tdir/f $nr
13145 }
13146 run_test 124c "LRUR cancel very aged locks"
13147
13148 test_124d() {
13149         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13150         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
13151                 skip_env "no lru resize on server"
13152
13153         # cache ununsed locks on client
13154         local nr=100
13155
13156         lru_resize_disable mdc
13157         stack_trap "lru_resize_enable mdc" EXIT
13158
13159         cancel_lru_locks mdc
13160
13161         # asynchronous object destroy at MDT could cause bl ast to client
13162         test_mkdir $DIR/$tdir
13163         createmany -o $DIR/$tdir/f $nr ||
13164                 error "failed to create $nr files in $DIR/$tdir"
13165         stack_trap "unlinkmany $DIR/$tdir/f $nr" EXIT
13166
13167         ls -l $DIR/$tdir > /dev/null
13168
13169         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
13170         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
13171         local max_age=$($LCTL get_param -n $nsdir.lru_max_age)
13172         local recalc_p=$($LCTL get_param -n $nsdir.pool.recalc_period)
13173
13174         echo "unused=$unused, max_age=$max_age, recalc_p=$recalc_p"
13175
13176         # set lru_max_age to 1 sec
13177         $LCTL set_param $nsdir.lru_max_age=1000 # milliseconds
13178         stack_trap "$LCTL set_param -n $nsdir.lru_max_age $max_age" EXIT
13179
13180         echo "sleep $((recalc_p * 2)) seconds..."
13181         sleep $((recalc_p * 2))
13182
13183         local remaining=$($LCTL get_param -n $nsdir.lock_unused_count)
13184
13185         [ $remaining -eq 0 ] || error "$remaining locks are not canceled"
13186 }
13187 run_test 124d "cancel very aged locks if lru-resize diasbaled"
13188
13189 test_125() { # 13358
13190         $LCTL get_param -n llite.*.client_type | grep -q local ||
13191                 skip "must run as local client"
13192         $LCTL get_param -n mdc.*-mdc-*.connect_flags | grep -q acl ||
13193                 skip_env "must have acl enabled"
13194         [ -z "$(which setfacl)" ] && skip_env "must have setfacl tool"
13195
13196         test_mkdir $DIR/$tdir
13197         $LFS setstripe -S 65536 -c -1 $DIR/$tdir || error "setstripe failed"
13198         setfacl -R -m u:bin:rwx $DIR/$tdir || error "setfacl $DIR/$tdir failed"
13199         ls -ld $DIR/$tdir || error "cannot access $DIR/$tdir"
13200 }
13201 run_test 125 "don't return EPROTO when a dir has a non-default striping and ACLs"
13202
13203 test_126() { # bug 12829/13455
13204         $GSS && skip_env "must run as gss disabled"
13205         $LCTL get_param -n llite.*.client_type | grep -q local ||
13206                 skip "must run as local client"
13207         [ "$UID" != 0 ] && skip "must run as root, not UID $UID"
13208
13209         $RUNAS -u 0 -g 1 touch $DIR/$tfile || error "touch failed"
13210         gid=`ls -n $DIR/$tfile | awk '{print $4}'`
13211         rm -f $DIR/$tfile
13212         [ $gid -eq "1" ] || error "gid is set to" $gid "instead of 1"
13213 }
13214 run_test 126 "check that the fsgid provided by the client is taken into account"
13215
13216 test_127a() { # bug 15521
13217         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13218         local name count samp unit min max sum sumsq
13219
13220         $LFS setstripe -i 0 -c 1 $DIR/$tfile || error "setstripe failed"
13221         echo "stats before reset"
13222         $LCTL get_param osc.*.stats
13223         $LCTL set_param osc.*.stats=0
13224         local fsize=$((2048 * 1024))
13225
13226         dd if=/dev/zero of=$DIR/$tfile bs=$fsize count=1
13227         cancel_lru_locks osc
13228         dd if=$DIR/$tfile of=/dev/null bs=$fsize
13229
13230         $LCTL get_param osc.*0000-osc-*.stats | grep samples > $DIR/$tfile.tmp
13231         stack_trap "rm -f $TMP/$tfile.tmp"
13232         while read name count samp unit min max sum sumsq; do
13233                 echo "got name=$name count=$count unit=$unit min=$min max=$max"
13234                 [ ! $min ] && error "Missing min value for $name proc entry"
13235                 eval $name=$count || error "Wrong proc format"
13236
13237                 case $name in
13238                 read_bytes|write_bytes)
13239                         [[ "$unit" =~ "bytes" ]] ||
13240                                 error "unit is not 'bytes': $unit"
13241                         (( $min >= 4096 )) || error "min is too small: $min"
13242                         (( $min <= $fsize )) || error "min is too big: $min"
13243                         (( $max >= 4096 )) || error "max is too small: $max"
13244                         (( $max <= $fsize )) || error "max is too big: $max"
13245                         (( $sum == $fsize )) || error "sum is wrong: $sum"
13246                         (( $sumsq >= ($fsize / 4096) * (4096 * 4096) )) ||
13247                                 error "sumsquare is too small: $sumsq"
13248                         (( $sumsq <= $fsize * $fsize )) ||
13249                                 error "sumsquare is too big: $sumsq"
13250                         ;;
13251                 ost_read|ost_write)
13252                         [[ "$unit" =~ "usec" ]] ||
13253                                 error "unit is not 'usec': $unit"
13254                         ;;
13255                 *)      ;;
13256                 esac
13257         done < $DIR/$tfile.tmp
13258
13259         #check that we actually got some stats
13260         [ "$read_bytes" ] || error "Missing read_bytes stats"
13261         [ "$write_bytes" ] || error "Missing write_bytes stats"
13262         [ "$read_bytes" != 0 ] || error "no read done"
13263         [ "$write_bytes" != 0 ] || error "no write done"
13264 }
13265 run_test 127a "verify the client stats are sane"
13266
13267 test_127b() { # bug LU-333
13268         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13269         local name count samp unit min max sum sumsq
13270
13271         echo "stats before reset"
13272         $LCTL get_param llite.*.stats
13273         $LCTL set_param llite.*.stats=0
13274
13275         # perform 2 reads and writes so MAX is different from SUM.
13276         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1
13277         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1
13278         cancel_lru_locks osc
13279         dd if=$DIR/$tfile of=/dev/null bs=$PAGE_SIZE count=1
13280         dd if=$DIR/$tfile of=/dev/null bs=$PAGE_SIZE count=1
13281
13282         $LCTL get_param llite.*.stats | grep samples > $TMP/$tfile.tmp
13283         stack_trap "rm -f $TMP/$tfile.tmp"
13284         while read name count samp unit min max sum sumsq; do
13285                 echo "got name=$name count=$count unit=$unit min=$min max=$max"
13286                 eval $name=$count || error "Wrong proc format"
13287
13288                 case $name in
13289                 read_bytes|write_bytes)
13290                         [[ "$unit" =~ "bytes" ]] ||
13291                                 error "unit is not 'bytes': $unit"
13292                         (( $count == 2 )) || error "count is not 2: $count"
13293                         (( $min == $PAGE_SIZE )) ||
13294                                 error "min is not $PAGE_SIZE: $min"
13295                         (( $max == $PAGE_SIZE )) ||
13296                                 error "max is not $PAGE_SIZE: $max"
13297                         (( $sum == $PAGE_SIZE * 2 )) ||
13298                                 error "sum is not $((PAGE_SIZE * 2)): $sum"
13299                         ;;
13300                 read|write)
13301                         [[ "$unit" =~ "usec" ]] ||
13302                                 error "unit is not 'usec': $unit"
13303                         ;;
13304                 *)      ;;
13305                 esac
13306         done < $TMP/$tfile.tmp
13307
13308         #check that we actually got some stats
13309         [ "$read_bytes" ] || error "Missing read_bytes stats"
13310         [ "$write_bytes" ] || error "Missing write_bytes stats"
13311         [ "$read_bytes" != 0 ] || error "no read done"
13312         [ "$write_bytes" != 0 ] || error "no write done"
13313 }
13314 run_test 127b "verify the llite client stats are sane"
13315
13316 test_127c() { # LU-12394
13317         [ "$OSTCOUNT" -lt "2" ] && skip_env "needs >= 2 OSTs"
13318         local size
13319         local bsize
13320         local reads
13321         local writes
13322         local count
13323
13324         $LCTL set_param llite.*.extents_stats=1
13325         stack_trap "$LCTL set_param llite.*.extents_stats=0" EXIT
13326
13327         # Use two stripes so there is enough space in default config
13328         $LFS setstripe -c 2 $DIR/$tfile
13329
13330         # Extent stats start at 0-4K and go in power of two buckets
13331         # LL_HIST_START = 12 --> 2^12 = 4K
13332         # We do 3K*2^i, so 3K, 6K, 12K, 24K... hitting each bucket.
13333         # We do not do buckets larger than 64 MiB to avoid ENOSPC issues on
13334         # small configs
13335         for size in 3K 6K 12K 24K 48K 96K 192K 384K 768K 1536K 3M 6M 12M 24M 48M;
13336                 do
13337                 # Write and read, 2x each, second time at a non-zero offset
13338                 dd if=/dev/zero of=$DIR/$tfile bs=$size count=1
13339                 dd if=/dev/zero of=$DIR/$tfile bs=$size count=1 seek=10
13340                 dd if=$DIR/$tfile of=/dev/null bs=$size count=1
13341                 dd if=$DIR/$tfile of=/dev/null bs=$size count=1 seek=10
13342                 rm -f $DIR/$tfile
13343         done
13344
13345         $LCTL get_param llite.*.extents_stats
13346
13347         count=2
13348         for bsize in 4K 8K 16K 32K 64K 128K 256K 512K 1M 2M 4M 8M 16M 32M 64M;
13349                 do
13350                 local bucket=$($LCTL get_param -n llite.*.extents_stats |
13351                                 grep -m 1 $bsize)
13352                 reads=$(echo $bucket | awk '{print $5}')
13353                 writes=$(echo $bucket | awk '{print $9}')
13354                 [ "$reads" -eq $count ] ||
13355                         error "$reads reads in < $bsize bucket, expect $count"
13356                 [ "$writes" -eq $count ] ||
13357                         error "$writes writes in < $bsize bucket, expect $count"
13358         done
13359
13360         # Test mmap write and read
13361         $LCTL set_param llite.*.extents_stats=c
13362         size=512
13363         dd if=/dev/zero of=$DIR/$tfile bs=${size}K count=1
13364         $MULTIOP $DIR/$tfile OSMRUc || error "$MULTIOP $DIR/$tfile failed"
13365         $MULTIOP $DIR/$tfile OSMWUc || error "$MULTIOP $DIR/$tfile failed"
13366
13367         $LCTL get_param llite.*.extents_stats
13368
13369         count=$(((size*1024) / PAGE_SIZE))
13370
13371         bsize=$((2 * PAGE_SIZE / 1024))K
13372
13373         bucket=$($LCTL get_param -n llite.*.extents_stats |
13374                         grep -m 1 $bsize)
13375         reads=$(echo $bucket | awk '{print $5}')
13376         writes=$(echo $bucket | awk '{print $9}')
13377         # mmap writes fault in the page first, creating an additonal read
13378         [ "$reads" -eq $((2 * count)) ] ||
13379                 error "$reads reads in < $bsize bucket, expect $count"
13380         [ "$writes" -eq $count ] ||
13381                 error "$writes writes in < $bsize bucket, expect $count"
13382 }
13383 run_test 127c "test llite extent stats with regular & mmap i/o"
13384
13385 test_128() { # bug 15212
13386         touch $DIR/$tfile
13387         $LFS 2>&1 <<-EOF | tee $TMP/$tfile.log
13388                 find $DIR/$tfile
13389                 find $DIR/$tfile
13390         EOF
13391
13392         result=$(grep error $TMP/$tfile.log)
13393         rm -f $DIR/$tfile $TMP/$tfile.log
13394         [ -z "$result" ] ||
13395                 error "consecutive find's under interactive lfs failed"
13396 }
13397 run_test 128 "interactive lfs for 2 consecutive find's"
13398
13399 set_dir_limits () {
13400         local mntdev
13401         local canondev
13402         local node
13403
13404         local ldproc=/proc/fs/ldiskfs
13405         local facets=$(get_facets MDS)
13406
13407         for facet in ${facets//,/ }; do
13408                 canondev=$(ldiskfs_canon \
13409                            *.$(convert_facet2label $facet).mntdev $facet)
13410                 do_facet $facet "test -e $ldproc/$canondev/max_dir_size" ||
13411                         ldproc=/sys/fs/ldiskfs
13412                 do_facet $facet "echo $1 >$ldproc/$canondev/max_dir_size"
13413                 do_facet $facet "echo $2 >$ldproc/$canondev/warning_dir_size"
13414         done
13415 }
13416
13417 check_mds_dmesg() {
13418         local facets=$(get_facets MDS)
13419         for facet in ${facets//,/ }; do
13420                 do_facet $facet "dmesg | tail -3 | grep $1" && return 0
13421         done
13422         return 1
13423 }
13424
13425 test_129() {
13426         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13427         [[ $MDS1_VERSION -ge $(version_code 2.5.56) ]] ||
13428                 skip "Need MDS version with at least 2.5.56"
13429         if [ "$mds1_FSTYPE" != ldiskfs ]; then
13430                 skip_env "ldiskfs only test"
13431         fi
13432         remote_mds_nodsh && skip "remote MDS with nodsh"
13433
13434         local ENOSPC=28
13435         local has_warning=false
13436
13437         rm -rf $DIR/$tdir
13438         mkdir -p $DIR/$tdir
13439
13440         # block size of mds1
13441         local maxsize=$(($($LCTL get_param -n mdc.*MDT0000*.blocksize) * 8))
13442         set_dir_limits $maxsize $((maxsize * 6 / 8))
13443         stack_trap "set_dir_limits 0 0"
13444         stack_trap "unlinkmany $DIR/$tdir/file_base_ 2000 || true"
13445         local dirsize=$(stat -c%s "$DIR/$tdir")
13446         local nfiles=0
13447         while (( $dirsize <= $maxsize )); do
13448                 $MCREATE $DIR/$tdir/file_base_$nfiles
13449                 rc=$?
13450                 # check two errors:
13451                 # ENOSPC for ext4 max_dir_size, which has been used since
13452                 # kernel v3.6-rc1-8-gdf981d03ee, lustre v2_4_50_0-79-gaed82035c0
13453                 if (( rc == ENOSPC )); then
13454                         set_dir_limits 0 0
13455                         echo "rc=$rc returned as expected after $nfiles files"
13456
13457                         createmany -o $DIR/$tdir/file_extra_$nfiles. 5 ||
13458                                 error "create failed w/o dir size limit"
13459
13460                         # messages may be rate limited if test is run repeatedly
13461                         check_mds_dmesg '"is approaching max"' ||
13462                                 echo "warning message should be output"
13463                         check_mds_dmesg '"has reached max"' ||
13464                                 echo "reached message should be output"
13465
13466                         dirsize=$(stat -c%s "$DIR/$tdir")
13467
13468                         [[ $dirsize -ge $maxsize ]] && return 0
13469                         error "dirsize $dirsize < $maxsize after $nfiles files"
13470                 elif (( rc != 0 )); then
13471                         break
13472                 fi
13473                 nfiles=$((nfiles + 1))
13474                 dirsize=$(stat -c%s "$DIR/$tdir")
13475         done
13476
13477         error "rc=$rc, size=$dirsize/$maxsize, mdt=$MDSCOUNT, nfiles=$nfiles"
13478 }
13479 run_test 129 "test directory size limit ========================"
13480
13481 OLDIFS="$IFS"
13482 cleanup_130() {
13483         trap 0
13484         IFS="$OLDIFS"
13485 }
13486
13487 test_130a() {
13488         local filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
13489         [ -n "$filefrag_op" ] && skip_env "filefrag does not support FIEMAP"
13490
13491         trap cleanup_130 EXIT RETURN
13492
13493         local fm_file=$DIR/$tfile
13494         $LFS setstripe -S 65536 -c 1 $fm_file || error "setstripe on $fm_file"
13495         dd if=/dev/zero of=$fm_file bs=65536 count=1 ||
13496                 error "dd failed for $fm_file"
13497
13498         # LU-1795: test filefrag/FIEMAP once, even if unsupported
13499         filefrag -ves $fm_file
13500         RC=$?
13501         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
13502                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
13503         [ $RC != 0 ] && error "filefrag $fm_file failed"
13504
13505         filefrag_op=$(filefrag -ve -k $fm_file |
13506                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
13507         lun=$($LFS getstripe -i $fm_file)
13508
13509         start_blk=`echo $filefrag_op | cut -d: -f2 | cut -d. -f1`
13510         IFS=$'\n'
13511         tot_len=0
13512         for line in $filefrag_op
13513         do
13514                 frag_lun=`echo $line | cut -d: -f5`
13515                 ext_len=`echo $line | cut -d: -f4`
13516                 if (( $frag_lun != $lun )); then
13517                         cleanup_130
13518                         error "FIEMAP on 1-stripe file($fm_file) failed"
13519                         return
13520                 fi
13521                 (( tot_len += ext_len ))
13522         done
13523
13524         if (( lun != frag_lun || start_blk != 0 || tot_len != 64 )); then
13525                 cleanup_130
13526                 error "FIEMAP on 1-stripe file($fm_file) failed;"
13527                 return
13528         fi
13529
13530         cleanup_130
13531
13532         echo "FIEMAP on single striped file succeeded"
13533 }
13534 run_test 130a "FIEMAP (1-stripe file)"
13535
13536 test_130b() {
13537         [ "$OSTCOUNT" -lt "2" ] && skip_env "needs >= 2 OSTs"
13538
13539         local filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
13540         [ -n "$filefrag_op" ] && skip_env "filefrag does not support FIEMAP"
13541
13542         trap cleanup_130 EXIT RETURN
13543
13544         local fm_file=$DIR/$tfile
13545         $LFS setstripe -S 65536 -c $OSTCOUNT $fm_file ||
13546                         error "setstripe on $fm_file"
13547         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
13548                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
13549
13550         dd if=/dev/zero of=$fm_file bs=1M count=$OSTCOUNT ||
13551                 error "dd failed on $fm_file"
13552
13553         filefrag -ves $fm_file || error "filefrag $fm_file failed"
13554         filefrag_op=$(filefrag -ve -k $fm_file |
13555                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
13556
13557         last_lun=$(echo $filefrag_op | cut -d: -f5 |
13558                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
13559
13560         IFS=$'\n'
13561         tot_len=0
13562         num_luns=1
13563         for line in $filefrag_op
13564         do
13565                 frag_lun=$(echo $line | cut -d: -f5 |
13566                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
13567                 ext_len=$(echo $line | cut -d: -f4)
13568                 if (( $frag_lun != $last_lun )); then
13569                         if (( tot_len != 1024 )); then
13570                                 cleanup_130
13571                                 error "FIEMAP on $fm_file failed; returned " \
13572                                 "len $tot_len for OST $last_lun instead of 1024"
13573                                 return
13574                         else
13575                                 (( num_luns += 1 ))
13576                                 tot_len=0
13577                         fi
13578                 fi
13579                 (( tot_len += ext_len ))
13580                 last_lun=$frag_lun
13581         done
13582         if (( num_luns != $OSTCOUNT || tot_len != 1024 )); then
13583                 cleanup_130
13584                 error "FIEMAP on $fm_file failed; returned wrong number of " \
13585                         "luns or wrong len for OST $last_lun"
13586                 return
13587         fi
13588
13589         cleanup_130
13590
13591         echo "FIEMAP on $OSTCOUNT-stripe file succeeded"
13592 }
13593 run_test 130b "FIEMAP ($OSTCOUNT-stripe file)"
13594
13595 test_130c() {
13596         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
13597
13598         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
13599         [ -n "$filefrag_op" ] && skip "filefrag does not support FIEMAP"
13600
13601         trap cleanup_130 EXIT RETURN
13602
13603         local fm_file=$DIR/$tfile
13604         $LFS setstripe -S 65536 -c 2 $fm_file || error "setstripe on $fm_file"
13605         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
13606                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
13607
13608         dd if=/dev/zero of=$fm_file seek=1 bs=1M count=1 ||
13609                         error "dd failed on $fm_file"
13610
13611         filefrag -ves $fm_file || error "filefrag $fm_file failed"
13612         filefrag_op=$(filefrag -ve -k $fm_file |
13613                 sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
13614
13615         last_lun=$(echo $filefrag_op | cut -d: -f5 |
13616                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
13617
13618         IFS=$'\n'
13619         tot_len=0
13620         num_luns=1
13621         for line in $filefrag_op
13622         do
13623                 frag_lun=$(echo $line | cut -d: -f5 |
13624                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
13625                 ext_len=$(echo $line | cut -d: -f4)
13626                 if (( $frag_lun != $last_lun )); then
13627                         logical=`echo $line | cut -d: -f2 | cut -d. -f1`
13628                         if (( logical != 512 )); then
13629                                 cleanup_130
13630                                 error "FIEMAP on $fm_file failed; returned " \
13631                                 "logical start for lun $logical instead of 512"
13632                                 return
13633                         fi
13634                         if (( tot_len != 512 )); then
13635                                 cleanup_130
13636                                 error "FIEMAP on $fm_file failed; returned " \
13637                                 "len $tot_len for OST $last_lun instead of 1024"
13638                                 return
13639                         else
13640                                 (( num_luns += 1 ))
13641                                 tot_len=0
13642                         fi
13643                 fi
13644                 (( tot_len += ext_len ))
13645                 last_lun=$frag_lun
13646         done
13647         if (( num_luns != 2 || tot_len != 512 )); then
13648                 cleanup_130
13649                 error "FIEMAP on $fm_file failed; returned wrong number of " \
13650                         "luns or wrong len for OST $last_lun"
13651                 return
13652         fi
13653
13654         cleanup_130
13655
13656         echo "FIEMAP on 2-stripe file with hole succeeded"
13657 }
13658 run_test 130c "FIEMAP (2-stripe file with hole)"
13659
13660 test_130d() {
13661         [[ $OSTCOUNT -lt 3 ]] && skip_env "needs >= 3 OSTs"
13662
13663         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
13664         [ -n "$filefrag_op" ] && skip "filefrag does not support FIEMAP"
13665
13666         trap cleanup_130 EXIT RETURN
13667
13668         local fm_file=$DIR/$tfile
13669         $LFS setstripe -S 65536 -c $OSTCOUNT $fm_file ||
13670                         error "setstripe on $fm_file"
13671         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
13672                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
13673
13674         local actual_stripe_count=$($LFS getstripe -c $fm_file)
13675         dd if=/dev/zero of=$fm_file bs=1M count=$actual_stripe_count ||
13676                 error "dd failed on $fm_file"
13677
13678         filefrag -ves $fm_file || error "filefrag $fm_file failed"
13679         filefrag_op=$(filefrag -ve -k $fm_file |
13680                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
13681
13682         last_lun=$(echo $filefrag_op | cut -d: -f5 |
13683                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
13684
13685         IFS=$'\n'
13686         tot_len=0
13687         num_luns=1
13688         for line in $filefrag_op
13689         do
13690                 frag_lun=$(echo $line | cut -d: -f5 |
13691                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
13692                 ext_len=$(echo $line | cut -d: -f4)
13693                 if (( $frag_lun != $last_lun )); then
13694                         if (( tot_len != 1024 )); then
13695                                 cleanup_130
13696                                 error "FIEMAP on $fm_file failed; returned " \
13697                                 "len $tot_len for OST $last_lun instead of 1024"
13698                                 return
13699                         else
13700                                 (( num_luns += 1 ))
13701                                 tot_len=0
13702                         fi
13703                 fi
13704                 (( tot_len += ext_len ))
13705                 last_lun=$frag_lun
13706         done
13707         if (( num_luns != actual_stripe_count || tot_len != 1024 )); then
13708                 cleanup_130
13709                 error "FIEMAP on $fm_file failed; returned wrong number of " \
13710                         "luns or wrong len for OST $last_lun"
13711                 return
13712         fi
13713
13714         cleanup_130
13715
13716         echo "FIEMAP on N-stripe file succeeded"
13717 }
13718 run_test 130d "FIEMAP (N-stripe file)"
13719
13720 test_130e() {
13721         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
13722
13723         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
13724         [ -n "$filefrag_op" ] && skip_env "filefrag does not support FIEMAP"
13725
13726         trap cleanup_130 EXIT RETURN
13727
13728         local fm_file=$DIR/$tfile
13729         $LFS setstripe -S 131072 -c 2 $fm_file || error "setstripe on $fm_file"
13730
13731         NUM_BLKS=512
13732         EXPECTED_LEN=$(( (NUM_BLKS / 2) * 64 ))
13733         for ((i = 0; i < $NUM_BLKS; i++)); do
13734                 dd if=/dev/zero of=$fm_file count=1 bs=64k seek=$((2*$i)) \
13735                         conv=notrunc > /dev/null 2>&1
13736         done
13737
13738         filefrag -ves $fm_file || error "filefrag $fm_file failed"
13739         filefrag_op=$(filefrag -ve -k $fm_file |
13740                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
13741
13742         last_lun=$(echo $filefrag_op | cut -d: -f5)
13743
13744         IFS=$'\n'
13745         tot_len=0
13746         num_luns=1
13747         for line in $filefrag_op; do
13748                 frag_lun=$(echo $line | cut -d: -f5)
13749                 ext_len=$(echo $line | cut -d: -f4)
13750                 if [[ "$frag_lun" != "$last_lun" ]]; then
13751                         if (( tot_len != $EXPECTED_LEN )); then
13752                                 cleanup_130
13753                                 error "OST$last_lun $tot_len != $EXPECTED_LEN"
13754                         else
13755                                 (( num_luns += 1 ))
13756                                 tot_len=0
13757                         fi
13758                 fi
13759                 (( tot_len += ext_len ))
13760                 last_lun=$frag_lun
13761         done
13762         if (( num_luns != 2 || tot_len != $EXPECTED_LEN )); then
13763                 cleanup_130
13764                 error "OST$last_lun $num_luns != 2, $tot_len != $EXPECTED_LEN"
13765         fi
13766
13767         echo "FIEMAP with continuation calls succeeded"
13768 }
13769 run_test 130e "FIEMAP (test continuation FIEMAP calls)"
13770
13771 test_130f() {
13772         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
13773         [ -n "$filefrag_op" ] && skip "filefrag does not support FIEMAP"
13774
13775         local fm_file=$DIR/$tfile
13776         $MULTIOP $fm_file oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:T33554432c ||
13777                 error "multiop create with lov_delay_create on $fm_file"
13778
13779         filefrag -ves $fm_file || error "filefrag $fm_file failed"
13780         filefrag_extents=$(filefrag -vek $fm_file |
13781                            awk '/extents? found/ { print $2 }')
13782         if [[ "$filefrag_extents" != "0" ]]; then
13783                 error "$fm_file: filefrag_extents=$filefrag_extents != 0"
13784         fi
13785
13786         rm -f $fm_file
13787 }
13788 run_test 130f "FIEMAP (unstriped file)"
13789
13790 test_130g() {
13791         local file=$DIR/$tfile
13792         local nr=$((OSTCOUNT * 100))
13793
13794         $LFS setstripe -C $nr $file ||
13795                 error "failed to setstripe -C $nr $file"
13796
13797         dd if=/dev/zero of=$file count=$nr bs=1M
13798         sync
13799         nr=$($LFS getstripe -c $file)
13800
13801         local extents=$(filefrag -v $file |
13802                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}' | wc -l)
13803
13804         echo "filefrag list $extents extents in file with stripecount $nr"
13805         if (( extents < nr )); then
13806                 $LFS getstripe $file
13807                 filefrag -v $file
13808                 error "filefrag printed $extents < $nr extents"
13809         fi
13810
13811         rm -f $file
13812 }
13813 run_test 130g "FIEMAP (overstripe file)"
13814
13815 # Test for writev/readv
13816 test_131a() {
13817         rwv -f $DIR/$tfile -w -n 3 524288 1048576 1572864 ||
13818                 error "writev test failed"
13819         rwv -f $DIR/$tfile -r -v -n 2 1572864 1048576 ||
13820                 error "readv failed"
13821         rm -f $DIR/$tfile
13822 }
13823 run_test 131a "test iov's crossing stripe boundary for writev/readv"
13824
13825 test_131b() {
13826         local fsize=$((524288 + 1048576 + 1572864))
13827         rwv -f $DIR/$tfile -w -a -n 3 524288 1048576 1572864 &&
13828                 $CHECKSTAT -t file $DIR/$tfile -s $fsize ||
13829                         error "append writev test failed"
13830
13831         ((fsize += 1572864 + 1048576))
13832         rwv -f $DIR/$tfile -w -a -n 2 1572864 1048576 &&
13833                 $CHECKSTAT -t file $DIR/$tfile -s $fsize ||
13834                         error "append writev test failed"
13835         rm -f $DIR/$tfile
13836 }
13837 run_test 131b "test append writev"
13838
13839 test_131c() {
13840         rwv -f $DIR/$tfile -w -d -n 1 1048576 || return 0
13841         error "NOT PASS"
13842 }
13843 run_test 131c "test read/write on file w/o objects"
13844
13845 test_131d() {
13846         rwv -f $DIR/$tfile -w -n 1 1572864
13847         NOB=`rwv -f $DIR/$tfile -r -n 3 524288 524288 1048576 | awk '/error/ {print $6}'`
13848         if [ "$NOB" != 1572864 ]; then
13849                 error "Short read filed: read $NOB bytes instead of 1572864"
13850         fi
13851         rm -f $DIR/$tfile
13852 }
13853 run_test 131d "test short read"
13854
13855 test_131e() {
13856         rwv -f $DIR/$tfile -w -s 1048576 -n 1 1048576
13857         rwv -f $DIR/$tfile -r -z -s 0 -n 1 524288 || \
13858         error "read hitting hole failed"
13859         rm -f $DIR/$tfile
13860 }
13861 run_test 131e "test read hitting hole"
13862
13863 check_stats() {
13864         local facet=$1
13865         local op=$2
13866         local want=${3:-0}
13867         local res
13868
13869         case $facet in
13870         mds*) res=$(do_facet $facet \
13871                    $LCTL get_param mdt.$FSNAME-MDT0000.md_stats | grep "$op")
13872                  ;;
13873         ost*) res=$(do_facet $facet \
13874                    $LCTL get_param obdfilter.$FSNAME-OST0000.stats | grep "$op")
13875                  ;;
13876         *) error "Wrong facet '$facet'" ;;
13877         esac
13878         [ "$res" ] || error "The counter for $op on $facet was not incremented"
13879         # if the argument $3 is zero, it means any stat increment is ok.
13880         if [[ $want -gt 0 ]]; then
13881                 local count=$(echo $res | awk '{ print $2 }')
13882                 [[ $count -ne $want ]] &&
13883                         error "The $op counter on $facet is $count, not $want"
13884         fi
13885 }
13886
13887 test_133a() {
13888         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13889         remote_ost_nodsh && skip "remote OST with nodsh"
13890         remote_mds_nodsh && skip "remote MDS with nodsh"
13891         do_facet $SINGLEMDS $LCTL list_param mdt.*.rename_stats ||
13892                 skip_env "MDS doesn't support rename stats"
13893
13894         local testdir=$DIR/${tdir}/stats_testdir
13895
13896         mkdir -p $DIR/${tdir}
13897
13898         # clear stats.
13899         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
13900         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
13901
13902         # verify mdt stats first.
13903         mkdir ${testdir} || error "mkdir failed"
13904         check_stats $SINGLEMDS "mkdir" 1
13905         touch ${testdir}/${tfile} || error "touch failed"
13906         check_stats $SINGLEMDS "open" 1
13907         check_stats $SINGLEMDS "close" 1
13908         [ $MDS1_VERSION -ge $(version_code 2.8.54) ] && {
13909                 mknod ${testdir}/${tfile}-pipe p || error "mknod failed"
13910                 check_stats $SINGLEMDS "mknod" 2
13911         }
13912         rm -f ${testdir}/${tfile}-pipe || error "pipe remove failed"
13913         check_stats $SINGLEMDS "unlink" 1
13914         rm -f ${testdir}/${tfile} || error "file remove failed"
13915         check_stats $SINGLEMDS "unlink" 2
13916
13917         # remove working dir and check mdt stats again.
13918         rmdir ${testdir} || error "rmdir failed"
13919         check_stats $SINGLEMDS "rmdir" 1
13920
13921         local testdir1=$DIR/${tdir}/stats_testdir1
13922         mkdir -p ${testdir}
13923         mkdir -p ${testdir1}
13924         touch ${testdir1}/test1
13925         mv ${testdir1}/test1 ${testdir} || error "file crossdir rename"
13926         check_stats $SINGLEMDS "crossdir_rename" 1
13927
13928         mv ${testdir}/test1 ${testdir}/test0 || error "file samedir rename"
13929         check_stats $SINGLEMDS "samedir_rename" 1
13930
13931         rm -rf $DIR/${tdir}
13932 }
13933 run_test 133a "Verifying MDT stats ========================================"
13934
13935 test_133b() {
13936         local res
13937
13938         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13939         remote_ost_nodsh && skip "remote OST with nodsh"
13940         remote_mds_nodsh && skip "remote MDS with nodsh"
13941
13942         local testdir=$DIR/${tdir}/stats_testdir
13943
13944         mkdir -p ${testdir} || error "mkdir failed"
13945         touch ${testdir}/${tfile} || error "touch failed"
13946         cancel_lru_locks mdc
13947
13948         # clear stats.
13949         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
13950         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
13951
13952         # extra mdt stats verification.
13953         chmod 444 ${testdir}/${tfile} || error "chmod failed"
13954         check_stats $SINGLEMDS "setattr" 1
13955         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
13956         if [ $MDS1_VERSION -ne $(version_code 2.2.0) ]
13957         then            # LU-1740
13958                 ls -l ${testdir}/${tfile} > /dev/null|| error "ls failed"
13959                 check_stats $SINGLEMDS "getattr" 1
13960         fi
13961         rm -rf $DIR/${tdir}
13962
13963         # when DNE is enabled, MDT uses STATFS RPC to ping other targets
13964         # so the check below is not reliable
13965         [ $MDSCOUNT -eq 1 ] || return 0
13966
13967         # Sleep to avoid a cached response.
13968         #define OBD_STATFS_CACHE_SECONDS 1
13969         sleep 2
13970         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
13971         do_facet ost1 $LCTL set_param obdfilter.*.exports.*.stats=clear
13972         $LFS df || error "lfs failed"
13973         check_stats $SINGLEMDS "statfs" 1
13974
13975         # check aggregated statfs (LU-10018)
13976         [ $MDS1_VERSION -lt $(version_code 2.11.54) ] &&
13977                 return 0
13978         [ $CLIENT_VERSION -lt $(version_code 2.11.54) ] &&
13979                 return 0
13980         sleep 2
13981         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
13982         do_facet ost1 $LCTL set_param obdfilter.*.exports.*.stats=clear
13983         df $DIR
13984         check_stats $SINGLEMDS "statfs" 1
13985
13986         # We want to check that the client didn't send OST_STATFS to
13987         # ost1 but the MDT also uses OST_STATFS for precreate. So some
13988         # extra care is needed here.
13989         if remote_mds; then
13990                 local nid=$($LCTL list_nids | head -1 | sed  "s/\./\\\./g")
13991                 local param="obdfilter.$FSNAME-OST0000.exports.'$nid'.stats"
13992
13993                 res=$(do_facet ost1 $LCTL get_param $param | grep statfs)
13994                 [ "$res" ] && error "OST got STATFS"
13995         fi
13996
13997         return 0
13998 }
13999 run_test 133b "Verifying extra MDT stats =================================="
14000
14001 test_133c() {
14002         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14003         remote_ost_nodsh && skip "remote OST with nodsh"
14004         remote_mds_nodsh && skip "remote MDS with nodsh"
14005
14006         local testdir=$DIR/$tdir/stats_testdir
14007
14008         test_mkdir -p $testdir
14009
14010         # verify obdfilter stats.
14011         $LFS setstripe -c 1 -i 0 $testdir/$tfile
14012         sync
14013         cancel_lru_locks osc
14014         wait_delete_completed
14015
14016         # clear stats.
14017         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
14018         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
14019
14020         dd if=/dev/zero of=$testdir/$tfile conv=notrunc bs=512k count=1 ||
14021                 error "dd failed"
14022         sync
14023         cancel_lru_locks osc
14024         check_stats ost1 "write" 1
14025
14026         dd if=$testdir/$tfile of=/dev/null bs=1k count=1 || error "dd failed"
14027         check_stats ost1 "read" 1
14028
14029         > $testdir/$tfile || error "truncate failed"
14030         check_stats ost1 "punch" 1
14031
14032         rm -f $testdir/$tfile || error "file remove failed"
14033         wait_delete_completed
14034         check_stats ost1 "destroy" 1
14035
14036         rm -rf $DIR/$tdir
14037 }
14038 run_test 133c "Verifying OST stats ========================================"
14039
14040 order_2() {
14041         local value=$1
14042         local orig=$value
14043         local order=1
14044
14045         while [ $value -ge 2 ]; do
14046                 order=$((order*2))
14047                 value=$((value/2))
14048         done
14049
14050         if [ $orig -gt $order ]; then
14051                 order=$((order*2))
14052         fi
14053         echo $order
14054 }
14055
14056 size_in_KMGT() {
14057     local value=$1
14058     local size=('K' 'M' 'G' 'T');
14059     local i=0
14060     local size_string=$value
14061
14062     while [ $value -ge 1024 ]; do
14063         if [ $i -gt 3 ]; then
14064             #T is the biggest unit we get here, if that is bigger,
14065             #just return XXXT
14066             size_string=${value}T
14067             break
14068         fi
14069         value=$((value >> 10))
14070         if [ $value -lt 1024 ]; then
14071             size_string=${value}${size[$i]}
14072             break
14073         fi
14074         i=$((i + 1))
14075     done
14076
14077     echo $size_string
14078 }
14079
14080 get_rename_size() {
14081         local size=$1
14082         local context=${2:-.}
14083         local sample=$(do_facet $SINGLEMDS $LCTL \
14084                 get_param mdt.$FSNAME-MDT0000.rename_stats |
14085                 grep -A1 $context |
14086                 awk '/ '${size}'/ {print $4}' | sed -e "s/,//g")
14087         echo $sample
14088 }
14089
14090 test_133d() {
14091         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14092         remote_ost_nodsh && skip "remote OST with nodsh"
14093         remote_mds_nodsh && skip "remote MDS with nodsh"
14094         do_facet $SINGLEMDS $LCTL list_param mdt.*.rename_stats ||
14095                 skip_env "MDS doesn't support rename stats"
14096
14097         local testdir1=$DIR/${tdir}/stats_testdir1
14098         local testdir2=$DIR/${tdir}/stats_testdir2
14099         mkdir -p $DIR/${tdir}
14100
14101         do_facet $SINGLEMDS $LCTL set_param mdt.*.rename_stats=clear
14102
14103         lfs mkdir -i 0 -c 1 ${testdir1} || error "mkdir failed"
14104         lfs mkdir -i 0 -c 1 ${testdir2} || error "mkdir failed"
14105
14106         createmany -o $testdir1/test 512 || error "createmany failed"
14107
14108         # check samedir rename size
14109         mv ${testdir1}/test0 ${testdir1}/test_0
14110
14111         local testdir1_size=$(ls -l $DIR/${tdir} |
14112                 awk '/stats_testdir1/ {print $5}')
14113         local testdir2_size=$(ls -l $DIR/${tdir} |
14114                 awk '/stats_testdir2/ {print $5}')
14115
14116         testdir1_size=$(order_2 $testdir1_size)
14117         testdir2_size=$(order_2 $testdir2_size)
14118
14119         testdir1_size=$(size_in_KMGT $testdir1_size)
14120         testdir2_size=$(size_in_KMGT $testdir2_size)
14121
14122         echo "source rename dir size: ${testdir1_size}"
14123         echo "target rename dir size: ${testdir2_size}"
14124
14125         local cmd="do_facet $SINGLEMDS $LCTL "
14126         cmd+="get_param mdt.$FSNAME-MDT0000.rename_stats"
14127
14128         eval $cmd || error "$cmd failed"
14129         local samedir=$($cmd | grep 'same_dir')
14130         local same_sample=$(get_rename_size $testdir1_size)
14131         [ -z "$samedir" ] && error "samedir_rename_size count error"
14132         [[ $same_sample -eq 1 ]] ||
14133                 error "samedir_rename_size error $same_sample"
14134         echo "Check same dir rename stats success"
14135
14136         do_facet $SINGLEMDS $LCTL set_param mdt.*.rename_stats=clear
14137
14138         # check crossdir rename size
14139         mv ${testdir1}/test_0 ${testdir2}/test_0
14140
14141         testdir1_size=$(ls -l $DIR/${tdir} |
14142                 awk '/stats_testdir1/ {print $5}')
14143         testdir2_size=$(ls -l $DIR/${tdir} |
14144                 awk '/stats_testdir2/ {print $5}')
14145
14146         testdir1_size=$(order_2 $testdir1_size)
14147         testdir2_size=$(order_2 $testdir2_size)
14148
14149         testdir1_size=$(size_in_KMGT $testdir1_size)
14150         testdir2_size=$(size_in_KMGT $testdir2_size)
14151
14152         echo "source rename dir size: ${testdir1_size}"
14153         echo "target rename dir size: ${testdir2_size}"
14154
14155         eval $cmd || error "$cmd failed"
14156         local crossdir=$($cmd | grep 'crossdir')
14157         local src_sample=$(get_rename_size $testdir1_size crossdir_src)
14158         local tgt_sample=$(get_rename_size $testdir2_size crossdir_tgt)
14159         [ -z "$crossdir" ] && error "crossdir_rename_size count error"
14160         [[ $src_sample -eq 1 ]] ||
14161                 error "crossdir_rename_size error $src_sample"
14162         [[ $tgt_sample -eq 1 ]] ||
14163                 error "crossdir_rename_size error $tgt_sample"
14164         echo "Check cross dir rename stats success"
14165         rm -rf $DIR/${tdir}
14166 }
14167 run_test 133d "Verifying rename_stats ========================================"
14168
14169 test_133e() {
14170         remote_mds_nodsh && skip "remote MDS with nodsh"
14171         remote_ost_nodsh && skip "remote OST with nodsh"
14172         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14173
14174         local testdir=$DIR/${tdir}/stats_testdir
14175         local ctr f0 f1 bs=32768 count=42 sum
14176
14177         mkdir -p ${testdir} || error "mkdir failed"
14178
14179         $LFS setstripe -c 1 -i 0 ${testdir}/${tfile}
14180
14181         for ctr in {write,read}_bytes; do
14182                 sync
14183                 cancel_lru_locks osc
14184
14185                 do_facet ost1 $LCTL set_param -n \
14186                         "obdfilter.*.exports.clear=clear"
14187
14188                 if [ $ctr = write_bytes ]; then
14189                         f0=/dev/zero
14190                         f1=${testdir}/${tfile}
14191                 else
14192                         f0=${testdir}/${tfile}
14193                         f1=/dev/null
14194                 fi
14195
14196                 dd if=$f0 of=$f1 conv=notrunc bs=$bs count=$count || \
14197                         error "dd failed"
14198                 sync
14199                 cancel_lru_locks osc
14200
14201                 sum=$(do_facet ost1 $LCTL get_param \
14202                         "obdfilter.*.exports.*.stats" |
14203                         awk -v ctr=$ctr 'BEGIN { sum = 0 }
14204                                 $1 == ctr { sum += $7 }
14205                                 END { printf("%0.0f", sum) }')
14206
14207                 if ((sum != bs * count)); then
14208                         error "Bad $ctr sum, expected $((bs * count)), got $sum"
14209                 fi
14210         done
14211
14212         rm -rf $DIR/${tdir}
14213 }
14214 run_test 133e "Verifying OST {read,write}_bytes nid stats ================="
14215
14216 test_133f() {
14217         [[ $(lustre_version_code $facet) -ge $(version_code 2.7.65) ]] ||
14218                 skip "too old lustre for get_param -R ($facet_ver)"
14219
14220         # verifying readability.
14221         $LCTL get_param -R '*' &> /dev/null
14222
14223         # Verifing writability with badarea_io.
14224         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
14225         local skipped_params='force_lbug|changelog_mask|daemon_file'
14226         $LCTL list_param -FR '*' | grep '=' | tr -d = |
14227                 egrep -v "$skipped_params" |
14228                 xargs -n 1 find $proc_dirs -name |
14229                 xargs -n 1 badarea_io ||
14230                 error "client badarea_io failed"
14231
14232         # remount the FS in case writes/reads /proc break the FS
14233         cleanup || error "failed to unmount"
14234         setup || error "failed to setup"
14235 }
14236 run_test 133f "Check reads/writes of client lustre proc files with bad area io"
14237
14238 test_133g() {
14239         remote_mds_nodsh && skip "remote MDS with nodsh"
14240         remote_ost_nodsh && skip "remote OST with nodsh"
14241
14242         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
14243         local skipped_params="'force_lbug|changelog_mask|daemon_file'"
14244         local facet
14245         for facet in mds1 ost1; do
14246                 local facet_ver=$(lustre_version_code $facet)
14247                 if [ $facet_ver -ge $(version_code 2.7.65) ]; then
14248                         do_facet $facet "$LCTL get_param -R '*'" &> /dev/null
14249                 else
14250                         log "$facet: too old lustre for get_param -R"
14251                 fi
14252                 if [ $facet_ver -ge $(version_code 2.5.54) ]; then
14253                         do_facet $facet "$LCTL list_param -FR '*' | grep '=' |
14254                                 tr -d = | egrep -v $skipped_params |
14255                                 xargs -n 1 find $proc_dirs -name |
14256                                 xargs -n 1 badarea_io" ||
14257                                         error "$facet badarea_io failed"
14258                 else
14259                         skip_noexit "$facet: too old lustre for get_param -R"
14260                 fi
14261         done
14262
14263         # remount the FS in case writes/reads /proc break the FS
14264         cleanup || error "failed to unmount"
14265         setup || error "failed to setup"
14266 }
14267 run_test 133g "Check reads/writes of server lustre proc files with bad area io"
14268
14269 test_133h() {
14270         remote_mds_nodsh && skip "remote MDS with nodsh"
14271         remote_ost_nodsh && skip "remote OST with nodsh"
14272         [[ $MDS1_VERSION -lt $(version_code 2.9.54) ]] &&
14273                 skip "Need MDS version at least 2.9.54"
14274
14275         local facet
14276         for facet in client mds1 ost1; do
14277                 # Get the list of files that are missing the terminating newline
14278                 local plist=$(do_facet $facet
14279                         $LCTL list_param -FR '*' | grep '=' | tr -d =)
14280                 local ent
14281                 for ent in $plist; do
14282                         local missing=$(do_facet $facet $LCTL get_param $ent \|\
14283                                 awk -v FS='\v' -v RS='\v\v' \
14284                                 "'END { if(NR>0 && \\\$NF !~ /.*\\\n\$/) \
14285                                         print FILENAME}'" 2>/dev/null)
14286                         [ -z $missing ] || {
14287                                 do_facet $facet $LCTL get_param $ent | od -An -tx1
14288                                 error "file does not end with newline: $facet-$ent"
14289                         }
14290                 done
14291         done
14292 }
14293 run_test 133h "Proc files should end with newlines"
14294
14295 test_134a() {
14296         remote_mds_nodsh && skip "remote MDS with nodsh"
14297         [[ $MDS1_VERSION -lt $(version_code 2.7.54) ]] &&
14298                 skip "Need MDS version at least 2.7.54"
14299
14300         mkdir_on_mdt0 $DIR/$tdir || error "failed to create $DIR/$tdir"
14301         cancel_lru_locks mdc
14302
14303         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
14304         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
14305         [ $unused -eq 0 ] || error "$unused locks are not cleared"
14306
14307         local nr=1000
14308         createmany -o $DIR/$tdir/f $nr ||
14309                 error "failed to create $nr files in $DIR/$tdir"
14310         unused=$($LCTL get_param -n $nsdir.lock_unused_count)
14311
14312         #define OBD_FAIL_LDLM_WATERMARK_LOW     0x327
14313         do_facet mds1 $LCTL set_param fail_loc=0x327
14314         do_facet mds1 $LCTL set_param fail_val=500
14315         touch $DIR/$tdir/m
14316
14317         echo "sleep 10 seconds ..."
14318         sleep 10
14319         local lck_cnt=$($LCTL get_param -n $nsdir.lock_unused_count)
14320
14321         do_facet mds1 $LCTL set_param fail_loc=0
14322         do_facet mds1 $LCTL set_param fail_val=0
14323         [ $lck_cnt -lt $unused ] ||
14324                 error "No locks reclaimed, before:$unused, after:$lck_cnt"
14325
14326         rm $DIR/$tdir/m
14327         unlinkmany $DIR/$tdir/f $nr
14328 }
14329 run_test 134a "Server reclaims locks when reaching lock_reclaim_threshold"
14330
14331 test_134b() {
14332         remote_mds_nodsh && skip "remote MDS with nodsh"
14333         [[ $MDS1_VERSION -lt $(version_code 2.7.54) ]] &&
14334                 skip "Need MDS version at least 2.7.54"
14335
14336         mkdir_on_mdt0 $DIR/$tdir || error "failed to create $DIR/$tdir"
14337         cancel_lru_locks mdc
14338
14339         local low_wm=$(do_facet mds1 $LCTL get_param -n \
14340                         ldlm.lock_reclaim_threshold_mb)
14341         # disable reclaim temporarily
14342         do_facet mds1 $LCTL set_param ldlm.lock_reclaim_threshold_mb=0
14343
14344         #define OBD_FAIL_LDLM_WATERMARK_HIGH     0x328
14345         do_facet mds1 $LCTL set_param fail_loc=0x328
14346         do_facet mds1 $LCTL set_param fail_val=500
14347
14348         $LCTL set_param debug=+trace
14349
14350         local nr=600
14351         createmany -o $DIR/$tdir/f $nr &
14352         local create_pid=$!
14353
14354         echo "Sleep $TIMEOUT seconds ..."
14355         sleep $TIMEOUT
14356         if ! ps -p $create_pid  > /dev/null 2>&1; then
14357                 do_facet mds1 $LCTL set_param fail_loc=0
14358                 do_facet mds1 $LCTL set_param fail_val=0
14359                 do_facet mds1 $LCTL set_param \
14360                         ldlm.lock_reclaim_threshold_mb=${low_wm}m
14361                 error "createmany finished incorrectly!"
14362         fi
14363         do_facet mds1 $LCTL set_param fail_loc=0
14364         do_facet mds1 $LCTL set_param fail_val=0
14365         do_facet mds1 $LCTL set_param ldlm.lock_reclaim_threshold_mb=${low_wm}m
14366         wait $create_pid || return 1
14367
14368         unlinkmany $DIR/$tdir/f $nr
14369 }
14370 run_test 134b "Server rejects lock request when reaching lock_limit_mb"
14371
14372 test_135() {
14373         remote_mds_nodsh && skip "remote MDS with nodsh"
14374         [[ $MDS1_VERSION -lt $(version_code 2.13.50) ]] &&
14375                 skip "Need MDS version at least 2.13.50"
14376         local fname
14377
14378         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
14379
14380 #define OBD_FAIL_PLAIN_RECORDS 0x1319
14381         #set only one record at plain llog
14382         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x1319 fail_val=1
14383
14384         #fill already existed plain llog each 64767
14385         #wrapping whole catalog
14386         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 1))
14387
14388         createmany -o $DIR/$tdir/$tfile_ 64700
14389         for (( i = 0; i < 64700; i = i + 2 ))
14390         do
14391                 rm $DIR/$tdir/$tfile_$i &
14392                 rm $DIR/$tdir/$tfile_$((i + 1)) &
14393                 local pid=$!
14394                 wait $pid
14395         done
14396
14397         #waiting osp synchronization
14398         wait_delete_completed
14399 }
14400 run_test 135 "Race catalog processing"
14401
14402 test_136() {
14403         remote_mds_nodsh && skip "remote MDS with nodsh"
14404         [[ $MDS1_VERSION -lt $(version_code 2.13.50) ]] &&
14405                 skip "Need MDS version at least 2.13.50"
14406         local fname
14407
14408         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
14409         $LFS setstripe -c 1 -i 0 $DIR/$tdir || error "failed to set striping"
14410         #set only one record at plain llog
14411 #define OBD_FAIL_CATALOG_FULL_CHECK                0x131a
14412         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x131a fail_val=1
14413
14414         #fill already existed 2 plain llogs each 64767
14415         #wrapping whole catalog
14416         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 1))
14417         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 3 / 2))
14418         wait_delete_completed
14419
14420         createmany -o $DIR/$tdir/$tfile_ 10
14421         sleep 25
14422
14423         do_facet $SINGLEMDS $LCTL set_param fail_val=3
14424         for (( i = 0; i < 10; i = i + 3 ))
14425         do
14426                 rm $DIR/$tdir/$tfile_$i &
14427                 rm $DIR/$tdir/$tfile_$((i + 1)) &
14428                 local pid=$!
14429                 wait $pid
14430                 sleep 7
14431                 rm $DIR/$tdir/$tfile_$((i + 2)) &
14432         done
14433
14434         #waiting osp synchronization
14435         wait_delete_completed
14436 }
14437 run_test 136 "Race catalog processing 2"
14438
14439 test_140() { #bug-17379
14440         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14441
14442         test_mkdir $DIR/$tdir
14443         cd $DIR/$tdir || error "Changing to $DIR/$tdir"
14444         cp $(which stat) . || error "Copying stat to $DIR/$tdir"
14445
14446         # VFS limits max symlink depth to 5(4KSTACK) or 7(8KSTACK) or 8
14447         # For kernel > 3.5, bellow only tests consecutive symlink (MAX 40)
14448         local i=0
14449         while i=$((i + 1)); do
14450                 test_mkdir $i
14451                 cd $i || error "Changing to $i"
14452                 ln -s ../stat stat || error "Creating stat symlink"
14453                 # Read the symlink until ELOOP present,
14454                 # not LBUGing the system is considered success,
14455                 # we didn't overrun the stack.
14456                 $OPENFILE -f O_RDONLY stat >/dev/null 2>&1; ret=$?
14457                 if [ $ret -ne 0 ]; then
14458                         if [ $ret -eq 40 ]; then
14459                                 break  # -ELOOP
14460                         else
14461                                 error "Open stat symlink"
14462                                         return
14463                         fi
14464                 fi
14465         done
14466         i=$((i - 1))
14467         echo "The symlink depth = $i"
14468         [ $i -eq 5 ] || [ $i -eq 7 ] || [ $i -eq 8 ] || [ $i -eq 40 ] ||
14469                 error "Invalid symlink depth"
14470
14471         # Test recursive symlink
14472         ln -s symlink_self symlink_self
14473         $OPENFILE -f O_RDONLY symlink_self >/dev/null 2>&1; ret=$?
14474         echo "open symlink_self returns $ret"
14475         [ $ret -eq 40 ] || error "recursive symlink doesn't return -ELOOP"
14476 }
14477 run_test 140 "Check reasonable stack depth (shouldn't LBUG) ===="
14478
14479 test_150a() {
14480         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14481
14482         local TF="$TMP/$tfile"
14483
14484         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
14485         dd if=/dev/urandom of=$TF bs=6096 count=1 || error "dd failed"
14486         cp $TF $DIR/$tfile
14487         cancel_lru_locks $OSC
14488         cmp $TF $DIR/$tfile || error "$TMP/$tfile $DIR/$tfile differ"
14489         remount_client $MOUNT
14490         df -P $MOUNT
14491         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (remount)"
14492
14493         $TRUNCATE $TF 6000
14494         $TRUNCATE $DIR/$tfile 6000
14495         cancel_lru_locks $OSC
14496         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (truncate1)"
14497
14498         echo "12345" >>$TF
14499         echo "12345" >>$DIR/$tfile
14500         cancel_lru_locks $OSC
14501         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (append1)"
14502
14503         echo "12345" >>$TF
14504         echo "12345" >>$DIR/$tfile
14505         cancel_lru_locks $OSC
14506         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (append2)"
14507 }
14508 run_test 150a "truncate/append tests"
14509
14510 test_150b() {
14511         check_set_fallocate_or_skip
14512
14513         touch $DIR/$tfile
14514         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
14515         check_fallocate $DIR/$tfile || error "fallocate failed"
14516 }
14517 run_test 150b "Verify fallocate (prealloc) functionality"
14518
14519 test_150bb() {
14520         check_set_fallocate_or_skip
14521
14522         touch $DIR/$tfile
14523         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
14524         dd if=/dev/urandom of=$DIR/$tfile bs=1M count=20 || error "dd failed"
14525         > $DIR/$tfile
14526         fallocate -l $((1048576 * 20)) $DIR/$tfile || error "fallocate failed"
14527         # precomputed md5sum for 20MB of zeroes
14528         local expect="8f4e33f3dc3e414ff94e5fb6905cba8c"
14529         local sum=($(md5sum $DIR/$tfile))
14530
14531         [[ "${sum[0]}" == "$expect" ]] || error "fallocate unwritten is not zero"
14532
14533         check_set_fallocate 1
14534
14535         > $DIR/$tfile
14536         fallocate -l $((1048576 * 20)) $DIR/$tfile || error "fallocate failed"
14537         sum=($(md5sum $DIR/$tfile))
14538
14539         [[ "${sum[0]}" == "$expect" ]] || error "fallocate zero is not zero"
14540 }
14541 run_test 150bb "Verify fallocate modes both zero space"
14542
14543 test_150c() {
14544         check_set_fallocate_or_skip
14545         local striping="-c2"
14546
14547         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
14548         $LFS setstripe -c $OSTCOUNT -S1M $DIR/$tfile || error "setstripe failed"
14549         fallocate -l ${OSTCOUNT}m $DIR/$tfile || error "fallocate failed"
14550         local bytes=$(($(stat -c '%b * %B' $DIR/$tfile)))
14551         local want=$((OSTCOUNT * 1048576))
14552
14553         # Must allocate all requested space, not more than 5% extra
14554         (( $bytes >= $want && $bytes < $want * 105 / 100 )) ||
14555                 error "bytes $bytes is not $want"
14556
14557         rm -f $DIR/$tfile
14558
14559         echo "verify fallocate on PFL file"
14560
14561         [[ "x$DOM" == "xyes" ]] && striping="-L mdt"
14562
14563         $LFS setstripe -E1M $striping -E16M -c3 -Eeof -c 4 $DIR/$tfile ||
14564                 error "Create $DIR/$tfile failed"
14565         fallocate -l $((1048576 * 512)) $DIR/$tfile ||
14566                         error "fallocate failed"
14567         bytes=$(($(stat -c '%b * %B' $DIR/$tfile)))
14568         want=$((512 * 1048576))
14569
14570         # Must allocate all requested space, not more than 5% extra
14571         (( $bytes >= $want && $bytes < $want * 105 / 100 )) ||
14572                 error "bytes $bytes is not $want"
14573 }
14574 run_test 150c "Verify fallocate Size and Blocks"
14575
14576 test_150d() {
14577         check_set_fallocate_or_skip
14578         local striping="-c2"
14579
14580         [[ "x$DOM" == "xyes" ]] && striping="-L mdt"
14581
14582         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
14583         $LFS setstripe -E1M $striping -E eof -c $OSTCOUNT -S1M $DIR/$tdir ||
14584                 error "setstripe failed"
14585         fallocate -o 1G -l ${OSTCOUNT}m $DIR/$tdir || error "fallocate failed"
14586         local bytes=$(($(stat -c '%b * %B' $DIR/$tdir)))
14587         local want=$((OSTCOUNT * 1048576))
14588
14589         # Must allocate all requested space, not more than 5% extra
14590         (( $bytes >= $want && $bytes < $want * 105 / 100 )) ||
14591                 error "bytes $bytes is not $want"
14592 }
14593 run_test 150d "Verify fallocate Size and Blocks - Non zero start"
14594
14595 test_150e() {
14596         check_set_fallocate_or_skip
14597
14598         echo "df before:"
14599         $LFS df
14600         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
14601         $LFS setstripe -c${OSTCOUNT} $DIR/$tfile ||
14602                 error "$LFS setstripe -c${OSTCOUNT} $DIR/$tfile failed"
14603
14604         # Find OST with Minimum Size
14605         min_size_ost=$($LFS df | awk "/$FSNAME-OST/ { print \$4 }" |
14606                        sort -un | head -1)
14607
14608         # Get 100MB per OST of the available space to reduce run time
14609         # else 60% of the available space if we are running SLOW tests
14610         if [ $SLOW == "no" ]; then
14611                 local space=$((1024 * 100 * OSTCOUNT))
14612         else
14613                 local space=$(((min_size_ost * 60)/100 * OSTCOUNT))
14614         fi
14615
14616         fallocate -l${space}k $DIR/$tfile ||
14617                 error "fallocate ${space}k $DIR/$tfile failed"
14618         echo "'fallocate -l ${space}k $DIR/$tfile' succeeded"
14619
14620         # get size immediately after fallocate. This should be correctly
14621         # updated
14622         local size=$(stat -c '%s' $DIR/$tfile)
14623         local used=$(( $(stat -c '%b * %B' $DIR/$tfile) / 1024))
14624
14625         # Sleep for a while for statfs to get updated. And not pull from cache.
14626         sleep 2
14627
14628         echo "df after fallocate:"
14629         $LFS df
14630
14631         (( size / 1024 == space )) || error "size $size != requested $space"
14632         [ "$ost1_FSTYPE" != ldiskfs ] || (( used >= space )) ||
14633                 error "used $used < space $space"
14634
14635         rm $DIR/$tfile || error "rm failed"
14636         sync
14637         wait_delete_completed
14638
14639         echo "df after unlink:"
14640         $LFS df
14641 }
14642 run_test 150e "Verify 60% of available OST space consumed by fallocate"
14643
14644 test_150f() {
14645         local size
14646         local blocks
14647         local want_size_before=20480 # in bytes
14648         local want_blocks_before=40 # 512 sized blocks
14649         local want_blocks_after=24  # 512 sized blocks
14650         local length=$(((want_blocks_before - want_blocks_after) * 512))
14651
14652         [[ $OST1_VERSION -ge $(version_code 2.14.0) ]] ||
14653                 skip "need at least 2.14.0 for fallocate punch"
14654
14655         if [ "$ost1_FSTYPE" = "zfs" ] || [ "$mds1_FSTYPE" = "zfs" ]; then
14656                 skip "LU-14160: punch mode is not implemented on OSD ZFS"
14657         fi
14658
14659         check_set_fallocate_or_skip
14660         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
14661
14662         [[ "x$DOM" == "xyes" ]] &&
14663                 $LFS setstripe -E1M -L mdt -E eof $DIR/$tfile
14664
14665         echo "Verify fallocate punch: Range within the file range"
14666         yes 'A' | dd of=$DIR/$tfile bs=4096 count=5 ||
14667                 error "dd failed for bs 4096 and count 5"
14668
14669         # Call fallocate with punch range which is within the file range
14670         fallocate -p --offset 4096 -l $length $DIR/$tfile ||
14671                 error "fallocate failed: offset 4096 and length $length"
14672         # client must see changes immediately after fallocate
14673         size=$(stat -c '%s' $DIR/$tfile)
14674         blocks=$(stat -c '%b' $DIR/$tfile)
14675
14676         # Verify punch worked.
14677         (( blocks == want_blocks_after )) ||
14678                 error "punch failed: blocks $blocks != $want_blocks_after"
14679
14680         (( size == want_size_before )) ||
14681                 error "punch failed: size $size != $want_size_before"
14682
14683         # Verify there is hole in file
14684         local data_off=$(lseek_test -d 4096 $DIR/$tfile)
14685         # precomputed md5sum
14686         local expect="4a9a834a2db02452929c0a348273b4aa"
14687
14688         cksum=($(md5sum $DIR/$tfile))
14689         [[ "${cksum[0]}" == "$expect" ]] ||
14690                 error "unexpected MD5SUM after punch: ${cksum[0]}"
14691
14692         # Start second sub-case for fallocate punch.
14693         echo "Verify fallocate punch: Range overlapping and less than blocksize"
14694         yes 'A' | dd of=$DIR/$tfile bs=4096 count=5 ||
14695                 error "dd failed for bs 4096 and count 5"
14696
14697         # Punch range less than block size will have no change in block count
14698         want_blocks_after=40  # 512 sized blocks
14699
14700         # Punch overlaps two blocks and less than blocksize
14701         fallocate -p --offset 4000 -l 3000 $DIR/$tfile ||
14702                 error "fallocate failed: offset 4000 length 3000"
14703         size=$(stat -c '%s' $DIR/$tfile)
14704         blocks=$(stat -c '%b' $DIR/$tfile)
14705
14706         # Verify punch worked.
14707         (( blocks == want_blocks_after )) ||
14708                 error "punch failed: blocks $blocks != $want_blocks_after"
14709
14710         (( size == want_size_before )) ||
14711                 error "punch failed: size $size != $want_size_before"
14712
14713         # Verify if range is really zero'ed out. We expect Zeros.
14714         # precomputed md5sum
14715         expect="c57ec5d769c3dbe3426edc3f7d7e11d3"
14716         cksum=($(md5sum $DIR/$tfile))
14717         [[ "${cksum[0]}" == "$expect" ]] ||
14718                 error "unexpected MD5SUM after punch: ${cksum[0]}"
14719 }
14720 run_test 150f "Verify fallocate punch functionality"
14721
14722 test_150g() {
14723         local space
14724         local size
14725         local blocks
14726         local blocks_after
14727         local size_after
14728         local BS=4096 # Block size in bytes
14729
14730         [[ $OST1_VERSION -ge $(version_code 2.14.0) ]] ||
14731                 skip "need at least 2.14.0 for fallocate punch"
14732
14733         if [ "$ost1_FSTYPE" = "zfs" ] || [ "$mds1_FSTYPE" = "zfs" ]; then
14734                 skip "LU-14160: punch mode is not implemented on OSD ZFS"
14735         fi
14736
14737         check_set_fallocate_or_skip
14738         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
14739
14740         if [[ "x$DOM" == "xyes" ]]; then
14741                 $LFS setstripe -E2M -L mdt -E eof -c${OSTCOUNT} $DIR/$tfile ||
14742                         error "$LFS setstripe DoM + ${OSTCOUNT} OST failed"
14743         else
14744                 $LFS setstripe -c${OSTCOUNT} $DIR/$tfile ||
14745                         error "$LFS setstripe -c${OSTCOUNT} $DIR/$tfile failed"
14746         fi
14747
14748         # Get 100MB per OST of the available space to reduce run time
14749         # else 60% of the available space if we are running SLOW tests
14750         if [ $SLOW == "no" ]; then
14751                 space=$((1024 * 100 * OSTCOUNT))
14752         else
14753                 # Find OST with Minimum Size
14754                 space=$($LFS df | awk "/$FSNAME-OST/ { print \$4 }" |
14755                         sort -un | head -1)
14756                 echo "min size OST: $space"
14757                 space=$(((space * 60)/100 * OSTCOUNT))
14758         fi
14759         # space in 1k units, round to 4k blocks
14760         local blkcount=$((space * 1024 / $BS))
14761
14762         echo "Verify fallocate punch: Very large Range"
14763         fallocate -l${space}k $DIR/$tfile ||
14764                 error "fallocate ${space}k $DIR/$tfile failed"
14765         # write 1M at the end, start and in the middle
14766         yes 'A' | dd of=$DIR/$tfile bs=$BS count=256 ||
14767                 error "dd failed: bs $BS count 256"
14768         yes 'A' | dd of=$DIR/$tfile bs=$BS seek=$((blkcount - 256)) count=256 ||
14769                 error "dd failed: bs $BS count 256 seek $((blkcount - 256))"
14770         yes 'A' | dd of=$DIR/$tfile bs=$BS seek=$((blkcount / 2)) count=1024 ||
14771                 error "dd failed: bs $BS count 256 seek $((blkcount / 2))"
14772
14773         # Gather stats.
14774         size=$(stat -c '%s' $DIR/$tfile)
14775
14776         # gather punch length.
14777         local punch_size=$((size - (BS * 2)))
14778
14779         echo "punch_size = $punch_size"
14780         echo "size - punch_size: $((size - punch_size))"
14781         echo "size - punch_size in blocks: $(((size - punch_size)/BS))"
14782
14783         # Call fallocate to punch all except 2 blocks. We leave the
14784         # first and the last block
14785         echo "fallocate -p --offset $BS -l $punch_size $DIR/$tfile"
14786         fallocate -p --offset $BS -l $punch_size $DIR/$tfile ||
14787                 error "fallocate failed: offset $BS length $punch_size"
14788
14789         size_after=$(stat -c '%s' $DIR/$tfile)
14790         blocks_after=$(stat -c '%b' $DIR/$tfile)
14791
14792         # Verify punch worked.
14793         # Size should be kept
14794         (( size == size_after )) ||
14795                 error "punch failed: size $size != $size_after"
14796
14797         # two 4k data blocks to remain plus possible 1 extra extent block
14798         (( blocks_after <= ((BS / 512) * 3) )) ||
14799                 error "too many blocks remains: $blocks_after"
14800
14801         # Verify that file has hole between the first and the last blocks
14802         local hole_start=$(lseek_test -l 0 $DIR/$tfile)
14803         local hole_end=$(lseek_test -d $BS $DIR/$tfile)
14804
14805         echo "Hole at [$hole_start, $hole_end)"
14806         (( hole_start == BS )) ||
14807                 error "no hole at offset $BS after punch"
14808
14809         (( hole_end == BS + punch_size )) ||
14810                 error "data at offset $hole_end < $((BS + punch_size))"
14811 }
14812 run_test 150g "Verify fallocate punch on large range"
14813
14814 #LU-2902 roc_hit was not able to read all values from lproc
14815 function roc_hit_init() {
14816         local list=$(comma_list $(osts_nodes))
14817         local dir=$DIR/$tdir-check
14818         local file=$dir/$tfile
14819         local BEFORE
14820         local AFTER
14821         local idx
14822
14823         test_mkdir $dir
14824         #use setstripe to do a write to every ost
14825         for i in $(seq 0 $((OSTCOUNT-1))); do
14826                 $LFS setstripe -c 1 -i $i $dir || error "$LFS setstripe $file failed"
14827                 dd if=/dev/urandom of=$file bs=4k count=4 2>&1 > /dev/null
14828                 idx=$(printf %04x $i)
14829                 BEFORE=$(get_osd_param $list *OST*$idx stats |
14830                         awk '$1 == "cache_access" {sum += $7}
14831                                 END { printf("%0.0f", sum) }')
14832
14833                 cancel_lru_locks osc
14834                 cat $file >/dev/null
14835
14836                 AFTER=$(get_osd_param $list *OST*$idx stats |
14837                         awk '$1 == "cache_access" {sum += $7}
14838                                 END { printf("%0.0f", sum) }')
14839
14840                 echo BEFORE:$BEFORE AFTER:$AFTER
14841                 if ! let "AFTER - BEFORE == 4"; then
14842                         rm -rf $dir
14843                         error "roc_hit is not safe to use"
14844                 fi
14845                 rm $file
14846         done
14847
14848         rm -rf $dir
14849 }
14850
14851 function roc_hit() {
14852         local list=$(comma_list $(osts_nodes))
14853         echo $(get_osd_param $list '' stats |
14854                 awk '$1 == "cache_hit" {sum += $7}
14855                         END { printf("%0.0f", sum) }')
14856 }
14857
14858 function set_cache() {
14859         local on=1
14860
14861         if [ "$2" == "off" ]; then
14862                 on=0;
14863         fi
14864         local list=$(comma_list $(osts_nodes))
14865         set_osd_param $list '' $1_cache_enable $on
14866
14867         cancel_lru_locks osc
14868 }
14869
14870 test_151() {
14871         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14872         remote_ost_nodsh && skip "remote OST with nodsh"
14873
14874         local CPAGES=3
14875         local list=$(comma_list $(osts_nodes))
14876
14877         # check whether obdfilter is cache capable at all
14878         if ! get_osd_param $list '' read_cache_enable >/dev/null; then
14879                 skip "not cache-capable obdfilter"
14880         fi
14881
14882         # check cache is enabled on all obdfilters
14883         if get_osd_param $list '' read_cache_enable | grep 0; then
14884                 skip "oss cache is disabled"
14885         fi
14886
14887         set_osd_param $list '' writethrough_cache_enable 1
14888
14889         # check write cache is enabled on all obdfilters
14890         if get_osd_param $list '' writethrough_cache_enable | grep 0; then
14891                 skip "oss write cache is NOT enabled"
14892         fi
14893
14894         roc_hit_init
14895
14896         #define OBD_FAIL_OBD_NO_LRU  0x609
14897         do_nodes $list $LCTL set_param fail_loc=0x609
14898
14899         # pages should be in the case right after write
14900         dd if=/dev/urandom of=$DIR/$tfile bs=4k count=$CPAGES ||
14901                 error "dd failed"
14902
14903         local BEFORE=$(roc_hit)
14904         cancel_lru_locks osc
14905         cat $DIR/$tfile >/dev/null
14906         local AFTER=$(roc_hit)
14907
14908         do_nodes $list $LCTL set_param fail_loc=0
14909
14910         if ! let "AFTER - BEFORE == CPAGES"; then
14911                 error "NOT IN CACHE: before: $BEFORE, after: $AFTER"
14912         fi
14913
14914         cancel_lru_locks osc
14915         # invalidates OST cache
14916         do_nodes $list "echo 1 > /proc/sys/vm/drop_caches"
14917         set_osd_param $list '' read_cache_enable 0
14918         cat $DIR/$tfile >/dev/null
14919
14920         # now data shouldn't be found in the cache
14921         BEFORE=$(roc_hit)
14922         cancel_lru_locks osc
14923         cat $DIR/$tfile >/dev/null
14924         AFTER=$(roc_hit)
14925         if let "AFTER - BEFORE != 0"; then
14926                 error "IN CACHE: before: $BEFORE, after: $AFTER"
14927         fi
14928
14929         set_osd_param $list '' read_cache_enable 1
14930         rm -f $DIR/$tfile
14931 }
14932 run_test 151 "test cache on oss and controls ==============================="
14933
14934 test_152() {
14935         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14936
14937         local TF="$TMP/$tfile"
14938
14939         # simulate ENOMEM during write
14940 #define OBD_FAIL_OST_NOMEM      0x226
14941         lctl set_param fail_loc=0x80000226
14942         dd if=/dev/urandom of=$TF bs=6096 count=1 || error "dd failed"
14943         cp $TF $DIR/$tfile
14944         sync || error "sync failed"
14945         lctl set_param fail_loc=0
14946
14947         # discard client's cache
14948         cancel_lru_locks osc
14949
14950         # simulate ENOMEM during read
14951         lctl set_param fail_loc=0x80000226
14952         cmp $TF $DIR/$tfile || error "cmp failed"
14953         lctl set_param fail_loc=0
14954
14955         rm -f $TF
14956 }
14957 run_test 152 "test read/write with enomem ============================"
14958
14959 test_153() {
14960         $MULTIOP $DIR/$tfile Ow4096Ycu || error "multiop failed"
14961 }
14962 run_test 153 "test if fdatasync does not crash ======================="
14963
14964 dot_lustre_fid_permission_check() {
14965         local fid=$1
14966         local ffid=$MOUNT/.lustre/fid/$fid
14967         local test_dir=$2
14968
14969         echo "stat fid $fid"
14970         stat $ffid > /dev/null || error "stat $ffid failed."
14971         echo "touch fid $fid"
14972         touch $ffid || error "touch $ffid failed."
14973         echo "write to fid $fid"
14974         cat /etc/hosts > $ffid || error "write $ffid failed."
14975         echo "read fid $fid"
14976         diff /etc/hosts $ffid || error "read $ffid failed."
14977         echo "append write to fid $fid"
14978         cat /etc/hosts >> $ffid || error "append write $ffid failed."
14979         echo "rename fid $fid"
14980         mv $ffid $test_dir/$tfile.1 &&
14981                 error "rename $ffid to $tfile.1 should fail."
14982         touch $test_dir/$tfile.1
14983         mv $test_dir/$tfile.1 $ffid &&
14984                 error "rename $tfile.1 to $ffid should fail."
14985         rm -f $test_dir/$tfile.1
14986         echo "truncate fid $fid"
14987         $TRUNCATE $ffid 777 || error "truncate $ffid failed."
14988         echo "link fid $fid"
14989         ln -f $ffid $test_dir/tfile.lnk || error "link $ffid failed."
14990         if [[ $($LCTL get_param -n mdc.*-mdc-*.connect_flags) =~ acl ]]; then
14991                 echo "setfacl fid $fid"
14992                 setfacl -R -m u:bin:rwx $ffid || error "setfacl $ffid failed."
14993                 echo "getfacl fid $fid"
14994                 getfacl $ffid >/dev/null || error "getfacl $ffid failed."
14995         fi
14996         echo "unlink fid $fid"
14997         unlink $MOUNT/.lustre/fid/$fid && error "unlink $ffid should fail."
14998         echo "mknod fid $fid"
14999         mknod $ffid c 1 3 && error "mknod $ffid should fail."
15000
15001         fid=[0xf00000400:0x1:0x0]
15002         ffid=$MOUNT/.lustre/fid/$fid
15003
15004         echo "stat non-exist fid $fid"
15005         stat $ffid > /dev/null && error "stat non-exist $ffid should fail."
15006         echo "write to non-exist fid $fid"
15007         cat /etc/hosts > $ffid && error "write non-exist $ffid should fail."
15008         echo "link new fid $fid"
15009         ln $test_dir/$tfile $ffid && error "link $ffid should fail."
15010
15011         mkdir -p $test_dir/$tdir
15012         touch $test_dir/$tdir/$tfile
15013         fid=$($LFS path2fid $test_dir/$tdir)
15014         rc=$?
15015         [ $rc -ne 0 ] &&
15016                 error "error: could not get fid for $test_dir/$dir/$tfile."
15017
15018         ffid=$MOUNT/.lustre/fid/$fid
15019
15020         echo "ls $fid"
15021         ls $ffid > /dev/null || error "ls $ffid failed."
15022         echo "touch $fid/$tfile.1"
15023         touch $ffid/$tfile.1 || error "touch $ffid/$tfile.1 failed."
15024
15025         echo "touch $MOUNT/.lustre/fid/$tfile"
15026         touch $MOUNT/.lustre/fid/$tfile && \
15027                 error "touch $MOUNT/.lustre/fid/$tfile should fail."
15028
15029         echo "setxattr to $MOUNT/.lustre/fid"
15030         setfattr -n trusted.name1 -v value1 $MOUNT/.lustre/fid
15031
15032         echo "listxattr for $MOUNT/.lustre/fid"
15033         getfattr -d -m "^trusted" $MOUNT/.lustre/fid
15034
15035         echo "delxattr from $MOUNT/.lustre/fid"
15036         setfattr -x trusted.name1 $MOUNT/.lustre/fid
15037
15038         echo "touch invalid fid: $MOUNT/.lustre/fid/[0x200000400:0x2:0x3]"
15039         touch $MOUNT/.lustre/fid/[0x200000400:0x2:0x3] &&
15040                 error "touch invalid fid should fail."
15041
15042         echo "touch non-normal fid: $MOUNT/.lustre/fid/[0x1:0x2:0x0]"
15043         touch $MOUNT/.lustre/fid/[0x1:0x2:0x0] &&
15044                 error "touch non-normal fid should fail."
15045
15046         echo "rename $tdir to $MOUNT/.lustre/fid"
15047         mrename $test_dir/$tdir $MOUNT/.lustre/fid &&
15048                 error "rename to $MOUNT/.lustre/fid should fail."
15049
15050         if [ $MDS1_VERSION -ge $(version_code 2.3.51) ]
15051         then            # LU-3547
15052                 local old_obf_mode=$(stat --format="%a" $DIR/.lustre/fid)
15053                 local new_obf_mode=777
15054
15055                 echo "change mode of $DIR/.lustre/fid to $new_obf_mode"
15056                 chmod $new_obf_mode $DIR/.lustre/fid ||
15057                         error "chmod $new_obf_mode $DIR/.lustre/fid failed"
15058
15059                 local obf_mode=$(stat --format=%a $DIR/.lustre/fid)
15060                 [ $obf_mode -eq $new_obf_mode ] ||
15061                         error "stat $DIR/.lustre/fid returned wrong mode $obf_mode"
15062
15063                 echo "restore mode of $DIR/.lustre/fid to $old_obf_mode"
15064                 chmod $old_obf_mode $DIR/.lustre/fid ||
15065                         error "chmod $old_obf_mode $DIR/.lustre/fid failed"
15066         fi
15067
15068         $OPENFILE -f O_LOV_DELAY_CREATE:O_CREAT $test_dir/$tfile-2
15069         fid=$($LFS path2fid $test_dir/$tfile-2)
15070
15071         if [ $MDS1_VERSION -ge $(version_code 2.6.50) ]
15072         then # LU-5424
15073                 echo "cp /etc/passwd $MOUNT/.lustre/fid/$fid"
15074                 cp /etc/passwd $MOUNT/.lustre/fid/$fid ||
15075                         error "create lov data thru .lustre failed"
15076         fi
15077         echo "cp /etc/passwd $test_dir/$tfile-2"
15078         cp /etc/passwd $test_dir/$tfile-2 ||
15079                 error "copy to $test_dir/$tfile-2 failed."
15080         echo "diff /etc/passwd $MOUNT/.lustre/fid/$fid"
15081         diff /etc/passwd $MOUNT/.lustre/fid/$fid ||
15082                 error "diff /etc/passwd $MOUNT/.lustre/fid/$fid failed."
15083
15084         rm -rf $test_dir/tfile.lnk
15085         rm -rf $test_dir/$tfile-2
15086 }
15087
15088 test_154A() {
15089         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
15090                 skip "Need MDS version at least 2.4.1"
15091
15092         local tf=$DIR/$tfile
15093         touch $tf
15094
15095         local fid=$($LFS path2fid $tf)
15096         [ -z "$fid" ] && error "path2fid unable to get $tf FID"
15097
15098         # check that we get the same pathname back
15099         local rootpath
15100         local found
15101         for rootpath in "$MOUNT" "$MOUNT///" "$MOUNT/$tfile"; do
15102                 echo "$rootpath $fid"
15103                 found=$($LFS fid2path $rootpath "$fid")
15104                 [ -z "$found" ] && error "fid2path unable to get '$fid' path"
15105                 [ "$found" == "$tf" ] || error "fid2path $found != $tf"
15106         done
15107
15108         # check wrong root path format
15109         rootpath=$MOUNT"_wrong"
15110         found=$($LFS fid2path $rootpath "$fid")
15111         [ -z "$found" ] || error "should fail ($rootpath != $MOUNT)"
15112 }
15113 run_test 154A "lfs path2fid and fid2path basic checks"
15114
15115 test_154B() {
15116         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
15117                 skip "Need MDS version at least 2.4.1"
15118
15119         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
15120         touch $DIR/$tdir/$tfile || error "touch $DIR/$tdir/$tfile failed"
15121         local linkea=$($LL_DECODE_LINKEA $DIR/$tdir/$tfile | grep 'pfid')
15122         [ -z "$linkea" ] && error "decode linkea $DIR/$tdir/$tfile failed"
15123
15124         local name=$(echo $linkea | awk '/pfid/ {print $5}' | sed -e "s/'//g")
15125         local PFID=$(echo $linkea | awk '/pfid/ {print $3}' | sed -e "s/,//g")
15126
15127         # check that we get the same pathname
15128         echo "PFID: $PFID, name: $name"
15129         local FOUND=$($LFS fid2path $MOUNT "$PFID")
15130         [ -z "$FOUND" ] && error "fid2path unable to get $PFID path"
15131         [ "$FOUND/$name" != "$DIR/$tdir/$tfile" ] &&
15132                 error "ll_decode_linkea has $FOUND/$name != $DIR/$tdir/$tfile"
15133
15134         rm -rf $DIR/$tdir || error "Can not delete directory $DIR/$tdir"
15135 }
15136 run_test 154B "verify the ll_decode_linkea tool"
15137
15138 test_154a() {
15139         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15140         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
15141         [[ $MDS1_VERSION -ge $(version_code 2.2.51) ]] ||
15142                 skip "Need MDS version at least 2.2.51"
15143         [ -z "$(which setfacl)" ] && skip_env "must have setfacl tool"
15144
15145         cp /etc/hosts $DIR/$tfile
15146
15147         fid=$($LFS path2fid $DIR/$tfile)
15148         rc=$?
15149         [ $rc -ne 0 ] && error "error: could not get fid for $DIR/$tfile."
15150
15151         dot_lustre_fid_permission_check "$fid" $DIR ||
15152                 error "dot lustre permission check $fid failed"
15153
15154         ls -a $MOUNT | grep "\.lustre" && error ".lustre should not be listed"
15155
15156         rm -rf $MOUNT/.lustre && error ".lustre is not allowed to be unlinked"
15157
15158         touch $MOUNT/.lustre/file &&
15159                 error "creation is not allowed under .lustre"
15160
15161         mkdir $MOUNT/.lustre/dir &&
15162                 error "mkdir is not allowed under .lustre"
15163
15164         rm -rf $DIR/$tfile
15165 }
15166 run_test 154a "Open-by-FID"
15167
15168 test_154b() {
15169         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15170         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
15171         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
15172         [[ $MDS1_VERSION -ge $(version_code 2.2.51) ]] ||
15173                 skip "Need MDS version at least 2.2.51"
15174
15175         local remote_dir=$DIR/$tdir/remote_dir
15176         local MDTIDX=1
15177         local rc=0
15178
15179         mkdir -p $DIR/$tdir
15180         $LFS mkdir -i $MDTIDX $remote_dir ||
15181                 error "create remote directory failed"
15182
15183         cp /etc/hosts $remote_dir/$tfile
15184
15185         fid=$($LFS path2fid $remote_dir/$tfile)
15186         rc=$?
15187         [ $rc -ne 0 ] && error "error: could not get fid for $remote_dir/$tfile"
15188
15189         dot_lustre_fid_permission_check "$fid" $remote_dir ||
15190                 error "dot lustre permission check $fid failed"
15191         rm -rf $DIR/$tdir
15192 }
15193 run_test 154b "Open-by-FID for remote directory"
15194
15195 test_154c() {
15196         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
15197                 skip "Need MDS version at least 2.4.1"
15198
15199         touch $DIR/$tfile.1 $DIR/$tfile.2 $DIR/$tfile.3
15200         local FID1=$($LFS path2fid $DIR/$tfile.1)
15201         local FID2=$($LFS path2fid $DIR/$tfile.2)
15202         local FID3=$($LFS path2fid $DIR/$tfile.3)
15203
15204         local N=1
15205         $LFS path2fid $DIR/$tfile.[123] | while read PATHNAME FID; do
15206                 [ "$PATHNAME" = "$DIR/$tfile.$N:" ] ||
15207                         error "path2fid pathname $PATHNAME != $DIR/$tfile.$N:"
15208                 local want=FID$N
15209                 [ "$FID" = "${!want}" ] ||
15210                         error "path2fid $PATHNAME FID $FID != FID$N ${!want}"
15211                 N=$((N + 1))
15212         done
15213
15214         $LFS fid2path $MOUNT "$FID1" "$FID2" "$FID3" | while read PATHNAME;
15215         do
15216                 [ "$PATHNAME" = "$DIR/$tfile.$N" ] ||
15217                         error "fid2path pathname $PATHNAME != $DIR/$tfile.$N:"
15218                 N=$((N + 1))
15219         done
15220 }
15221 run_test 154c "lfs path2fid and fid2path multiple arguments"
15222
15223 test_154d() {
15224         remote_mds_nodsh && skip "remote MDS with nodsh"
15225         [[ $MDS1_VERSION -lt $(version_code 2.5.53) ]] &&
15226                 skip "Need MDS version at least 2.5.53"
15227
15228         if remote_mds; then
15229                 nid=$($LCTL list_nids | sed  "s/\./\\\./g")
15230         else
15231                 nid="0@lo"
15232         fi
15233         local proc_ofile="mdt.*.exports.'$nid'.open_files"
15234         local fd
15235         local cmd
15236
15237         rm -f $DIR/$tfile
15238         touch $DIR/$tfile
15239
15240         local fid=$($LFS path2fid $DIR/$tfile)
15241         # Open the file
15242         fd=$(free_fd)
15243         cmd="exec $fd<$DIR/$tfile"
15244         eval $cmd
15245         local fid_list=$(do_facet $SINGLEMDS $LCTL get_param $proc_ofile)
15246         echo "$fid_list" | grep "$fid"
15247         rc=$?
15248
15249         cmd="exec $fd>/dev/null"
15250         eval $cmd
15251         if [ $rc -ne 0 ]; then
15252                 error "FID $fid not found in open files list $fid_list"
15253         fi
15254 }
15255 run_test 154d "Verify open file fid"
15256
15257 test_154e()
15258 {
15259         [[ $MDS1_VERSION -lt $(version_code 2.6.50) ]] &&
15260                 skip "Need MDS version at least 2.6.50"
15261
15262         if ls -a $MOUNT | grep -q '^\.lustre$'; then
15263                 error ".lustre returned by readdir"
15264         fi
15265 }
15266 run_test 154e ".lustre is not returned by readdir"
15267
15268 test_154f() {
15269         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
15270
15271         # create parent directory on a single MDT to avoid cross-MDT hardlinks
15272         mkdir_on_mdt0 $DIR/$tdir
15273         # test dirs inherit from its stripe
15274         mkdir -p $DIR/$tdir/foo1 || error "mkdir error"
15275         mkdir -p $DIR/$tdir/foo2 || error "mkdir error"
15276         cp /etc/hosts $DIR/$tdir/foo1/$tfile
15277         ln $DIR/$tdir/foo1/$tfile $DIR/$tdir/foo2/link
15278         touch $DIR/f
15279
15280         # get fid of parents
15281         local FID0=$($LFS path2fid $DIR/$tdir)
15282         local FID1=$($LFS path2fid $DIR/$tdir/foo1)
15283         local FID2=$($LFS path2fid $DIR/$tdir/foo2)
15284         local FID3=$($LFS path2fid $DIR)
15285
15286         # check that path2fid --parents returns expected <parent_fid>/name
15287         # 1) test for a directory (single parent)
15288         local parent=$($LFS path2fid --parents $DIR/$tdir/foo1)
15289         [ "$parent" == "$FID0/foo1" ] ||
15290                 error "expected parent: $FID0/foo1, got: $parent"
15291
15292         # 2) test for a file with nlink > 1 (multiple parents)
15293         parent=$($LFS path2fid --parents $DIR/$tdir/foo1/$tfile)
15294         echo "$parent" | grep -F "$FID1/$tfile" ||
15295                 error "$FID1/$tfile not returned in parent list"
15296         echo "$parent" | grep -F "$FID2/link" ||
15297                 error "$FID2/link not returned in parent list"
15298
15299         # 3) get parent by fid
15300         local file_fid=$($LFS path2fid $DIR/$tdir/foo1/$tfile)
15301         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
15302         echo "$parent" | grep -F "$FID1/$tfile" ||
15303                 error "$FID1/$tfile not returned in parent list (by fid)"
15304         echo "$parent" | grep -F "$FID2/link" ||
15305                 error "$FID2/link not returned in parent list (by fid)"
15306
15307         # 4) test for entry in root directory
15308         parent=$($LFS path2fid --parents $DIR/f)
15309         echo "$parent" | grep -F "$FID3/f" ||
15310                 error "$FID3/f not returned in parent list"
15311
15312         # 5) test it on root directory
15313         [ -z "$($LFS path2fid --parents $MOUNT 2>/dev/null)" ] ||
15314                 error "$MOUNT should not have parents"
15315
15316         # enable xattr caching and check that linkea is correctly updated
15317         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
15318         save_lustre_params client "llite.*.xattr_cache" > $save
15319         lctl set_param llite.*.xattr_cache 1
15320
15321         # 6.1) linkea update on rename
15322         mv $DIR/$tdir/foo1/$tfile $DIR/$tdir/foo2/$tfile.moved
15323
15324         # get parents by fid
15325         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
15326         # foo1 should no longer be returned in parent list
15327         echo "$parent" | grep -F "$FID1" &&
15328                 error "$FID1 should no longer be in parent list"
15329         # the new path should appear
15330         echo "$parent" | grep -F "$FID2/$tfile.moved" ||
15331                 error "$FID2/$tfile.moved is not in parent list"
15332
15333         # 6.2) linkea update on unlink
15334         rm -f $DIR/$tdir/foo2/link
15335         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
15336         # foo2/link should no longer be returned in parent list
15337         echo "$parent" | grep -F "$FID2/link" &&
15338                 error "$FID2/link should no longer be in parent list"
15339         true
15340
15341         rm -f $DIR/f
15342         restore_lustre_params < $save
15343         rm -f $save
15344 }
15345 run_test 154f "get parent fids by reading link ea"
15346
15347 test_154g()
15348 {
15349         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
15350         [[ $MDS1_VERSION -ge $(version_code 2.6.92) &&
15351            $CLIENT_VERSION -gt $(version_code 2.6.99) ]] ||
15352                 skip "Need MDS version at least 2.6.92"
15353
15354         mkdir_on_mdt0 $DIR/$tdir
15355         llapi_fid_test -d $DIR/$tdir
15356 }
15357 run_test 154g "various llapi FID tests"
15358
15359 test_155_small_load() {
15360     local temp=$TMP/$tfile
15361     local file=$DIR/$tfile
15362
15363     dd if=/dev/urandom of=$temp bs=6096 count=1 || \
15364         error "dd of=$temp bs=6096 count=1 failed"
15365     cp $temp $file
15366     cancel_lru_locks $OSC
15367     cmp $temp $file || error "$temp $file differ"
15368
15369     $TRUNCATE $temp 6000
15370     $TRUNCATE $file 6000
15371     cmp $temp $file || error "$temp $file differ (truncate1)"
15372
15373     echo "12345" >>$temp
15374     echo "12345" >>$file
15375     cmp $temp $file || error "$temp $file differ (append1)"
15376
15377     echo "12345" >>$temp
15378     echo "12345" >>$file
15379     cmp $temp $file || error "$temp $file differ (append2)"
15380
15381     rm -f $temp $file
15382     true
15383 }
15384
15385 test_155_big_load() {
15386         remote_ost_nodsh && skip "remote OST with nodsh"
15387
15388         local temp=$TMP/$tfile
15389         local file=$DIR/$tfile
15390
15391         free_min_max
15392         local cache_size=$(do_facet ost$((MAXI+1)) \
15393                 "awk '/cache/ {sum+=\\\$4} END {print sum}' /proc/cpuinfo")
15394         local large_file_size=$((cache_size * 2))
15395
15396         echo "OSS cache size: $cache_size KB"
15397         echo "Large file size: $large_file_size KB"
15398
15399         [ $MAXV -le $large_file_size ] &&
15400                 skip_env "max available OST size needs > $large_file_size KB"
15401
15402         $LFS setstripe $file -c 1 -i $MAXI || error "$LFS setstripe $file failed"
15403
15404         dd if=/dev/urandom of=$temp bs=$large_file_size count=1k ||
15405                 error "dd of=$temp bs=$large_file_size count=1k failed"
15406         cp $temp $file
15407         ls -lh $temp $file
15408         cancel_lru_locks osc
15409         cmp $temp $file || error "$temp $file differ"
15410
15411         rm -f $temp $file
15412         true
15413 }
15414
15415 save_writethrough() {
15416         local facets=$(get_facets OST)
15417
15418         save_lustre_params $facets "osd-*.*.writethrough_cache_enable" > $1
15419 }
15420
15421 test_155a() {
15422         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15423
15424         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15425
15426         save_writethrough $p
15427
15428         set_cache read on
15429         set_cache writethrough on
15430         test_155_small_load
15431         restore_lustre_params < $p
15432         rm -f $p
15433 }
15434 run_test 155a "Verify small file correctness: read cache:on write_cache:on"
15435
15436 test_155b() {
15437         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15438
15439         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15440
15441         save_writethrough $p
15442
15443         set_cache read on
15444         set_cache writethrough off
15445         test_155_small_load
15446         restore_lustre_params < $p
15447         rm -f $p
15448 }
15449 run_test 155b "Verify small file correctness: read cache:on write_cache:off"
15450
15451 test_155c() {
15452         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15453
15454         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15455
15456         save_writethrough $p
15457
15458         set_cache read off
15459         set_cache writethrough on
15460         test_155_small_load
15461         restore_lustre_params < $p
15462         rm -f $p
15463 }
15464 run_test 155c "Verify small file correctness: read cache:off write_cache:on"
15465
15466 test_155d() {
15467         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15468
15469         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15470
15471         save_writethrough $p
15472
15473         set_cache read off
15474         set_cache writethrough off
15475         test_155_small_load
15476         restore_lustre_params < $p
15477         rm -f $p
15478 }
15479 run_test 155d "Verify small file correctness: read cache:off write_cache:off"
15480
15481 test_155e() {
15482         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15483
15484         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15485
15486         save_writethrough $p
15487
15488         set_cache read on
15489         set_cache writethrough on
15490         test_155_big_load
15491         restore_lustre_params < $p
15492         rm -f $p
15493 }
15494 run_test 155e "Verify big file correctness: read cache:on write_cache:on"
15495
15496 test_155f() {
15497         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15498
15499         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15500
15501         save_writethrough $p
15502
15503         set_cache read on
15504         set_cache writethrough off
15505         test_155_big_load
15506         restore_lustre_params < $p
15507         rm -f $p
15508 }
15509 run_test 155f "Verify big file correctness: read cache:on write_cache:off"
15510
15511 test_155g() {
15512         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15513
15514         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15515
15516         save_writethrough $p
15517
15518         set_cache read off
15519         set_cache writethrough on
15520         test_155_big_load
15521         restore_lustre_params < $p
15522         rm -f $p
15523 }
15524 run_test 155g "Verify big file correctness: read cache:off write_cache:on"
15525
15526 test_155h() {
15527         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15528
15529         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15530
15531         save_writethrough $p
15532
15533         set_cache read off
15534         set_cache writethrough off
15535         test_155_big_load
15536         restore_lustre_params < $p
15537         rm -f $p
15538 }
15539 run_test 155h "Verify big file correctness: read cache:off write_cache:off"
15540
15541 test_156() {
15542         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15543         remote_ost_nodsh && skip "remote OST with nodsh"
15544         [ $OST1_VERSION -lt $(version_code 2.6.93) ] &&
15545                 skip "stats not implemented on old servers"
15546         [ "$ost1_FSTYPE" = "zfs" ] &&
15547                 skip "LU-1956/LU-2261: stats not implemented on OSD ZFS"
15548
15549         local CPAGES=3
15550         local BEFORE
15551         local AFTER
15552         local file="$DIR/$tfile"
15553         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15554
15555         save_writethrough $p
15556         roc_hit_init
15557
15558         log "Turn on read and write cache"
15559         set_cache read on
15560         set_cache writethrough on
15561
15562         log "Write data and read it back."
15563         log "Read should be satisfied from the cache."
15564         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
15565         BEFORE=$(roc_hit)
15566         cancel_lru_locks osc
15567         cat $file >/dev/null
15568         AFTER=$(roc_hit)
15569         if ! let "AFTER - BEFORE == CPAGES"; then
15570                 error "NOT IN CACHE (2): before: $BEFORE, after: $AFTER"
15571         else
15572                 log "cache hits: before: $BEFORE, after: $AFTER"
15573         fi
15574
15575         log "Read again; it should be satisfied from the cache."
15576         BEFORE=$AFTER
15577         cancel_lru_locks osc
15578         cat $file >/dev/null
15579         AFTER=$(roc_hit)
15580         if ! let "AFTER - BEFORE == CPAGES"; then
15581                 error "NOT IN CACHE (3): before: $BEFORE, after: $AFTER"
15582         else
15583                 log "cache hits:: before: $BEFORE, after: $AFTER"
15584         fi
15585
15586         log "Turn off the read cache and turn on the write cache"
15587         set_cache read off
15588         set_cache writethrough on
15589
15590         log "Read again; it should be satisfied from the cache."
15591         BEFORE=$(roc_hit)
15592         cancel_lru_locks osc
15593         cat $file >/dev/null
15594         AFTER=$(roc_hit)
15595         if ! let "AFTER - BEFORE == CPAGES"; then
15596                 error "NOT IN CACHE (4): before: $BEFORE, after: $AFTER"
15597         else
15598                 log "cache hits:: before: $BEFORE, after: $AFTER"
15599         fi
15600
15601         if [ $OST1_VERSION -lt $(version_code 2.12.55) ]; then
15602                 # > 2.12.56 uses pagecache if cached
15603                 log "Read again; it should not be satisfied from the cache."
15604                 BEFORE=$AFTER
15605                 cancel_lru_locks osc
15606                 cat $file >/dev/null
15607                 AFTER=$(roc_hit)
15608                 if ! let "AFTER - BEFORE == 0"; then
15609                         error "IN CACHE (5): before: $BEFORE, after: $AFTER"
15610                 else
15611                         log "cache hits:: before: $BEFORE, after: $AFTER"
15612                 fi
15613         fi
15614
15615         log "Write data and read it back."
15616         log "Read should be satisfied from the cache."
15617         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
15618         BEFORE=$(roc_hit)
15619         cancel_lru_locks osc
15620         cat $file >/dev/null
15621         AFTER=$(roc_hit)
15622         if ! let "AFTER - BEFORE == CPAGES"; then
15623                 error "NOT IN CACHE (6): before: $BEFORE, after: $AFTER"
15624         else
15625                 log "cache hits:: before: $BEFORE, after: $AFTER"
15626         fi
15627
15628         if [ $OST1_VERSION -lt $(version_code 2.12.55) ]; then
15629                 # > 2.12.56 uses pagecache if cached
15630                 log "Read again; it should not be satisfied from the cache."
15631                 BEFORE=$AFTER
15632                 cancel_lru_locks osc
15633                 cat $file >/dev/null
15634                 AFTER=$(roc_hit)
15635                 if ! let "AFTER - BEFORE == 0"; then
15636                         error "IN CACHE (7): before: $BEFORE, after: $AFTER"
15637                 else
15638                         log "cache hits:: before: $BEFORE, after: $AFTER"
15639                 fi
15640         fi
15641
15642         log "Turn off read and write cache"
15643         set_cache read off
15644         set_cache writethrough off
15645
15646         log "Write data and read it back"
15647         log "It should not be satisfied from the cache."
15648         rm -f $file
15649         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
15650         cancel_lru_locks osc
15651         BEFORE=$(roc_hit)
15652         cat $file >/dev/null
15653         AFTER=$(roc_hit)
15654         if ! let "AFTER - BEFORE == 0"; then
15655                 error_ignore bz20762 "IN CACHE (8):before:$BEFORE,after:$AFTER"
15656         else
15657                 log "cache hits:: before: $BEFORE, after: $AFTER"
15658         fi
15659
15660         log "Turn on the read cache and turn off the write cache"
15661         set_cache read on
15662         set_cache writethrough off
15663
15664         log "Write data and read it back"
15665         log "It should not be satisfied from the cache."
15666         rm -f $file
15667         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
15668         BEFORE=$(roc_hit)
15669         cancel_lru_locks osc
15670         cat $file >/dev/null
15671         AFTER=$(roc_hit)
15672         if ! let "AFTER - BEFORE == 0"; then
15673                 error_ignore bz20762 "IN CACHE (9):before:$BEFORE,after:$AFTER"
15674         else
15675                 log "cache hits:: before: $BEFORE, after: $AFTER"
15676         fi
15677
15678         log "Read again; it should be satisfied from the cache."
15679         BEFORE=$(roc_hit)
15680         cancel_lru_locks osc
15681         cat $file >/dev/null
15682         AFTER=$(roc_hit)
15683         if ! let "AFTER - BEFORE == CPAGES"; then
15684                 error "NOT IN CACHE (1): before: $BEFORE, after: $AFTER"
15685         else
15686                 log "cache hits:: before: $BEFORE, after: $AFTER"
15687         fi
15688
15689         restore_lustre_params < $p
15690         rm -f $p $file
15691 }
15692 run_test 156 "Verification of tunables"
15693
15694 test_160a() {
15695         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15696         remote_mds_nodsh && skip "remote MDS with nodsh"
15697         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] ||
15698                 skip "Need MDS version at least 2.2.0"
15699
15700         changelog_register || error "changelog_register failed"
15701         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
15702         changelog_users $SINGLEMDS | grep -q $cl_user ||
15703                 error "User $cl_user not found in changelog_users"
15704
15705         mkdir_on_mdt0 $DIR/$tdir
15706
15707         # change something
15708         test_mkdir -p $DIR/$tdir/pics/2008/zachy
15709         changelog_clear 0 || error "changelog_clear failed"
15710         touch $DIR/$tdir/pics/2008/zachy/$tfile                 # open 1
15711         cp /etc/hosts $DIR/$tdir/pics/2008/zachy/pic1.jpg       # open 2
15712         mv $DIR/$tdir/pics/2008/zachy $DIR/$tdir/pics/zach
15713         ln $DIR/$tdir/pics/zach/pic1.jpg $DIR/$tdir/pics/2008/portland.jpg
15714         ln -s $DIR/$tdir/pics/2008/portland.jpg $DIR/$tdir/pics/desktop.jpg
15715         rm $DIR/$tdir/pics/desktop.jpg
15716
15717         echo "verifying changelog mask"
15718         changelog_chmask "-MKDIR"
15719         changelog_chmask "-CLOSE"
15720
15721         test_mkdir -p $DIR/$tdir/pics/zach/sofia                # not logged
15722         echo "zzzzzz" > $DIR/$tdir/pics/zach/file               # not logged
15723
15724         changelog_chmask "+MKDIR"
15725         changelog_chmask "+CLOSE"
15726
15727         test_mkdir -p $DIR/$tdir/pics/2008/sofia                # mkdir 1
15728         echo "zzzzzz" > $DIR/$tdir/pics/zach/file               # open 3
15729
15730         MKDIRS=$(changelog_dump | grep -c "MKDIR")
15731         CLOSES=$(changelog_dump | grep -c "CLOSE")
15732         [ $MKDIRS -eq 1 ] || error "MKDIR changelog mask count $MKDIRS != 1"
15733         [ $CLOSES -eq 3 ] || error "CLOSE changelog mask count $CLOSES != 3"
15734
15735         # verify contents
15736         echo "verifying target fid"
15737         local fidc=$(changelog_extract_field "CREAT" "$tfile" "t=")
15738         local fidf=$($LFS path2fid $DIR/$tdir/pics/zach/$tfile)
15739         [ "$fidc" == "$fidf" ] ||
15740                 error "changelog '$tfile' fid $fidc != file fid $fidf"
15741         echo "verifying parent fid"
15742         # The FID returned from the Changelog may be the directory shard on
15743         # a different MDT, and not the FID returned by path2fid on the parent.
15744         # Instead of comparing FIDs, verify that fid2path(fidp) is correct,
15745         # since this is what will matter when recreating this file in the tree.
15746         local fidp=$(changelog_extract_field "CREAT" "$tfile" "p=")
15747         local pathp=$($LFS fid2path $MOUNT "$fidp")
15748         [ "${pathp%/}" == "$DIR/$tdir/pics/zach" ] ||
15749                 error "changelog fid2path($fidc) $pathp != $DIR/$tdir/pics/zach"
15750
15751         echo "getting records for $cl_user"
15752         changelog_users $SINGLEMDS
15753         local user_rec1=$(changelog_user_rec $SINGLEMDS $cl_user)
15754         local nclr=3
15755         __changelog_clear $SINGLEMDS $cl_user +$nclr ||
15756                 error "changelog_clear failed"
15757         local user_rec2=$(changelog_user_rec $SINGLEMDS $cl_user)
15758         echo "verifying user clear: $user_rec1 + $nclr == $user_rec2"
15759         [ $user_rec2 == $((user_rec1 + nclr)) ] ||
15760                 error "user index expect $user_rec1 + $nclr != $user_rec2"
15761
15762         local min0_rec=$(changelog_users $SINGLEMDS |
15763                 awk 'min == "" || $2 < min { min = $2 }; END { print min }')
15764         local first_rec=$($LFS changelog $(facet_svc $SINGLEMDS) |
15765                           awk '{ print $1; exit; }')
15766
15767         changelog_dump | tail -n 5
15768         echo "verifying user min purge: $min0_rec + 1 == $first_rec"
15769         [ $first_rec == $((min0_rec + 1)) ] ||
15770                 error "first index should be $min0_rec + 1 not $first_rec"
15771
15772         # LU-3446 changelog index reset on MDT restart
15773         local cur_rec1=$(changelog_users $SINGLEMDS |
15774                          awk '/^current.index:/ { print $NF }')
15775         changelog_clear 0 ||
15776                 error "clear all changelog records for $cl_user failed"
15777         stop $SINGLEMDS || error "Fail to stop $SINGLEMDS"
15778         start $SINGLEMDS $(mdsdevname ${SINGLEMDS//mds/}) $MDS_MOUNT_OPTS ||
15779                 error "Fail to start $SINGLEMDS"
15780         local cur_rec2=$(changelog_users $SINGLEMDS |
15781                          awk '/^current.index:/ { print $NF }')
15782         echo "verifying index survives MDT restart: $cur_rec1 == $cur_rec2"
15783         [ $cur_rec1 == $cur_rec2 ] ||
15784                 error "current index should be $cur_rec1 not $cur_rec2"
15785
15786         echo "verifying users from this test are deregistered"
15787         changelog_deregister || error "changelog_deregister failed"
15788         changelog_users $SINGLEMDS | grep -q $cl_user &&
15789                 error "User '$cl_user' still in changelog_users"
15790
15791         # lctl get_param -n mdd.*.changelog_users
15792         # current_index: 144
15793         # ID    index (idle seconds)
15794         # cl3   144   (2) mask=<list>
15795         if [ -z "$(changelog_users $SINGLEMDS | grep -v current.index)" ]; then
15796                 # this is the normal case where all users were deregistered
15797                 # make sure no new records are added when no users are present
15798                 local last_rec1=$(changelog_users $SINGLEMDS |
15799                                   awk '/^current.index:/ { print $NF }')
15800                 touch $DIR/$tdir/chloe
15801                 local last_rec2=$(changelog_users $SINGLEMDS |
15802                                   awk '/^current.index:/ { print $NF }')
15803                 echo "verify changelogs are off: $last_rec1 == $last_rec2"
15804                 [ $last_rec1 == $last_rec2 ] || error "changelogs not off"
15805         else
15806                 # any changelog users must be leftovers from a previous test
15807                 changelog_users $SINGLEMDS
15808                 echo "other changelog users; can't verify off"
15809         fi
15810 }
15811 run_test 160a "changelog sanity"
15812
15813 test_160b() { # LU-3587
15814         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15815         remote_mds_nodsh && skip "remote MDS with nodsh"
15816         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] ||
15817                 skip "Need MDS version at least 2.2.0"
15818
15819         changelog_register || error "changelog_register failed"
15820         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
15821         changelog_users $SINGLEMDS | grep -q $cl_user ||
15822                 error "User '$cl_user' not found in changelog_users"
15823
15824         local longname1=$(str_repeat a 255)
15825         local longname2=$(str_repeat b 255)
15826
15827         cd $DIR
15828         echo "creating very long named file"
15829         touch $longname1 || error "create of '$longname1' failed"
15830         echo "renaming very long named file"
15831         mv $longname1 $longname2
15832
15833         changelog_dump | grep RENME | tail -n 5
15834         rm -f $longname2
15835 }
15836 run_test 160b "Verify that very long rename doesn't crash in changelog"
15837
15838 test_160c() {
15839         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15840         remote_mds_nodsh && skip "remote MDS with nodsh"
15841
15842         [[ $MDS1_VERSION -gt $(version_code 2.5.57) ]] ||
15843                 [[ $MDS1_VERSION -gt $(version_code 2.5.1) &&
15844                    $MDS1_VERSION -lt $(version_code 2.5.50) ]] ||
15845                 skip "Need MDS version at least 2.5.58 or 2.5.2+"
15846
15847         local rc=0
15848
15849         # Registration step
15850         changelog_register || error "changelog_register failed"
15851
15852         rm -rf $DIR/$tdir
15853         mkdir -p $DIR/$tdir
15854         $MCREATE $DIR/$tdir/foo_160c
15855         changelog_chmask "-TRUNC"
15856         $TRUNCATE $DIR/$tdir/foo_160c 200
15857         changelog_chmask "+TRUNC"
15858         $TRUNCATE $DIR/$tdir/foo_160c 199
15859         changelog_dump | tail -n 5
15860         local truncs=$(changelog_dump | tail -n 5 | grep -c TRUNC)
15861         [ $truncs -eq 1 ] || error "TRUNC changelog mask count $truncs != 1"
15862 }
15863 run_test 160c "verify that changelog log catch the truncate event"
15864
15865 test_160d() {
15866         remote_mds_nodsh && skip "remote MDS with nodsh"
15867         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
15868         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15869         [[ $MDS1_VERSION -ge $(version_code 2.7.60) ]] ||
15870                 skip "Need MDS version at least 2.7.60"
15871
15872         # Registration step
15873         changelog_register || error "changelog_register failed"
15874
15875         mkdir -p $DIR/$tdir/migrate_dir
15876         changelog_clear 0 || error "changelog_clear failed"
15877
15878         $LFS migrate -m 1 $DIR/$tdir/migrate_dir || error "migrate fails"
15879         changelog_dump | tail -n 5
15880         local migrates=$(changelog_dump | grep -c "MIGRT")
15881         [ $migrates -eq 1 ] || error "MIGRATE changelog count $migrates != 1"
15882 }
15883 run_test 160d "verify that changelog log catch the migrate event"
15884
15885 test_160e() {
15886         remote_mds_nodsh && skip "remote MDS with nodsh"
15887
15888         # Create a user
15889         changelog_register || error "changelog_register failed"
15890
15891         local MDT0=$(facet_svc $SINGLEMDS)
15892         local rc
15893
15894         # No user (expect fail)
15895         do_facet $SINGLEMDS $LCTL --device $MDT0 changelog_deregister
15896         rc=$?
15897         if [ $rc -eq 0 ]; then
15898                 error "Should fail without user"
15899         elif [ $rc -ne 4 ]; then
15900                 error "changelog_deregister failed with $rc, expect 4(CMD_HELP)"
15901         fi
15902
15903         # Delete a future user (expect fail)
15904         do_facet $SINGLEMDS $LCTL --device $MDT0 changelog_deregister "cl77"
15905         rc=$?
15906         if [ $rc -eq 0 ]; then
15907                 error "Deleted non-existant user cl77"
15908         elif [ $rc -ne 2 ]; then
15909                 error "changelog_deregister failed with $rc, expect 2 (ENOENT)"
15910         fi
15911
15912         # Clear to a bad index (1 billion should be safe)
15913         $LFS changelog_clear $MDT0 "${CL_USERS[$SINGLEMDS]%% *}" 1000000000
15914         rc=$?
15915
15916         if [ $rc -eq 0 ]; then
15917                 error "Successfully cleared to invalid CL index"
15918         elif [ $rc -ne 22 ]; then
15919                 error "changelog_clear failed with $rc, expected 22 (EINVAL)"
15920         fi
15921 }
15922 run_test 160e "changelog negative testing (should return errors)"
15923
15924 test_160f() {
15925         remote_mds_nodsh && skip "remote MDS with nodsh" && return
15926         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
15927                 skip "Need MDS version at least 2.10.56"
15928
15929         local mdts=$(comma_list $(mdts_nodes))
15930
15931         # Create a user
15932         changelog_register || error "first changelog_register failed"
15933         changelog_register || error "second changelog_register failed"
15934         local cl_users
15935         declare -A cl_user1
15936         declare -A cl_user2
15937         local user_rec1
15938         local user_rec2
15939         local i
15940
15941         # generate some changelog records to accumulate on each MDT
15942         # use all_char because created files should be evenly distributed
15943         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
15944                 error "test_mkdir $tdir failed"
15945         log "$(date +%s): creating first files"
15946         for ((i = 0; i < MDSCOUNT * 2; i++)); do
15947                 $LFS mkdir -i $((i%MDSCOUNT)) $DIR/$tdir/d$i.$((i/MDSCOUNT)) ||
15948                         error "create $DIR/$tdir/d$i.$((i/MDSCOUNT)) failed"
15949         done
15950
15951         # check changelogs have been generated
15952         local start=$SECONDS
15953         local idle_time=$((MDSCOUNT * 5 + 5))
15954         local nbcl=$(changelog_dump | wc -l)
15955         [[ $nbcl -eq 0 ]] && error "no changelogs found"
15956
15957         for param in "changelog_max_idle_time=$idle_time" \
15958                      "changelog_gc=1" \
15959                      "changelog_min_gc_interval=2" \
15960                      "changelog_min_free_cat_entries=3"; do
15961                 local MDT0=$(facet_svc $SINGLEMDS)
15962                 local var="${param%=*}"
15963                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
15964
15965                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
15966                 do_nodes $mdts $LCTL set_param mdd.*.$param
15967         done
15968
15969         # force cl_user2 to be idle (1st part), but also cancel the
15970         # cl_user1 records so that it is not evicted later in the test.
15971         local sleep1=$((idle_time / 2))
15972         echo "$(date +%s): sleep1 $sleep1/${idle_time}s"
15973         sleep $sleep1
15974
15975         # simulate changelog catalog almost full
15976         #define OBD_FAIL_CAT_FREE_RECORDS       0x1313
15977         do_nodes $mdts "$LCTL set_param fail_loc=0x1313 fail_val=3"
15978
15979         for i in $(seq $MDSCOUNT); do
15980                 cl_users=(${CL_USERS[mds$i]})
15981                 cl_user1[mds$i]="${cl_users[0]}"
15982                 cl_user2[mds$i]="${cl_users[1]}"
15983
15984                 [ -n "${cl_user1[mds$i]}" ] ||
15985                         error "mds$i: no user registered"
15986                 [ -n "${cl_user2[mds$i]}" ] ||
15987                         error "mds$i: only ${cl_user2[mds$i]} is registered"
15988
15989                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
15990                 [ -n "$user_rec1" ] ||
15991                         error "mds$i: User ${cl_user1[mds$i]} not registered"
15992                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
15993                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
15994                 [ -n "$user_rec2" ] ||
15995                         error "mds$i: User ${cl_user1[mds$i]} not registered"
15996                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
15997                      "$user_rec1 + 2 == $user_rec2"
15998                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
15999                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
16000                               "$user_rec1 + 2, but is $user_rec2"
16001                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
16002                 [ -n "$user_rec2" ] ||
16003                         error "mds$i: User ${cl_user2[mds$i]} not registered"
16004                 [ $user_rec1 == $user_rec2 ] ||
16005                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
16006                               "$user_rec1, but is $user_rec2"
16007         done
16008
16009         # force cl_user2 idle (2nd part) to just exceed changelog_max_idle_time
16010         local sleep2=$((idle_time - (SECONDS - start) + 1))
16011         echo "$(date +%s): sleep2 $sleep2/${idle_time}s"
16012         sleep $sleep2
16013
16014         # Generate one more changelog to trigger GC at fail_loc for cl_user2.
16015         # cl_user1 should be OK because it recently processed records.
16016         echo "$(date +%s): creating $((MDSCOUNT * 2)) files"
16017         for ((i = 0; i < MDSCOUNT * 2; i++)); do
16018                 $LFS mkdir -i $((i%MDSCOUNT)) $DIR/$tdir/d$i.$((i/MDSCOUNT+2))||
16019                         error "create $DIR/$tdir/d$i.$((i/MDSCOUNT+2)) failed"
16020         done
16021
16022         # ensure gc thread is done
16023         for i in $(mdts_nodes); do
16024                 wait_update $i "ps -e -o comm= | grep chlg_gc_thread" "" 20 ||
16025                         error "$i: GC-thread not done"
16026         done
16027
16028         local first_rec
16029         for (( i = 1; i <= MDSCOUNT; i++ )); do
16030                 # check cl_user1 still registered
16031                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
16032                         error "mds$i: User ${cl_user1[mds$i]} not registered"
16033                 # check cl_user2 unregistered
16034                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
16035                         error "mds$i: User ${cl_user2[mds$i]} still registered"
16036
16037                 # check changelogs are present and starting at $user_rec1 + 1
16038                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16039                 [ -n "$user_rec1" ] ||
16040                         error "mds$i: User ${cl_user1[mds$i]} not registered"
16041                 first_rec=$($LFS changelog $(facet_svc mds$i) |
16042                             awk '{ print $1; exit; }')
16043
16044                 echo "mds$i: $(date +%s) verify rec $user_rec1+1 == $first_rec"
16045                 [ $((user_rec1 + 1)) == $first_rec ] ||
16046                         error "mds$i: rec $first_rec != $user_rec1 + 1"
16047         done
16048 }
16049 run_test 160f "changelog garbage collect (timestamped users)"
16050
16051 test_160g() {
16052         remote_mds_nodsh && skip "remote MDS with nodsh"
16053         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
16054                 skip "Need MDS version at least 2.10.56"
16055
16056         local mdts=$(comma_list $(mdts_nodes))
16057
16058         #define OBD_FAIL_TIME_IN_CHLOG_USER     0x1314
16059         do_nodes $mdts $LCTL set_param fail_loc=0x1314
16060
16061         # Create a user
16062         changelog_register || error "first changelog_register failed"
16063         changelog_register || error "second changelog_register failed"
16064         local cl_users
16065         declare -A cl_user1
16066         declare -A cl_user2
16067         local user_rec1
16068         local user_rec2
16069         local i
16070
16071         # generate some changelog records to accumulate on each MDT
16072         # use all_char because created files should be evenly distributed
16073         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
16074                 error "test_mkdir $tdir failed"
16075         for ((i = 0; i < MDSCOUNT; i++)); do
16076                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
16077                         error "create $DIR/$tdir/d$i.1 failed"
16078         done
16079
16080         # check changelogs have been generated
16081         local nbcl=$(changelog_dump | wc -l)
16082         (( $nbcl > 0 )) || error "no changelogs found"
16083
16084         # reduce the max_idle_indexes value to make sure we exceed it
16085         for param in "changelog_max_idle_indexes=1" \
16086                      "changelog_gc=1" \
16087                      "changelog_min_gc_interval=2" \
16088                      "changelog_min_free_cat_entries=3"; do
16089                 local MDT0=$(facet_svc $SINGLEMDS)
16090                 local var="${param%=*}"
16091                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
16092
16093                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
16094                 do_nodes $mdts $LCTL set_param mdd.*.$param ||
16095                         error "unable to set mdd.*.$param"
16096         done
16097
16098         # simulate changelog catalog almost full
16099         #define OBD_FAIL_CAT_FREE_RECORDS       0x1313
16100         do_nodes $mdts "$LCTL set_param fail_loc=0x1313 fail_val=3"
16101
16102         local start=$SECONDS
16103         for i in $(seq $MDSCOUNT); do
16104                 cl_users=(${CL_USERS[mds$i]})
16105                 cl_user1[mds$i]="${cl_users[0]}"
16106                 cl_user2[mds$i]="${cl_users[1]}"
16107
16108                 [ -n "${cl_user1[mds$i]}" ] ||
16109                         error "mds$i: no user registered"
16110                 [ -n "${cl_user2[mds$i]}" ] ||
16111                         error "mds$i: only ${cl_user1[mds$i]} is registered"
16112
16113                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16114                 [ -n "$user_rec1" ] ||
16115                         error "mds$i: User ${cl_user1[mds$i]} not registered"
16116                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
16117                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16118                 [ -n "$user_rec2" ] ||
16119                         error "mds$i: User ${cl_user1[mds$i]} not registered"
16120                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
16121                      "$user_rec1 + 2 == $user_rec2"
16122                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
16123                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
16124                               "$user_rec1 + 2, but is $user_rec2"
16125                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
16126                 [ -n "$user_rec2" ] ||
16127                         error "mds$i: User ${cl_user2[mds$i]} not registered"
16128                 [ $user_rec1 == $user_rec2 ] ||
16129                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
16130                               "$user_rec1, but is $user_rec2"
16131         done
16132
16133         # ensure we are past the previous changelog_min_gc_interval set above
16134         local sleep2=$((start + 2 - SECONDS))
16135         (( sleep2 > 0 )) && echo "sleep $sleep2 for interval" && sleep $sleep2
16136
16137         # Generate one more changelog to trigger GC at fail_loc for cl_user2.
16138         # cl_user1 should be OK because it recently processed records.
16139         for ((i = 0; i < MDSCOUNT; i++)); do
16140                 $LFS mkdir -i $i $DIR/$tdir/d$i.3 $DIR/$tdir/d$i.4 ||
16141                         error "create $DIR/$tdir/d$i.3 failed"
16142         done
16143
16144         # ensure gc thread is done
16145         for i in $(mdts_nodes); do
16146                 wait_update $i "ps -e -o comm= | grep chlg_gc_thread" "" 20 ||
16147                         error "$i: GC-thread not done"
16148         done
16149
16150         local first_rec
16151         for (( i = 1; i <= MDSCOUNT; i++ )); do
16152                 # check cl_user1 still registered
16153                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
16154                         error "mds$i: User ${cl_user1[mds$i]} not registered"
16155                 # check cl_user2 unregistered
16156                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
16157                         error "mds$i: User ${cl_user2[mds$i]} still registered"
16158
16159                 # check changelogs are present and starting at $user_rec1 + 1
16160                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16161                 [ -n "$user_rec1" ] ||
16162                         error "mds$i: User ${cl_user1[mds$i]} not registered"
16163                 first_rec=$($LFS changelog $(facet_svc mds$i) |
16164                             awk '{ print $1; exit; }')
16165
16166                 echo "mds$i: $(date +%s) verify rec $user_rec1+1 == $first_rec"
16167                 [ $((user_rec1 + 1)) == $first_rec ] ||
16168                         error "mds$i: rec $first_rec != $user_rec1 + 1"
16169         done
16170 }
16171 run_test 160g "changelog garbage collect (old users)"
16172
16173 test_160h() {
16174         remote_mds_nodsh && skip "remote MDS with nodsh" && return
16175         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
16176                 skip "Need MDS version at least 2.10.56"
16177
16178         local mdts=$(comma_list $(mdts_nodes))
16179
16180         # Create a user
16181         changelog_register || error "first changelog_register failed"
16182         changelog_register || error "second changelog_register failed"
16183         local cl_users
16184         declare -A cl_user1
16185         declare -A cl_user2
16186         local user_rec1
16187         local user_rec2
16188         local i
16189
16190         # generate some changelog records to accumulate on each MDT
16191         # use all_char because created files should be evenly distributed
16192         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
16193                 error "test_mkdir $tdir failed"
16194         for ((i = 0; i < MDSCOUNT; i++)); do
16195                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
16196                         error "create $DIR/$tdir/d$i.1 failed"
16197         done
16198
16199         # check changelogs have been generated
16200         local nbcl=$(changelog_dump | wc -l)
16201         [[ $nbcl -eq 0 ]] && error "no changelogs found"
16202
16203         for param in "changelog_max_idle_time=10" \
16204                      "changelog_gc=1" \
16205                      "changelog_min_gc_interval=2"; do
16206                 local MDT0=$(facet_svc $SINGLEMDS)
16207                 local var="${param%=*}"
16208                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
16209
16210                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
16211                 do_nodes $mdts $LCTL set_param mdd.*.$param
16212         done
16213
16214         # force cl_user2 to be idle (1st part)
16215         sleep 9
16216
16217         for i in $(seq $MDSCOUNT); do
16218                 cl_users=(${CL_USERS[mds$i]})
16219                 cl_user1[mds$i]="${cl_users[0]}"
16220                 cl_user2[mds$i]="${cl_users[1]}"
16221
16222                 [ -n "${cl_user1[mds$i]}" ] ||
16223                         error "mds$i: no user registered"
16224                 [ -n "${cl_user2[mds$i]}" ] ||
16225                         error "mds$i: only ${cl_user2[mds$i]} is registered"
16226
16227                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16228                 [ -n "$user_rec1" ] ||
16229                         error "mds$i: User ${cl_user1[mds$i]} not registered"
16230                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
16231                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16232                 [ -n "$user_rec2" ] ||
16233                         error "mds$i: User ${cl_user1[mds$i]} not registered"
16234                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
16235                      "$user_rec1 + 2 == $user_rec2"
16236                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
16237                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
16238                               "$user_rec1 + 2, but is $user_rec2"
16239                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
16240                 [ -n "$user_rec2" ] ||
16241                         error "mds$i: User ${cl_user2[mds$i]} not registered"
16242                 [ $user_rec1 == $user_rec2 ] ||
16243                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
16244                               "$user_rec1, but is $user_rec2"
16245         done
16246
16247         # force cl_user2 to be idle (2nd part) and to reach
16248         # changelog_max_idle_time
16249         sleep 2
16250
16251         # force each GC-thread start and block then
16252         # one per MDT/MDD, set fail_val accordingly
16253         #define OBD_FAIL_FORCE_GC_THREAD 0x1316
16254         do_nodes $mdts $LCTL set_param fail_loc=0x1316
16255
16256         # generate more changelogs to trigger fail_loc
16257         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
16258                 error "create $DIR/$tdir/${tfile}bis failed"
16259
16260         # stop MDT to stop GC-thread, should be done in back-ground as it will
16261         # block waiting for the thread to be released and exit
16262         declare -A stop_pids
16263         for i in $(seq $MDSCOUNT); do
16264                 stop mds$i &
16265                 stop_pids[mds$i]=$!
16266         done
16267
16268         for i in $(mdts_nodes); do
16269                 local facet
16270                 local nb=0
16271                 local facets=$(facets_up_on_host $i)
16272
16273                 for facet in ${facets//,/ }; do
16274                         if [[ $facet == mds* ]]; then
16275                                 nb=$((nb + 1))
16276                         fi
16277                 done
16278                 # ensure each MDS's gc threads are still present and all in "R"
16279                 # state (OBD_FAIL_FORCE_GC_THREAD effect!)
16280                 [[ $(do_node $i pgrep chlg_gc_thread | wc -l) -eq $nb ]] ||
16281                         error "$i: expected $nb GC-thread"
16282                 wait_update $i \
16283                         "ps -C chlg_gc_thread -o state --no-headers | uniq" \
16284                         "R" 20 ||
16285                         error "$i: GC-thread not found in R-state"
16286                 # check umounts of each MDT on MDS have reached kthread_stop()
16287                 [[ $(do_node $i pgrep umount | wc -l) -eq $nb ]] ||
16288                         error "$i: expected $nb umount"
16289                 wait_update $i \
16290                         "ps -C umount -o state --no-headers | uniq" "D" 20 ||
16291                         error "$i: umount not found in D-state"
16292         done
16293
16294         # release all GC-threads
16295         do_nodes $mdts $LCTL set_param fail_loc=0
16296
16297         # wait for MDT stop to complete
16298         for i in $(seq $MDSCOUNT); do
16299                 wait ${stop_pids[mds$i]} || error "mds$i: stop failed"
16300         done
16301
16302         # XXX
16303         # may try to check if any orphan changelog records are present
16304         # via ldiskfs/zfs and llog_reader...
16305
16306         # re-start/mount MDTs
16307         for i in $(seq $MDSCOUNT); do
16308                 start mds$i $(mdsdevname $i) $MDS_MOUNT_OPTS ||
16309                         error "Fail to start mds$i"
16310         done
16311
16312         local first_rec
16313         for i in $(seq $MDSCOUNT); do
16314                 # check cl_user1 still registered
16315                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
16316                         error "mds$i: User ${cl_user1[mds$i]} not registered"
16317                 # check cl_user2 unregistered
16318                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
16319                         error "mds$i: User ${cl_user2[mds$i]} still registered"
16320
16321                 # check changelogs are present and starting at $user_rec1 + 1
16322                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16323                 [ -n "$user_rec1" ] ||
16324                         error "mds$i: User ${cl_user1[mds$i]} not registered"
16325                 first_rec=$($LFS changelog $(facet_svc mds$i) |
16326                             awk '{ print $1; exit; }')
16327
16328                 echo "mds$i: verifying first index $user_rec1 + 1 == $first_rec"
16329                 [ $((user_rec1 + 1)) == $first_rec ] ||
16330                         error "mds$i: first index should be $user_rec1 + 1, " \
16331                               "but is $first_rec"
16332         done
16333 }
16334 run_test 160h "changelog gc thread stop upon umount, orphan records delete " \
16335               "during mount"
16336
16337 test_160i() {
16338
16339         local mdts=$(comma_list $(mdts_nodes))
16340
16341         changelog_register || error "first changelog_register failed"
16342
16343         # generate some changelog records to accumulate on each MDT
16344         # use all_char because created files should be evenly distributed
16345         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
16346                 error "test_mkdir $tdir failed"
16347         for ((i = 0; i < MDSCOUNT; i++)); do
16348                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
16349                         error "create $DIR/$tdir/d$i.1 failed"
16350         done
16351
16352         # check changelogs have been generated
16353         local nbcl=$(changelog_dump | wc -l)
16354         [[ $nbcl -eq 0 ]] && error "no changelogs found"
16355
16356         # simulate race between register and unregister
16357         # XXX as fail_loc is set per-MDS, with DNE configs the race
16358         # simulation will only occur for one MDT per MDS and for the
16359         # others the normal race scenario will take place
16360         #define CFS_FAIL_CHLOG_USER_REG_UNREG_RACE          0x1315
16361         do_nodes $mdts $LCTL set_param fail_loc=0x10001315
16362         do_nodes $mdts $LCTL set_param fail_val=1
16363
16364         # unregister 1st user
16365         changelog_deregister &
16366         local pid1=$!
16367         # wait some time for deregister work to reach race rdv
16368         sleep 2
16369         # register 2nd user
16370         changelog_register || error "2nd user register failed"
16371
16372         wait $pid1 || error "1st user deregister failed"
16373
16374         local i
16375         local last_rec
16376         declare -A LAST_REC
16377         for i in $(seq $MDSCOUNT); do
16378                 if changelog_users mds$i | grep "^cl"; then
16379                         # make sure new records are added with one user present
16380                         LAST_REC[mds$i]=$(changelog_users $SINGLEMDS |
16381                                           awk '/^current.index:/ { print $NF }')
16382                 else
16383                         error "mds$i has no user registered"
16384                 fi
16385         done
16386
16387         # generate more changelog records to accumulate on each MDT
16388         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
16389                 error "create $DIR/$tdir/${tfile}bis failed"
16390
16391         for i in $(seq $MDSCOUNT); do
16392                 last_rec=$(changelog_users $SINGLEMDS |
16393                            awk '/^current.index:/ { print $NF }')
16394                 echo "verify changelogs are on: $last_rec != ${LAST_REC[mds$i]}"
16395                 [ $last_rec != ${LAST_REC[mds$i]} ] ||
16396                         error "changelogs are off on mds$i"
16397         done
16398 }
16399 run_test 160i "changelog user register/unregister race"
16400
16401 test_160j() {
16402         remote_mds_nodsh && skip "remote MDS with nodsh"
16403         [[ $MDS1_VERSION -lt $(version_code 2.12.56) ]] &&
16404                 skip "Need MDS version at least 2.12.56"
16405
16406         mount_client $MOUNT2 || error "mount_client on $MOUNT2 failed"
16407         stack_trap "umount $MOUNT2" EXIT
16408
16409         changelog_register || error "first changelog_register failed"
16410         stack_trap "changelog_deregister" EXIT
16411
16412         # generate some changelog
16413         # use all_char because created files should be evenly distributed
16414         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
16415                 error "mkdir $tdir failed"
16416         for ((i = 0; i < MDSCOUNT; i++)); do
16417                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
16418                         error "create $DIR/$tdir/d$i.1 failed"
16419         done
16420
16421         # open the changelog device
16422         exec 3>/dev/changelog-$FSNAME-MDT0000
16423         stack_trap "exec 3>&-" EXIT
16424         exec 4</dev/changelog-$FSNAME-MDT0000
16425         stack_trap "exec 4<&-" EXIT
16426
16427         # umount the first lustre mount
16428         umount $MOUNT
16429         stack_trap "mount_client $MOUNT" EXIT
16430
16431         # read changelog, which may or may not fail, but should not crash
16432         cat <&4 >/dev/null
16433
16434         # clear changelog
16435         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
16436         changelog_users $SINGLEMDS | grep -q $cl_user ||
16437                 error "User $cl_user not found in changelog_users"
16438
16439         printf 'clear:'$cl_user':0' >&3
16440 }
16441 run_test 160j "client can be umounted while its chanangelog is being used"
16442
16443 test_160k() {
16444         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16445         remote_mds_nodsh && skip "remote MDS with nodsh"
16446
16447         mkdir -p $DIR/$tdir/1/1
16448
16449         changelog_register || error "changelog_register failed"
16450         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
16451
16452         changelog_users $SINGLEMDS | grep -q $cl_user ||
16453                 error "User '$cl_user' not found in changelog_users"
16454 #define OBD_FAIL_MDS_CHANGELOG_REORDER 0x15d
16455         do_facet mds1 $LCTL set_param fail_loc=0x8000015d fail_val=3
16456         rmdir $DIR/$tdir/1/1 & sleep 1
16457         mkdir $DIR/$tdir/2
16458         touch $DIR/$tdir/2/2
16459         rm -rf $DIR/$tdir/2
16460
16461         wait
16462         sleep 4
16463
16464         changelog_dump | grep rmdir || error "rmdir not recorded"
16465 }
16466 run_test 160k "Verify that changelog records are not lost"
16467
16468 # Verifies that a file passed as a parameter has recently had an operation
16469 # performed on it that has generated an MTIME changelog which contains the
16470 # correct parent FID. As files might reside on a different MDT from the
16471 # parent directory in DNE configurations, the FIDs are translated to paths
16472 # before being compared, which should be identical
16473 compare_mtime_changelog() {
16474         local file="${1}"
16475         local mdtidx
16476         local mtime
16477         local cl_fid
16478         local pdir
16479         local dir
16480
16481         mdtidx=$($LFS getstripe --mdt-index $file)
16482         mdtidx=$(printf "%04x" $mdtidx)
16483
16484         # Obtain the parent FID from the MTIME changelog
16485         mtime=$($LFS changelog $FSNAME-MDT$mdtidx | tail -n 1 | grep MTIME)
16486         [ -z "$mtime" ] && error "MTIME changelog not recorded"
16487
16488         cl_fid=$(sed -e 's/.* p=//' -e 's/ .*//' <<<$mtime)
16489         [ -z "$cl_fid" ] && error "parent FID not present"
16490
16491         # Verify that the path for the parent FID is the same as the path for
16492         # the test directory
16493         pdir=$($LFS fid2path $MOUNT "$cl_fid")
16494
16495         dir=$(dirname $1)
16496
16497         [[ "${pdir%/}" == "$dir" ]] ||
16498                 error "MTIME changelog parent FID is wrong, expected $dir, got $pdir"
16499 }
16500
16501 test_160l() {
16502         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16503
16504         remote_mds_nodsh && skip "remote MDS with nodsh"
16505         [[ $MDS1_VERSION -ge $(version_code 2.13.55) ]] ||
16506                 skip "Need MDS version at least 2.13.55"
16507
16508         local cl_user
16509
16510         changelog_register || error "changelog_register failed"
16511         cl_user="${CL_USERS[$SINGLEMDS]%% *}"
16512
16513         changelog_users $SINGLEMDS | grep -q $cl_user ||
16514                 error "User '$cl_user' not found in changelog_users"
16515
16516         # Clear some types so that MTIME changelogs are generated
16517         changelog_chmask "-CREAT"
16518         changelog_chmask "-CLOSE"
16519
16520         test_mkdir $DIR/$tdir || error "failed to mkdir $DIR/$tdir"
16521
16522         # Test CL_MTIME during setattr
16523         touch $DIR/$tdir/$tfile
16524         compare_mtime_changelog $DIR/$tdir/$tfile
16525
16526         # Test CL_MTIME during close
16527         $MULTIOP $DIR/$tdir/${tfile}_2 O_2w4096c || error "multiop failed"
16528         compare_mtime_changelog $DIR/$tdir/${tfile}_2
16529 }
16530 run_test 160l "Verify that MTIME changelog records contain the parent FID"
16531
16532 test_160m() {
16533         remote_mds_nodsh && skip "remote MDS with nodsh" && return
16534         [[ $MDS1_VERSION -ge $(version_code 2.14.51) ]] ||
16535                 skip "Need MDS version at least 2.14.51"
16536         local cl_users
16537         local cl_user1
16538         local cl_user2
16539         local pid1
16540
16541         # Create a user
16542         changelog_register || error "first changelog_register failed"
16543         changelog_register || error "second changelog_register failed"
16544
16545         cl_users=(${CL_USERS[mds1]})
16546         cl_user1="${cl_users[0]}"
16547         cl_user2="${cl_users[1]}"
16548         # generate some changelog records to accumulate on MDT0
16549         test_mkdir -p -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
16550         createmany -m $DIR/$tdir/$tfile 50 ||
16551                 error "create $DIR/$tdir/$tfile failed"
16552         unlinkmany $DIR/$tdir/$tfile 50 || error "unlinkmany failed"
16553         rm -f $DIR/$tdir
16554
16555         # check changelogs have been generated
16556         local nbcl=$(changelog_dump | wc -l)
16557         [[ $nbcl -eq 0 ]] && error "no changelogs found"
16558
16559 #define OBD_FAIL_MDS_CHANGELOG_RACE      0x15f
16560         do_facet mds1 $LCTL set_param fail_loc=0x8000015f fail_val=0
16561
16562         __changelog_clear mds1 $cl_user1 +10
16563         __changelog_clear mds1 $cl_user2 0 &
16564         pid1=$!
16565         sleep 2
16566         __changelog_clear mds1 $cl_user1 0 ||
16567                 error "fail to cancel record for $cl_user1"
16568         wait $pid1
16569         [[ $? -eq 0 ]] || error "fail to cancel record for $cl_user2"
16570 }
16571 run_test 160m "Changelog clear race"
16572
16573 test_160n() {
16574         remote_mds_nodsh && skip "remote MDS with nodsh" && return
16575         [[ $MDS1_VERSION -ge $(version_code 2.14.51) ]] ||
16576                 skip "Need MDS version at least 2.14.51"
16577         local cl_users
16578         local cl_user1
16579         local cl_user2
16580         local pid1
16581         local first_rec
16582         local last_rec=0
16583
16584         # Create a user
16585         changelog_register || error "first changelog_register failed"
16586
16587         cl_users=(${CL_USERS[mds1]})
16588         cl_user1="${cl_users[0]}"
16589
16590         # generate some changelog records to accumulate on MDT0
16591         test_mkdir -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
16592         first_rec=$(changelog_users $SINGLEMDS |
16593                         awk '/^current.index:/ { print $NF }')
16594         while (( last_rec < (( first_rec + 65000)) )); do
16595                 createmany -m $DIR/$tdir/$tfile 10000 ||
16596                         error "create $DIR/$tdir/$tfile failed"
16597
16598                 for i in $(seq 0 10000); do
16599                         mrename $DIR/$tdir/$tfile$i $DIR/$tdir/$tfile-new$i \
16600                                 > /dev/null
16601                 done
16602
16603                 unlinkmany $DIR/$tdir/$tfile-new 10000 ||
16604                         error "unlinkmany failed unlink"
16605                 last_rec=$(changelog_users $SINGLEMDS |
16606                         awk '/^current.index:/ { print $NF }')
16607                 echo last record $last_rec
16608                 (( last_rec == 0 )) && error "no changelog found"
16609         done
16610
16611 #define OBD_FAIL_MDS_CHANGELOG_DEL       0x16c
16612         do_facet mds1 $LCTL set_param fail_loc=0x8000016c fail_val=0
16613
16614         __changelog_clear mds1 $cl_user1 0 &
16615         pid1=$!
16616         sleep 2
16617         __changelog_clear mds1 $cl_user1 0 ||
16618                 error "fail to cancel record for $cl_user1"
16619         wait $pid1
16620         [[ $? -eq 0 ]] || error "fail to cancel record for $cl_user2"
16621 }
16622 run_test 160n "Changelog destroy race"
16623
16624 test_160o() {
16625         local mdt="$(facet_svc $SINGLEMDS)"
16626
16627         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
16628         remote_mds_nodsh && skip "remote MDS with nodsh"
16629         [ $MDS1_VERSION -ge $(version_code 2.14.52) ] ||
16630                 skip "Need MDS version at least 2.14.52"
16631
16632         changelog_register --user test_160o -m unlnk+close+open ||
16633                 error "changelog_register failed"
16634
16635         do_facet $SINGLEMDS $LCTL --device $mdt \
16636                                 changelog_register -u "Tt3_-#" &&
16637                 error "bad symbols in name should fail"
16638
16639         do_facet $SINGLEMDS $LCTL --device $mdt \
16640                                 changelog_register -u test_160o &&
16641                 error "the same name registration should fail"
16642
16643         do_facet $SINGLEMDS $LCTL --device $mdt \
16644                         changelog_register -u test_160toolongname &&
16645                 error "too long name registration should fail"
16646
16647         changelog_chmask "MARK+HSM"
16648         lctl get_param mdd.*.changelog*mask
16649         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
16650         changelog_users $SINGLEMDS | grep -q $cl_user ||
16651                 error "User $cl_user not found in changelog_users"
16652         #verify username
16653         echo $cl_user | grep -q test_160o ||
16654                 error "User $cl_user has no specific name 'test160o'"
16655
16656         # change something
16657         changelog_clear 0 || error "changelog_clear failed"
16658         # generate some changelog records to accumulate on MDT0
16659         test_mkdir -p -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
16660         touch $DIR/$tdir/$tfile                 # open 1
16661
16662         OPENS=$(changelog_dump | grep -c "OPEN")
16663         [[ $OPENS -eq 1 ]] || error "OPEN changelog mask count $OPENS != 1"
16664
16665         # must be no MKDIR it wasn't set as user mask
16666         MKDIR=$(changelog_dump | grep -c "MKDIR")
16667         [[ $MKDIR -eq 0 ]] || error "MKDIR changelog mask found $MKDIR > 0"
16668
16669         oldmask=$(do_facet $SINGLEMDS $LCTL get_param \
16670                                 mdd.$mdt.changelog_current_mask -n)
16671         # register maskless user
16672         changelog_register || error "changelog_register failed"
16673         # effective mask should be not changed because it is not minimal
16674         mask=$(do_facet $SINGLEMDS $LCTL get_param \
16675                                 mdd.$mdt.changelog_current_mask -n)
16676         [[ $mask == $oldmask ]] || error "mask was changed: $mask vs $oldmask"
16677         # set server mask to minimal value
16678         changelog_chmask "MARK"
16679         # check effective mask again, should be treated as DEFMASK now
16680         mask=$(do_facet $SINGLEMDS $LCTL get_param \
16681                                 mdd.$mdt.changelog_current_mask -n)
16682         [[ $mask == *"HLINK"* ]] || error "mask is not DEFMASK as expected"
16683
16684         do_facet $SINGLEMDS $LCTL --device $mdt \
16685                                 changelog_deregister -u test_160o ||
16686                 error "cannot deregister by name"
16687 }
16688 run_test 160o "changelog user name and mask"
16689
16690 test_160p() {
16691         remote_mds_nodsh && skip "remote MDS with nodsh" && return
16692         [[ $MDS1_VERSION -ge $(version_code 2.14.51) ]] ||
16693                 skip "Need MDS version at least 2.14.51"
16694         [[ "$mds1_FSTYPE" == "ldiskfs" ]] || skip "ldiskfs only test"
16695         local cl_users
16696         local cl_user1
16697         local entry_count
16698
16699         # Create a user
16700         changelog_register || error "first changelog_register failed"
16701
16702         cl_users=(${CL_USERS[mds1]})
16703         cl_user1="${cl_users[0]}"
16704
16705         test_mkdir -p -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
16706         createmany -m $DIR/$tdir/$tfile 50 ||
16707                 error "create $DIR/$tdir/$tfile failed"
16708         unlinkmany $DIR/$tdir/$tfile 50 || error "unlinkmany failed"
16709         rm -rf $DIR/$tdir
16710
16711         # check changelogs have been generated
16712         entry_count=$(changelog_dump | wc -l)
16713         ((entry_count != 0)) || error "no changelog entries found"
16714
16715         # remove changelog_users and check that orphan entries are removed
16716         stop mds1
16717         do_facet mds1 "$DEBUGFS -w -R 'rm changelog_users' $(mdsdevname 1)"
16718         start mds1 || error "cannot start mdt"
16719         entry_count=$(changelog_dump | wc -l)
16720         ((entry_count == 0)) ||
16721                 error "found $entry_count changelog entries, expected none"
16722 }
16723 run_test 160p "Changelog orphan cleanup with no users"
16724
16725 test_160q() {
16726         local mdt="$(facet_svc $SINGLEMDS)"
16727         local clu
16728
16729         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
16730         remote_mds_nodsh && skip "remote MDS with nodsh"
16731         [ $MDS1_VERSION -ge $(version_code 2.14.54) ] ||
16732                 skip "Need MDS version at least 2.14.54"
16733
16734         # set server mask to minimal value like server init does
16735         changelog_chmask "MARK"
16736         clu=$(do_facet $SINGLEMDS $LCTL --device $mdt changelog_register -n) ||
16737                 error "changelog_register failed"
16738         # check effective mask again, should be treated as DEFMASK now
16739         mask=$(do_facet $SINGLEMDS $LCTL get_param \
16740                                 mdd.$mdt.changelog_current_mask -n)
16741         do_facet $SINGLEMDS $LCTL --device $mdt changelog_deregister $clu ||
16742                 error "changelog_deregister failed"
16743         [[ $mask == *"HLINK"* ]] || error "mask is not DEFMASK as expected"
16744 }
16745 run_test 160q "changelog effective mask is DEFMASK if not set"
16746
16747 test_161a() {
16748         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16749
16750         test_mkdir -c1 $DIR/$tdir
16751         cp /etc/hosts $DIR/$tdir/$tfile
16752         test_mkdir -c1 $DIR/$tdir/foo1
16753         test_mkdir -c1 $DIR/$tdir/foo2
16754         ln $DIR/$tdir/$tfile $DIR/$tdir/foo1/sofia
16755         ln $DIR/$tdir/$tfile $DIR/$tdir/foo2/zachary
16756         ln $DIR/$tdir/$tfile $DIR/$tdir/foo1/luna
16757         ln $DIR/$tdir/$tfile $DIR/$tdir/foo2/thor
16758         local FID=$($LFS path2fid $DIR/$tdir/$tfile | tr -d '[]')
16759         if [ "$($LFS fid2path $DIR $FID | wc -l)" != "5" ]; then
16760                 $LFS fid2path $DIR $FID
16761                 error "bad link ea"
16762         fi
16763         # middle
16764         rm $DIR/$tdir/foo2/zachary
16765         # last
16766         rm $DIR/$tdir/foo2/thor
16767         # first
16768         rm $DIR/$tdir/$tfile
16769         # rename
16770         mv $DIR/$tdir/foo1/sofia $DIR/$tdir/foo2/maggie
16771         [ "$($LFS fid2path $FSNAME --link 1 $FID)" != "$tdir/foo2/maggie" ] &&
16772                 { $LFS fid2path $DIR $FID; error "bad link rename"; }
16773         rm $DIR/$tdir/foo2/maggie
16774
16775         # overflow the EA
16776         local longname=$tfile.avg_len_is_thirty_two_
16777         stack_trap "unlinkmany $DIR/$tdir/foo2/$longname 1000 || \
16778                 error_noexit 'failed to unlink many hardlinks'" EXIT
16779         createmany -l$DIR/$tdir/foo1/luna $DIR/$tdir/foo2/$longname 1000 ||
16780                 error "failed to hardlink many files"
16781         links=$($LFS fid2path $DIR $FID | wc -l)
16782         echo -n "${links}/1000 links in link EA"
16783         [[ $links -gt 60 ]] || error "expected at least 60 links in link EA"
16784 }
16785 run_test 161a "link ea sanity"
16786
16787 test_161b() {
16788         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16789         [ $MDSCOUNT -lt 2 ] && skip_env "skipping remote directory test"
16790
16791         local MDTIDX=1
16792         local remote_dir=$DIR/$tdir/remote_dir
16793
16794         mkdir -p $DIR/$tdir
16795         $LFS mkdir -i $MDTIDX $remote_dir ||
16796                 error "create remote directory failed"
16797
16798         cp /etc/hosts $remote_dir/$tfile
16799         mkdir -p $remote_dir/foo1
16800         mkdir -p $remote_dir/foo2
16801         ln $remote_dir/$tfile $remote_dir/foo1/sofia
16802         ln $remote_dir/$tfile $remote_dir/foo2/zachary
16803         ln $remote_dir/$tfile $remote_dir/foo1/luna
16804         ln $remote_dir/$tfile $remote_dir/foo2/thor
16805
16806         local FID=$($LFS path2fid $remote_dir/$tfile | tr -d '[' |
16807                      tr -d ']')
16808         if [ "$($LFS fid2path $DIR $FID | wc -l)" != "5" ]; then
16809                 $LFS fid2path $DIR $FID
16810                 error "bad link ea"
16811         fi
16812         # middle
16813         rm $remote_dir/foo2/zachary
16814         # last
16815         rm $remote_dir/foo2/thor
16816         # first
16817         rm $remote_dir/$tfile
16818         # rename
16819         mv $remote_dir/foo1/sofia $remote_dir/foo2/maggie
16820         local link_path=$($LFS fid2path $FSNAME --link 1 $FID)
16821         if [ "$DIR/$link_path" != "$remote_dir/foo2/maggie" ]; then
16822                 $LFS fid2path $DIR $FID
16823                 error "bad link rename"
16824         fi
16825         rm $remote_dir/foo2/maggie
16826
16827         # overflow the EA
16828         local longname=filename_avg_len_is_thirty_two_
16829         createmany -l$remote_dir/foo1/luna $remote_dir/foo2/$longname 1000 ||
16830                 error "failed to hardlink many files"
16831         links=$($LFS fid2path $DIR $FID | wc -l)
16832         echo -n "${links}/1000 links in link EA"
16833         [[ ${links} -gt 60 ]] ||
16834                 error "expected at least 60 links in link EA"
16835         unlinkmany $remote_dir/foo2/$longname 1000 ||
16836         error "failed to unlink many hardlinks"
16837 }
16838 run_test 161b "link ea sanity under remote directory"
16839
16840 test_161c() {
16841         remote_mds_nodsh && skip "remote MDS with nodsh"
16842         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16843         [[ $MDS1_VERSION -lt $(version_code 2.1.5) ]] &&
16844                 skip "Need MDS version at least 2.1.5"
16845
16846         # define CLF_RENAME_LAST 0x0001
16847         # rename overwrite a target having nlink = 1 (changelog flag 0x1)
16848         changelog_register || error "changelog_register failed"
16849
16850         rm -rf $DIR/$tdir
16851         test_mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir
16852         touch $DIR/$tdir/foo_161c
16853         touch $DIR/$tdir/bar_161c
16854         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/bar_161c
16855         changelog_dump | grep RENME | tail -n 5
16856         local flags=$(changelog_dump | grep "RENME.*bar_161c" | cut -f5 -d' ')
16857         changelog_clear 0 || error "changelog_clear failed"
16858         if [ x$flags != "x0x1" ]; then
16859                 error "flag $flags is not 0x1"
16860         fi
16861
16862         echo "rename overwrite target with nlink = 1, changelog flags=$flags"
16863         # rename overwrite a target having nlink > 1 (changelog flag 0x0)
16864         touch $DIR/$tdir/foo_161c
16865         touch $DIR/$tdir/bar_161c
16866         ln $DIR/$tdir/bar_161c $DIR/$tdir/foobar_161c
16867         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/bar_161c
16868         changelog_dump | grep RENME | tail -n 5
16869         flags=$(changelog_dump | grep "RENME.*bar_161c" | cut -f5 -d' ')
16870         changelog_clear 0 || error "changelog_clear failed"
16871         if [ x$flags != "x0x0" ]; then
16872                 error "flag $flags is not 0x0"
16873         fi
16874         echo "rename overwrite a target having nlink > 1," \
16875                 "changelog record has flags of $flags"
16876
16877         # rename doesn't overwrite a target (changelog flag 0x0)
16878         touch $DIR/$tdir/foo_161c
16879         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/foo2_161c
16880         changelog_dump | grep RENME | tail -n 5
16881         flags=$(changelog_dump | grep RENME | tail -1 | cut -f5 -d' ')
16882         changelog_clear 0 || error "changelog_clear failed"
16883         if [ x$flags != "x0x0" ]; then
16884                 error "flag $flags is not 0x0"
16885         fi
16886         echo "rename doesn't overwrite a target," \
16887                 "changelog record has flags of $flags"
16888
16889         # define CLF_UNLINK_LAST 0x0001
16890         # unlink a file having nlink = 1 (changelog flag 0x1)
16891         rm -f $DIR/$tdir/foo2_161c
16892         changelog_dump | grep UNLNK | tail -n 5
16893         flags=$(changelog_dump | grep UNLNK | tail -1 | cut -f5 -d' ')
16894         changelog_clear 0 || error "changelog_clear failed"
16895         if [ x$flags != "x0x1" ]; then
16896                 error "flag $flags is not 0x1"
16897         fi
16898         echo "unlink a file having nlink = 1," \
16899                 "changelog record has flags of $flags"
16900
16901         # unlink a file having nlink > 1 (changelog flag 0x0)
16902         ln -f $DIR/$tdir/bar_161c $DIR/$tdir/foobar_161c
16903         rm -f $DIR/$tdir/foobar_161c
16904         changelog_dump | grep UNLNK | tail -n 5
16905         flags=$(changelog_dump | grep UNLNK | tail -1 | cut -f5 -d' ')
16906         changelog_clear 0 || error "changelog_clear failed"
16907         if [ x$flags != "x0x0" ]; then
16908                 error "flag $flags is not 0x0"
16909         fi
16910         echo "unlink a file having nlink > 1, changelog record flags '$flags'"
16911 }
16912 run_test 161c "check CL_RENME[UNLINK] changelog record flags"
16913
16914 test_161d() {
16915         remote_mds_nodsh && skip "remote MDS with nodsh"
16916         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
16917
16918         local pid
16919         local fid
16920
16921         changelog_register || error "changelog_register failed"
16922
16923         # work in a standalone dir to avoid locking on $DIR/$MOUNT to
16924         # interfer with $MOUNT/.lustre/fid/ access
16925         mkdir $DIR/$tdir
16926         [[ $? -eq 0 ]] || error "mkdir failed"
16927
16928         #define OBD_FAIL_LLITE_CREATE_NODE_PAUSE 0x140c | OBD_FAIL_ONCE
16929         $LCTL set_param fail_loc=0x8000140c
16930         # 5s pause
16931         $LCTL set_param fail_val=5
16932
16933         # create file
16934         echo foofoo > $DIR/$tdir/$tfile &
16935         pid=$!
16936
16937         # wait for create to be delayed
16938         sleep 2
16939
16940         ps -p $pid
16941         [[ $? -eq 0 ]] || error "create should be blocked"
16942
16943         local tempfile="$(mktemp --tmpdir $tfile.XXXXXX)"
16944         stack_trap "rm -f $tempfile"
16945         fid=$(changelog_extract_field "CREAT" "$tfile" "t=")
16946         cat $MOUNT/.lustre/fid/$fid 2>/dev/null >$tempfile || error "cat failed"
16947         # some delay may occur during ChangeLog publishing and file read just
16948         # above, that could allow file write to happen finally
16949         [[ -s $tempfile ]] && echo "file should be empty"
16950
16951         $LCTL set_param fail_loc=0
16952
16953         wait $pid
16954         [[ $? -eq 0 ]] || error "create failed"
16955 }
16956 run_test 161d "create with concurrent .lustre/fid access"
16957
16958 check_path() {
16959         local expected="$1"
16960         shift
16961         local fid="$2"
16962
16963         local path
16964         path=$($LFS fid2path "$@")
16965         local rc=$?
16966
16967         if [ $rc -ne 0 ]; then
16968                 error "path looked up of '$expected' failed: rc=$rc"
16969         elif [ "$path" != "$expected" ]; then
16970                 error "path looked up '$path' instead of '$expected'"
16971         else
16972                 echo "FID '$fid' resolves to path '$path' as expected"
16973         fi
16974 }
16975
16976 test_162a() { # was test_162
16977         test_mkdir -p -c1 $DIR/$tdir/d2
16978         touch $DIR/$tdir/d2/$tfile
16979         touch $DIR/$tdir/d2/x1
16980         touch $DIR/$tdir/d2/x2
16981         test_mkdir -p -c1 $DIR/$tdir/d2/a/b/c
16982         test_mkdir -p -c1 $DIR/$tdir/d2/p/q/r
16983         # regular file
16984         local fid=$($LFS path2fid $DIR/$tdir/d2/$tfile | tr -d '[]')
16985         check_path "$tdir/d2/$tfile" $FSNAME "$fid" --link 0
16986
16987         # softlink
16988         ln -s $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/p/q/r/slink
16989         fid=$($LFS path2fid $DIR/$tdir/d2/p/q/r/slink | tr -d '[]')
16990         check_path "$tdir/d2/p/q/r/slink" $FSNAME "$fid" --link 0
16991
16992         # softlink to wrong file
16993         ln -s /this/is/garbage $DIR/$tdir/d2/p/q/r/slink.wrong
16994         fid=$($LFS path2fid $DIR/$tdir/d2/p/q/r/slink.wrong | tr -d '[]')
16995         check_path "$tdir/d2/p/q/r/slink.wrong" $FSNAME "$fid" --link 0
16996
16997         # hardlink
16998         ln $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/p/q/r/hlink
16999         mv $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/a/b/c/new_file
17000         fid=$($LFS path2fid $DIR/$tdir/d2/a/b/c/new_file | tr -d '[]')
17001         # fid2path dir/fsname should both work
17002         check_path "$tdir/d2/a/b/c/new_file" $FSNAME "$fid" --link 1
17003         check_path "$DIR/$tdir/d2/p/q/r/hlink" $DIR "$fid" --link 0
17004
17005         # hardlink count: check that there are 2 links
17006         local nlinks=$($LFS fid2path $DIR "$fid" | wc -l)
17007         [ $nlinks -eq 2 ] || error "expect 2 links, found $nlinks"
17008
17009         # hardlink indexing: remove the first link
17010         rm $DIR/$tdir/d2/p/q/r/hlink
17011         check_path "$tdir/d2/a/b/c/new_file" $FSNAME $fid --link 0
17012 }
17013 run_test 162a "path lookup sanity"
17014
17015 test_162b() {
17016         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17017         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
17018
17019         mkdir $DIR/$tdir
17020         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
17021                                 error "create striped dir failed"
17022
17023         local FID=$($LFS getdirstripe $DIR/$tdir/striped_dir |
17024                                         tail -n 1 | awk '{print $2}')
17025         stat $MOUNT/.lustre/fid/$FID && error "sub_stripe can be accessed"
17026
17027         touch $DIR/$tdir/striped_dir/f{0..4} || error "touch f0..4 failed"
17028         mkdir $DIR/$tdir/striped_dir/d{0..4} || error "mkdir d0..4 failed"
17029
17030         # regular file
17031         for ((i=0;i<5;i++)); do
17032                 FID=$($LFS path2fid $DIR/$tdir/striped_dir/f$i | tr -d '[]') ||
17033                         error "get fid for f$i failed"
17034                 check_path "$tdir/striped_dir/f$i" $FSNAME $FID --link 0
17035
17036                 FID=$($LFS path2fid $DIR/$tdir/striped_dir/d$i | tr -d '[]') ||
17037                         error "get fid for d$i failed"
17038                 check_path "$tdir/striped_dir/d$i" $FSNAME $FID --link 0
17039         done
17040
17041         return 0
17042 }
17043 run_test 162b "striped directory path lookup sanity"
17044
17045 # LU-4239: Verify fid2path works with paths 100 or more directories deep
17046 test_162c() {
17047         [[ $MDS1_VERSION -lt $(version_code 2.7.51) ]] &&
17048                 skip "Need MDS version at least 2.7.51"
17049
17050         local lpath=$tdir.local
17051         local rpath=$tdir.remote
17052
17053         test_mkdir $DIR/$lpath
17054         test_mkdir $DIR/$rpath
17055
17056         for ((i = 0; i <= 101; i++)); do
17057                 lpath="$lpath/$i"
17058                 mkdir $DIR/$lpath
17059                 FID=$($LFS path2fid $DIR/$lpath | tr -d '[]') ||
17060                         error "get fid for local directory $DIR/$lpath failed"
17061                 check_path "$DIR/$lpath" $MOUNT $FID --link 0
17062
17063                 rpath="$rpath/$i"
17064                 test_mkdir $DIR/$rpath
17065                 FID=$($LFS path2fid $DIR/$rpath | tr -d '[]') ||
17066                         error "get fid for remote directory $DIR/$rpath failed"
17067                 check_path "$DIR/$rpath" $MOUNT $FID --link 0
17068         done
17069
17070         return 0
17071 }
17072 run_test 162c "fid2path works with paths 100 or more directories deep"
17073
17074 oalr_event_count() {
17075         local event="${1}"
17076         local trace="${2}"
17077
17078         awk -v name="${FSNAME}-OST0000" \
17079             -v event="${event}" \
17080             '$1 == "TRACE" && $2 == event && $3 == name' \
17081             "${trace}" |
17082         wc -l
17083 }
17084
17085 oalr_expect_event_count() {
17086         local event="${1}"
17087         local trace="${2}"
17088         local expect="${3}"
17089         local count
17090
17091         count=$(oalr_event_count "${event}" "${trace}")
17092         if ((count == expect)); then
17093                 return 0
17094         fi
17095
17096         error_noexit "${event} event count was '${count}', expected ${expect}"
17097         cat "${trace}" >&2
17098         exit 1
17099 }
17100
17101 cleanup_165() {
17102         do_facet ost1 killall --quiet -KILL ofd_access_log_reader || true
17103         stop ost1
17104         start ost1 "$(ostdevname 1)" $OST_MOUNT_OPTS
17105 }
17106
17107 setup_165() {
17108         sync # Flush previous IOs so we can count log entries.
17109         do_facet ost1 $LCTL set_param "obdfilter.${FSNAME}-OST0000.access_log_size=4096"
17110         stack_trap cleanup_165 EXIT
17111 }
17112
17113 test_165a() {
17114         local trace="/tmp/${tfile}.trace"
17115         local rc
17116         local count
17117
17118         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
17119                 skip "OFD access log unsupported"
17120
17121         setup_165
17122         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
17123         sleep 5
17124
17125         do_facet ost1 ofd_access_log_reader --list
17126         stop ost1
17127
17128         do_facet ost1 killall -TERM ofd_access_log_reader
17129         wait
17130         rc=$?
17131
17132         if ((rc != 0)); then
17133                 error "ofd_access_log_reader exited with rc = '${rc}'"
17134         fi
17135
17136         # Parse trace file for discovery events:
17137         oalr_expect_event_count alr_log_add "${trace}" 1
17138         oalr_expect_event_count alr_log_eof "${trace}" 1
17139         oalr_expect_event_count alr_log_free "${trace}" 1
17140 }
17141 run_test 165a "ofd access log discovery"
17142
17143 test_165b() {
17144         local trace="/tmp/${tfile}.trace"
17145         local file="${DIR}/${tfile}"
17146         local pfid1
17147         local pfid2
17148         local -a entry
17149         local rc
17150         local count
17151         local size
17152         local flags
17153
17154         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
17155                 skip "OFD access log unsupported"
17156
17157         setup_165
17158         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
17159         sleep 5
17160
17161         do_facet ost1 ofd_access_log_reader --list
17162
17163         lfs setstripe -c 1 -i 0 "${file}"
17164         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
17165                 error "cannot create '${file}'"
17166
17167         sleep 5
17168         do_facet ost1 killall -TERM ofd_access_log_reader
17169         wait
17170         rc=$?
17171
17172         if ((rc != 0)); then
17173                 error "ofd_access_log_reader exited with rc = '${rc}'"
17174         fi
17175
17176         oalr_expect_event_count alr_log_entry "${trace}" 1
17177
17178         pfid1=$($LFS path2fid "${file}")
17179
17180         # 1     2             3   4    5     6   7    8    9     10
17181         # TRACE alr_log_entry OST PFID BEGIN END TIME SIZE COUNT FLAGS
17182         entry=( - $(awk -v pfid="${pfid}" '$1 == "TRACE" && $2 == "alr_log_entry"' "${trace}" ) )
17183
17184         echo "entry = '${entry[*]}'" >&2
17185
17186         pfid2=${entry[4]}
17187         if [[ "${pfid1}" != "${pfid2}" ]]; then
17188                 error "entry '${entry[*]}' has invalid PFID '${pfid2}', expected ${pfid1}"
17189         fi
17190
17191         size=${entry[8]}
17192         if ((size != 1048576)); then
17193                 error "entry '${entry[*]}' has invalid io size '${size}', expected 1048576"
17194         fi
17195
17196         flags=${entry[10]}
17197         if [[ "${flags}" != "w" ]]; then
17198                 error "entry '${entry[*]}' has invalid io flags '${flags}', expected 'w'"
17199         fi
17200
17201         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
17202         sleep 5
17203
17204         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r524288c ||
17205                 error "cannot read '${file}'"
17206         sleep 5
17207
17208         do_facet ost1 killall -TERM ofd_access_log_reader
17209         wait
17210         rc=$?
17211
17212         if ((rc != 0)); then
17213                 error "ofd_access_log_reader exited with rc = '${rc}'"
17214         fi
17215
17216         oalr_expect_event_count alr_log_entry "${trace}" 1
17217
17218         entry=( - $(awk -v pfid="${pfid}" '$1 == "TRACE" && $2 == "alr_log_entry"' "${trace}" ) )
17219         echo "entry = '${entry[*]}'" >&2
17220
17221         pfid2=${entry[4]}
17222         if [[ "${pfid1}" != "${pfid2}" ]]; then
17223                 error "entry '${entry[*]}' has invalid PFID '${pfid2}', expected ${pfid1}"
17224         fi
17225
17226         size=${entry[8]}
17227         if ((size != 524288)); then
17228                 error "entry '${entry[*]}' has invalid io size '${size}', 524288"
17229         fi
17230
17231         flags=${entry[10]}
17232         if [[ "${flags}" != "r" ]]; then
17233                 error "entry '${entry[*]}' has invalid io flags '${flags}', expected 'r'"
17234         fi
17235 }
17236 run_test 165b "ofd access log entries are produced and consumed"
17237
17238 test_165c() {
17239         local trace="/tmp/${tfile}.trace"
17240         local file="${DIR}/${tdir}/${tfile}"
17241
17242         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
17243                 skip "OFD access log unsupported"
17244
17245         test_mkdir "${DIR}/${tdir}"
17246
17247         setup_165
17248         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
17249         sleep 5
17250
17251         lfs setstripe -c 1 -i 0 "${DIR}/${tdir}"
17252
17253         # 4096 / 64 = 64. Create twice as many entries.
17254         for ((i = 0; i < 128; i++)); do
17255                 $MULTIOP "${file}-${i}" oO_CREAT:O_WRONLY:w512c ||
17256                         error "cannot create file"
17257         done
17258
17259         sync
17260
17261         do_facet ost1 killall -TERM ofd_access_log_reader
17262         wait
17263         rc=$?
17264         if ((rc != 0)); then
17265                 error "ofd_access_log_reader exited with rc = '${rc}'"
17266         fi
17267
17268         unlinkmany  "${file}-%d" 128
17269 }
17270 run_test 165c "full ofd access logs do not block IOs"
17271
17272 oal_get_read_count() {
17273         local stats="$1"
17274
17275         # STATS lustre-OST0001 alr_read_count 1
17276
17277         do_facet ost1 cat "${stats}" |
17278         awk '$1 == "STATS" && $3 == "alr_read_count" { count = $4; }
17279              END { print count; }'
17280 }
17281
17282 oal_expect_read_count() {
17283         local stats="$1"
17284         local count
17285         local expect="$2"
17286
17287         # Ask ofd_access_log_reader to write stats.
17288         do_facet ost1 killall -USR1 ofd_access_log_reader
17289
17290         # Allow some time for things to happen.
17291         sleep 1
17292
17293         count=$(oal_get_read_count "${stats}")
17294         if ((count == expect)); then
17295                 return 0
17296         fi
17297
17298         error_noexit "bad read count, got ${count}, expected ${expect}"
17299         do_facet ost1 cat "${stats}" >&2
17300         exit 1
17301 }
17302
17303 test_165d() {
17304         local stats="/tmp/${tfile}.stats"
17305         local file="${DIR}/${tdir}/${tfile}"
17306         local param="obdfilter.${FSNAME}-OST0000.access_log_mask"
17307
17308         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
17309                 skip "OFD access log unsupported"
17310
17311         test_mkdir "${DIR}/${tdir}"
17312
17313         setup_165
17314         do_facet ost1 ofd_access_log_reader --stats="${stats}" &
17315         sleep 5
17316
17317         lfs setstripe -c 1 -i 0 "${file}"
17318
17319         do_facet ost1 lctl set_param "${param}=rw"
17320         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
17321                 error "cannot create '${file}'"
17322         oal_expect_read_count "${stats}" 1
17323
17324         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
17325                 error "cannot read '${file}'"
17326         oal_expect_read_count "${stats}" 2
17327
17328         do_facet ost1 lctl set_param "${param}=r"
17329         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
17330                 error "cannot create '${file}'"
17331         oal_expect_read_count "${stats}" 2
17332
17333         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
17334                 error "cannot read '${file}'"
17335         oal_expect_read_count "${stats}" 3
17336
17337         do_facet ost1 lctl set_param "${param}=w"
17338         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
17339                 error "cannot create '${file}'"
17340         oal_expect_read_count "${stats}" 4
17341
17342         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
17343                 error "cannot read '${file}'"
17344         oal_expect_read_count "${stats}" 4
17345
17346         do_facet ost1 lctl set_param "${param}=0"
17347         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
17348                 error "cannot create '${file}'"
17349         oal_expect_read_count "${stats}" 4
17350
17351         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
17352                 error "cannot read '${file}'"
17353         oal_expect_read_count "${stats}" 4
17354
17355         do_facet ost1 killall -TERM ofd_access_log_reader
17356         wait
17357         rc=$?
17358         if ((rc != 0)); then
17359                 error "ofd_access_log_reader exited with rc = '${rc}'"
17360         fi
17361 }
17362 run_test 165d "ofd_access_log mask works"
17363
17364 test_165e() {
17365         local stats="/tmp/${tfile}.stats"
17366         local file0="${DIR}/${tdir}-0/${tfile}"
17367         local file1="${DIR}/${tdir}-1/${tfile}"
17368
17369         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
17370                 skip "OFD access log unsupported"
17371
17372         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
17373
17374         test_mkdir -c 1 -i 0 "${DIR}/${tdir}-0"
17375         test_mkdir -c 1 -i 1 "${DIR}/${tdir}-1"
17376
17377         lfs setstripe -c 1 -i 0 "${file0}"
17378         lfs setstripe -c 1 -i 0 "${file1}"
17379
17380         setup_165
17381         do_facet ost1 ofd_access_log_reader -I 1 --stats="${stats}" &
17382         sleep 5
17383
17384         $MULTIOP "${file0}" oO_CREAT:O_WRONLY:w512c ||
17385                 error "cannot create '${file0}'"
17386         sync
17387         oal_expect_read_count "${stats}" 0
17388
17389         $MULTIOP "${file1}" oO_CREAT:O_WRONLY:w512c ||
17390                 error "cannot create '${file1}'"
17391         sync
17392         oal_expect_read_count "${stats}" 1
17393
17394         do_facet ost1 killall -TERM ofd_access_log_reader
17395         wait
17396         rc=$?
17397         if ((rc != 0)); then
17398                 error "ofd_access_log_reader exited with rc = '${rc}'"
17399         fi
17400 }
17401 run_test 165e "ofd_access_log MDT index filter works"
17402
17403 test_165f() {
17404         local trace="/tmp/${tfile}.trace"
17405         local rc
17406         local count
17407
17408         setup_165
17409         do_facet ost1 timeout 60 ofd_access_log_reader \
17410                 --exit-on-close --debug=- --trace=- > "${trace}" &
17411         sleep 5
17412         stop ost1
17413
17414         wait
17415         rc=$?
17416
17417         if ((rc != 0)); then
17418                 error_noexit "ofd_access_log_reader exited with rc = '${rc}'"
17419                 cat "${trace}"
17420                 exit 1
17421         fi
17422 }
17423 run_test 165f "ofd_access_log_reader --exit-on-close works"
17424
17425 test_169() {
17426         # do directio so as not to populate the page cache
17427         log "creating a 10 Mb file"
17428         $MULTIOP $DIR/$tfile oO_CREAT:O_DIRECT:O_RDWR:w$((10*1048576))c ||
17429                 error "multiop failed while creating a file"
17430         log "starting reads"
17431         dd if=$DIR/$tfile of=/dev/null bs=4096 &
17432         log "truncating the file"
17433         $MULTIOP $DIR/$tfile oO_TRUNC:c ||
17434                 error "multiop failed while truncating the file"
17435         log "killing dd"
17436         kill %+ || true # reads might have finished
17437         echo "wait until dd is finished"
17438         wait
17439         log "removing the temporary file"
17440         rm -rf $DIR/$tfile || error "tmp file removal failed"
17441 }
17442 run_test 169 "parallel read and truncate should not deadlock"
17443
17444 test_170() {
17445         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17446
17447         $LCTL clear     # bug 18514
17448         $LCTL debug_daemon start $TMP/${tfile}_log_good
17449         touch $DIR/$tfile
17450         $LCTL debug_daemon stop
17451         sed -e "s/^...../a/g" $TMP/${tfile}_log_good > $TMP/${tfile}_log_bad ||
17452                 error "sed failed to read log_good"
17453
17454         $LCTL debug_daemon start $TMP/${tfile}_log_good
17455         rm -rf $DIR/$tfile
17456         $LCTL debug_daemon stop
17457
17458         $LCTL df $TMP/${tfile}_log_bad > $TMP/${tfile}_log_bad.out 2>&1 ||
17459                error "lctl df log_bad failed"
17460
17461         local bad_line=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $9}')
17462         local good_line1=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $5}')
17463
17464         $LCTL df $TMP/${tfile}_log_good > $TMP/${tfile}_log_good.out 2>&1
17465         local good_line2=$(tail -n 1 $TMP/${tfile}_log_good.out | awk '{print $5}')
17466
17467         [ "$bad_line" ] && [ "$good_line1" ] && [ "$good_line2" ] ||
17468                 error "bad_line good_line1 good_line2 are empty"
17469
17470         cat $TMP/${tfile}_log_good >> $TMP/${tfile}_logs_corrupt
17471         cat $TMP/${tfile}_log_bad >> $TMP/${tfile}_logs_corrupt
17472         cat $TMP/${tfile}_log_good >> $TMP/${tfile}_logs_corrupt
17473
17474         $LCTL df $TMP/${tfile}_logs_corrupt > $TMP/${tfile}_log_bad.out 2>&1
17475         local bad_line_new=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $9}')
17476         local good_line_new=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $5}')
17477
17478         [ "$bad_line_new" ] && [ "$good_line_new" ] ||
17479                 error "bad_line_new good_line_new are empty"
17480
17481         local expected_good=$((good_line1 + good_line2*2))
17482
17483         rm -f $TMP/${tfile}*
17484         # LU-231, short malformed line may not be counted into bad lines
17485         if [ $bad_line -ne $bad_line_new ] &&
17486                    [ $bad_line -ne $((bad_line_new - 1)) ]; then
17487                 error "expected $bad_line bad lines, but got $bad_line_new"
17488                 return 1
17489         fi
17490
17491         if [ $expected_good -ne $good_line_new ]; then
17492                 error "expected $expected_good good lines, but got $good_line_new"
17493                 return 2
17494         fi
17495         true
17496 }
17497 run_test 170 "test lctl df to handle corrupted log ====================="
17498
17499 test_171() { # bug20592
17500         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17501
17502         #define OBD_FAIL_PTLRPC_DUMP_LOG         0x50e
17503         $LCTL set_param fail_loc=0x50e
17504         $LCTL set_param fail_val=3000
17505         multiop_bg_pause $DIR/$tfile O_s || true
17506         local MULTIPID=$!
17507         kill -USR1 $MULTIPID
17508         # cause log dump
17509         sleep 3
17510         wait $MULTIPID
17511         if dmesg | grep "recursive fault"; then
17512                 error "caught a recursive fault"
17513         fi
17514         $LCTL set_param fail_loc=0
17515         true
17516 }
17517 run_test 171 "test libcfs_debug_dumplog_thread stuck in do_exit() ======"
17518
17519 # it would be good to share it with obdfilter-survey/iokit-libecho code
17520 setup_obdecho_osc () {
17521         local rc=0
17522         local ost_nid=$1
17523         local obdfilter_name=$2
17524         echo "Creating new osc for $obdfilter_name on $ost_nid"
17525         # make sure we can find loopback nid
17526         $LCTL add_uuid $ost_nid $ost_nid >/dev/null 2>&1
17527
17528         [ $rc -eq 0 ] && { $LCTL attach osc ${obdfilter_name}_osc     \
17529                            ${obdfilter_name}_osc_UUID || rc=2; }
17530         [ $rc -eq 0 ] && { $LCTL --device ${obdfilter_name}_osc setup \
17531                            ${obdfilter_name}_UUID  $ost_nid || rc=3; }
17532         return $rc
17533 }
17534
17535 cleanup_obdecho_osc () {
17536         local obdfilter_name=$1
17537         $LCTL --device ${obdfilter_name}_osc cleanup >/dev/null
17538         $LCTL --device ${obdfilter_name}_osc detach  >/dev/null
17539         return 0
17540 }
17541
17542 obdecho_test() {
17543         local OBD=$1
17544         local node=$2
17545         local pages=${3:-64}
17546         local rc=0
17547         local id
17548
17549         local count=10
17550         local obd_size=$(get_obd_size $node $OBD)
17551         local page_size=$(get_page_size $node)
17552         if [[ -n "$obd_size" ]]; then
17553                 local new_count=$((obd_size / (pages * page_size / 1024)))
17554                 [[ $new_count -ge $count ]] || count=$new_count
17555         fi
17556
17557         do_facet $node "$LCTL attach echo_client ec ec_uuid" || rc=1
17558         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec setup $OBD" ||
17559                            rc=2; }
17560         if [ $rc -eq 0 ]; then
17561             id=$(do_facet $node "$LCTL --device ec create 1"  | awk '/object id/ {print $6}')
17562             [ ${PIPESTATUS[0]} -eq 0 -a -n "$id" ] || rc=3
17563         fi
17564         echo "New object id is $id"
17565         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec getattr $id" ||
17566                            rc=4; }
17567         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec "                 \
17568                            "test_brw $count w v $pages $id" || rc=4; }
17569         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec destroy $id 1" ||
17570                            rc=4; }
17571         [ $rc -eq 0 ] || [ $rc -gt 2 ] &&
17572                 { do_facet $node "$LCTL --device ec cleanup" || rc=5; }
17573         [ $rc -eq 0 ] || [ $rc -gt 1 ] &&
17574                 { do_facet $node "$LCTL --device ec detach" || rc=6; }
17575         [ $rc -ne 0 ] && echo "obecho_create_test failed: $rc"
17576         return $rc
17577 }
17578
17579 test_180a() {
17580         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17581
17582         if ! [ -d /sys/fs/lustre/echo_client ] &&
17583            ! module_loaded obdecho; then
17584                 load_module obdecho/obdecho &&
17585                         stack_trap "rmmod obdecho" EXIT ||
17586                         error "unable to load obdecho on client"
17587         fi
17588
17589         local osc=$($LCTL dl | grep -v mdt | awk '$3 == "osc" {print $4; exit}')
17590         local host=$($LCTL get_param -n osc.$osc.import |
17591                      awk '/current_connection:/ { print $2 }' )
17592         local target=$($LCTL get_param -n osc.$osc.import |
17593                        awk '/target:/ { print $2 }' )
17594         target=${target%_UUID}
17595
17596         if [ -n "$target" ]; then
17597                 setup_obdecho_osc $host $target &&
17598                         stack_trap "cleanup_obdecho_osc $target" EXIT ||
17599                         { error "obdecho setup failed with $?"; return; }
17600
17601                 obdecho_test ${target}_osc client ||
17602                         error "obdecho_test failed on ${target}_osc"
17603         else
17604                 $LCTL get_param osc.$osc.import
17605                 error "there is no osc.$osc.import target"
17606         fi
17607 }
17608 run_test 180a "test obdecho on osc"
17609
17610 test_180b() {
17611         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17612         remote_ost_nodsh && skip "remote OST with nodsh"
17613
17614         do_rpc_nodes $(facet_active_host ost1) load_module obdecho/obdecho &&
17615                 stack_trap "do_facet ost1 rmmod obdecho" EXIT ||
17616                 error "failed to load module obdecho"
17617
17618         local target=$(do_facet ost1 $LCTL dl |
17619                        awk '/obdfilter/ { print $4; exit; }')
17620
17621         if [ -n "$target" ]; then
17622                 obdecho_test $target ost1 || error "obdecho_test failed with $?"
17623         else
17624                 do_facet ost1 $LCTL dl
17625                 error "there is no obdfilter target on ost1"
17626         fi
17627 }
17628 run_test 180b "test obdecho directly on obdfilter"
17629
17630 test_180c() { # LU-2598
17631         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17632         remote_ost_nodsh && skip "remote OST with nodsh"
17633         [[ $MDS1_VERSION -lt $(version_code 2.4.0) ]] &&
17634                 skip "Need MDS version at least 2.4.0"
17635
17636         do_rpc_nodes $(facet_active_host ost1) load_module obdecho/obdecho &&
17637                 stack_trap "do_facet ost1 rmmod obdecho" EXIT ||
17638                 error "failed to load module obdecho"
17639
17640         local target=$(do_facet ost1 $LCTL dl |
17641                        awk '/obdfilter/ { print $4; exit; }')
17642
17643         if [ -n "$target" ]; then
17644                 local pages=16384 # 64MB bulk I/O RPC size
17645
17646                 obdecho_test "$target" ost1 "$pages" ||
17647                         error "obdecho_test with pages=$pages failed with $?"
17648         else
17649                 do_facet ost1 $LCTL dl
17650                 error "there is no obdfilter target on ost1"
17651         fi
17652 }
17653 run_test 180c "test huge bulk I/O size on obdfilter, don't LASSERT"
17654
17655 test_181() { # bug 22177
17656         test_mkdir $DIR/$tdir
17657         # create enough files to index the directory
17658         createmany -o $DIR/$tdir/foobar 4000
17659         # print attributes for debug purpose
17660         lsattr -d .
17661         # open dir
17662         multiop_bg_pause $DIR/$tdir D_Sc || return 1
17663         MULTIPID=$!
17664         # remove the files & current working dir
17665         unlinkmany $DIR/$tdir/foobar 4000
17666         rmdir $DIR/$tdir
17667         kill -USR1 $MULTIPID
17668         wait $MULTIPID
17669         stat $DIR/$tdir && error "open-unlinked dir was not removed!"
17670         return 0
17671 }
17672 run_test 181 "Test open-unlinked dir ========================"
17673
17674 test_182() {
17675         local fcount=1000
17676         local tcount=10
17677
17678         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
17679
17680         $LCTL set_param mdc.*.rpc_stats=clear
17681
17682         for (( i = 0; i < $tcount; i++ )) ; do
17683                 mkdir $DIR/$tdir/$i
17684         done
17685
17686         for (( i = 0; i < $tcount; i++ )) ; do
17687                 createmany -o $DIR/$tdir/$i/f- $fcount &
17688         done
17689         wait
17690
17691         for (( i = 0; i < $tcount; i++ )) ; do
17692                 unlinkmany $DIR/$tdir/$i/f- $fcount &
17693         done
17694         wait
17695
17696         $LCTL get_param mdc.*.rpc_stats
17697
17698         rm -rf $DIR/$tdir
17699 }
17700 run_test 182 "Test parallel modify metadata operations ================"
17701
17702 test_183() { # LU-2275
17703         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17704         remote_mds_nodsh && skip "remote MDS with nodsh"
17705         [[ $MDS1_VERSION -lt $(version_code 2.3.56) ]] &&
17706                 skip "Need MDS version at least 2.3.56"
17707
17708         mkdir_on_mdt0 $DIR/$tdir || error "creating dir $DIR/$tdir"
17709         echo aaa > $DIR/$tdir/$tfile
17710
17711 #define OBD_FAIL_MDS_NEGATIVE_POSITIVE  0x148
17712         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x148
17713
17714         ls -l $DIR/$tdir && error "ls succeeded, should have failed"
17715         cat $DIR/$tdir/$tfile && error "cat succeeded, should have failed"
17716
17717         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
17718
17719         # Flush negative dentry cache
17720         touch $DIR/$tdir/$tfile
17721
17722         # We are not checking for any leaked references here, they'll
17723         # become evident next time we do cleanup with module unload.
17724         rm -rf $DIR/$tdir
17725 }
17726 run_test 183 "No crash or request leak in case of strange dispositions ========"
17727
17728 # test suite 184 is for LU-2016, LU-2017
17729 test_184a() {
17730         check_swap_layouts_support
17731
17732         dir0=$DIR/$tdir/$testnum
17733         test_mkdir -p -c1 $dir0
17734         ref1=/etc/passwd
17735         ref2=/etc/group
17736         file1=$dir0/f1
17737         file2=$dir0/f2
17738         $LFS setstripe -c1 $file1
17739         cp $ref1 $file1
17740         $LFS setstripe -c2 $file2
17741         cp $ref2 $file2
17742         gen1=$($LFS getstripe -g $file1)
17743         gen2=$($LFS getstripe -g $file2)
17744
17745         $LFS swap_layouts $file1 $file2 || error "swap of file layout failed"
17746         gen=$($LFS getstripe -g $file1)
17747         [[ $gen1 != $gen ]] ||
17748                 "Layout generation on $file1 does not change"
17749         gen=$($LFS getstripe -g $file2)
17750         [[ $gen2 != $gen ]] ||
17751                 "Layout generation on $file2 does not change"
17752
17753         cmp $ref1 $file2 || error "content compare failed ($ref1 != $file2)"
17754         cmp $ref2 $file1 || error "content compare failed ($ref2 != $file1)"
17755
17756         lfsck_verify_pfid $file1 $file2 || error "PFID are not transferred"
17757 }
17758 run_test 184a "Basic layout swap"
17759
17760 test_184b() {
17761         check_swap_layouts_support
17762
17763         dir0=$DIR/$tdir/$testnum
17764         mkdir -p $dir0 || error "creating dir $dir0"
17765         file1=$dir0/f1
17766         file2=$dir0/f2
17767         file3=$dir0/f3
17768         dir1=$dir0/d1
17769         dir2=$dir0/d2
17770         mkdir $dir1 $dir2
17771         $LFS setstripe -c1 $file1
17772         $LFS setstripe -c2 $file2
17773         $LFS setstripe -c1 $file3
17774         chown $RUNAS_ID $file3
17775         gen1=$($LFS getstripe -g $file1)
17776         gen2=$($LFS getstripe -g $file2)
17777
17778         $LFS swap_layouts $dir1 $dir2 &&
17779                 error "swap of directories layouts should fail"
17780         $LFS swap_layouts $dir1 $file1 &&
17781                 error "swap of directory and file layouts should fail"
17782         $RUNAS $LFS swap_layouts $file1 $file2 &&
17783                 error "swap of file we cannot write should fail"
17784         $LFS swap_layouts $file1 $file3 &&
17785                 error "swap of file with different owner should fail"
17786         /bin/true # to clear error code
17787 }
17788 run_test 184b "Forbidden layout swap (will generate errors)"
17789
17790 test_184c() {
17791         local cmpn_arg=$(cmp -n 2>&1 | grep "invalid option")
17792         [ -n "$cmpn_arg" ] && skip_env "cmp does not support -n"
17793         check_swap_layouts_support
17794         check_swap_layout_no_dom $DIR
17795
17796         local dir0=$DIR/$tdir/$testnum
17797         mkdir -p $dir0 || error "creating dir $dir0"
17798
17799         local ref1=$dir0/ref1
17800         local ref2=$dir0/ref2
17801         local file1=$dir0/file1
17802         local file2=$dir0/file2
17803         # create a file large enough for the concurrent test
17804         dd if=/dev/urandom of=$ref1 bs=1M count=$((RANDOM % 50 + 20))
17805         dd if=/dev/urandom of=$ref2 bs=1M count=$((RANDOM % 50 + 20))
17806         echo "ref file size: ref1($(stat -c %s $ref1))," \
17807              "ref2($(stat -c %s $ref2))"
17808
17809         cp $ref2 $file2
17810         dd if=$ref1 of=$file1 bs=16k &
17811         local DD_PID=$!
17812
17813         # Make sure dd starts to copy file, but wait at most 5 seconds
17814         local loops=0
17815         while [ ! -s $file1 -a $((loops++)) -lt 50 ]; do sleep 0.1; done
17816
17817         $LFS swap_layouts $file1 $file2
17818         local rc=$?
17819         wait $DD_PID
17820         [[ $? == 0 ]] || error "concurrent write on $file1 failed"
17821         [[ $rc == 0 ]] || error "swap of $file1 and $file2 failed"
17822
17823         # how many bytes copied before swapping layout
17824         local copied=$(stat -c %s $file2)
17825         local remaining=$(stat -c %s $ref1)
17826         remaining=$((remaining - copied))
17827         echo "Copied $copied bytes before swapping layout..."
17828
17829         cmp -n $copied $file1 $ref2 | grep differ &&
17830                 error "Content mismatch [0, $copied) of ref2 and file1"
17831         cmp -n $copied $file2 $ref1 ||
17832                 error "Content mismatch [0, $copied) of ref1 and file2"
17833         cmp -i $copied:$copied -n $remaining $file1 $ref1 ||
17834                 error "Content mismatch [$copied, EOF) of ref1 and file1"
17835
17836         # clean up
17837         rm -f $ref1 $ref2 $file1 $file2
17838 }
17839 run_test 184c "Concurrent write and layout swap"
17840
17841 test_184d() {
17842         check_swap_layouts_support
17843         check_swap_layout_no_dom $DIR
17844         [ -z "$(which getfattr 2>/dev/null)" ] &&
17845                 skip_env "no getfattr command"
17846
17847         local file1=$DIR/$tdir/$tfile-1
17848         local file2=$DIR/$tdir/$tfile-2
17849         local file3=$DIR/$tdir/$tfile-3
17850         local lovea1
17851         local lovea2
17852
17853         mkdir -p $DIR/$tdir
17854         touch $file1 || error "create $file1 failed"
17855         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file2 ||
17856                 error "create $file2 failed"
17857         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file3 ||
17858                 error "create $file3 failed"
17859         lovea1=$(get_layout_param $file1)
17860
17861         $LFS swap_layouts $file2 $file3 ||
17862                 error "swap $file2 $file3 layouts failed"
17863         $LFS swap_layouts $file1 $file2 ||
17864                 error "swap $file1 $file2 layouts failed"
17865
17866         lovea2=$(get_layout_param $file2)
17867         echo "$lovea1"
17868         echo "$lovea2"
17869         [ "$lovea1" == "$lovea2" ] || error "lovea $lovea1 != $lovea2"
17870
17871         lovea1=$(getfattr -n trusted.lov $file1 | grep ^trusted)
17872         [[ -z "$lovea1" ]] || error "$file1 shouldn't have lovea"
17873 }
17874 run_test 184d "allow stripeless layouts swap"
17875
17876 test_184e() {
17877         [[ $MDS1_VERSION -ge $(version_code 2.6.94) ]] ||
17878                 skip "Need MDS version at least 2.6.94"
17879         check_swap_layouts_support
17880         check_swap_layout_no_dom $DIR
17881         [ -z "$(which getfattr 2>/dev/null)" ] &&
17882                 skip_env "no getfattr command"
17883
17884         local file1=$DIR/$tdir/$tfile-1
17885         local file2=$DIR/$tdir/$tfile-2
17886         local file3=$DIR/$tdir/$tfile-3
17887         local lovea
17888
17889         mkdir -p $DIR/$tdir
17890         touch $file1 || error "create $file1 failed"
17891         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file2 ||
17892                 error "create $file2 failed"
17893         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file3 ||
17894                 error "create $file3 failed"
17895
17896         $LFS swap_layouts $file1 $file2 ||
17897                 error "swap $file1 $file2 layouts failed"
17898
17899         lovea=$(getfattr -n trusted.lov $file1 | grep ^trusted)
17900         [[ -z "$lovea" ]] || error "$file1 shouldn't have lovea"
17901
17902         echo 123 > $file1 || error "Should be able to write into $file1"
17903
17904         $LFS swap_layouts $file1 $file3 ||
17905                 error "swap $file1 $file3 layouts failed"
17906
17907         echo 123 > $file1 || error "Should be able to write into $file1"
17908
17909         rm -rf $file1 $file2 $file3
17910 }
17911 run_test 184e "Recreate layout after stripeless layout swaps"
17912
17913 test_184f() {
17914         # Create a file with name longer than sizeof(struct stat) ==
17915         # 144 to see if we can get chars from the file name to appear
17916         # in the returned striping. Note that 'f' == 0x66.
17917         local file=$(for ((i = 0; i < 200; i++)); do echo -n f; done)
17918
17919         mkdir -p $DIR/$tdir
17920         mcreate $DIR/$tdir/$file
17921         if lfs find --stripe-count 0x6666 $DIR/$tdir | grep $file; then
17922                 error "IOC_MDC_GETFILEINFO returned garbage striping"
17923         fi
17924 }
17925 run_test 184f "IOC_MDC_GETFILEINFO for files with long names but no striping"
17926
17927 test_185() { # LU-2441
17928         # LU-3553 - no volatile file support in old servers
17929         [[ $MDS1_VERSION -ge $(version_code 2.3.60) ]] ||
17930                 skip "Need MDS version at least 2.3.60"
17931
17932         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
17933         touch $DIR/$tdir/spoo
17934         local mtime1=$(stat -c "%Y" $DIR/$tdir)
17935         local fid=$($MULTIOP $DIR/$tdir VFw4096c) ||
17936                 error "cannot create/write a volatile file"
17937         [ "$FILESET" == "" ] &&
17938         $CHECKSTAT -t file $MOUNT/.lustre/fid/$fid 2>/dev/null &&
17939                 error "FID is still valid after close"
17940
17941         multiop_bg_pause $DIR/$tdir vVw4096_c
17942         local multi_pid=$!
17943
17944         local OLD_IFS=$IFS
17945         IFS=":"
17946         local fidv=($fid)
17947         IFS=$OLD_IFS
17948         # assume that the next FID for this client is sequential, since stdout
17949         # is unfortunately eaten by multiop_bg_pause
17950         local n=$((${fidv[1]} + 1))
17951         local next_fid="${fidv[0]}:$(printf "0x%x" $n):${fidv[2]}"
17952         if [ "$FILESET" == "" ]; then
17953                 $CHECKSTAT -t file $MOUNT/.lustre/fid/$next_fid ||
17954                         error "FID is missing before close"
17955         fi
17956         kill -USR1 $multi_pid
17957         # 1 second delay, so if mtime change we will see it
17958         sleep 1
17959         local mtime2=$(stat -c "%Y" $DIR/$tdir)
17960         [[ $mtime1 == $mtime2 ]] || error "mtime has changed"
17961 }
17962 run_test 185 "Volatile file support"
17963
17964 function create_check_volatile() {
17965         local idx=$1
17966         local tgt
17967
17968         $MULTIOP $MOUNT/.lustre/fid V${idx}Fw4096_c >&/tmp/${tfile}.fid &
17969         local PID=$!
17970         sleep 1
17971         local FID=$(cat /tmp/${tfile}.fid)
17972         [ "$FID" == "" ] && error "can't get FID for volatile"
17973         $CHECKSTAT -t file $MOUNT/.lustre/fid/$FID || error "can't stat $FID"
17974         tgt=$($LFS getstripe -m $MOUNT/.lustre/fid/$FID)
17975         [ "$tgt" != "$idx" ] && error "wrong MDS $tgt, expected $idx"
17976         kill -USR1 $PID
17977         wait
17978         sleep 1
17979         cancel_lru_locks mdc # flush opencache
17980         $CHECKSTAT -t file $MOUNT/.lustre/fid/$FID && error "can stat $FID"
17981         return 0
17982 }
17983
17984 test_185a(){
17985         # LU-12516 - volatile creation via .lustre
17986         [[ $MDS1_VERSION -ge $(version_code 2.12.55) ]] ||
17987                 skip "Need MDS version at least 2.3.55"
17988
17989         create_check_volatile 0
17990         [ $MDSCOUNT -lt 2 ] && return 0
17991
17992         # DNE case
17993         create_check_volatile 1
17994
17995         return 0
17996 }
17997 run_test 185a "Volatile file creation in .lustre/fid/"
17998
17999 test_187a() {
18000         remote_mds_nodsh && skip "remote MDS with nodsh"
18001         [ $MDS1_VERSION -lt $(version_code 2.3.0) ] &&
18002                 skip "Need MDS version at least 2.3.0"
18003
18004         local dir0=$DIR/$tdir/$testnum
18005         mkdir -p $dir0 || error "creating dir $dir0"
18006
18007         local file=$dir0/file1
18008         dd if=/dev/urandom of=$file count=10 bs=1M conv=fsync
18009         local dv1=$($LFS data_version $file)
18010         dd if=/dev/urandom of=$file seek=10 count=1 bs=1M conv=fsync
18011         local dv2=$($LFS data_version $file)
18012         [[ $dv1 != $dv2 ]] ||
18013                 error "data version did not change on write $dv1 == $dv2"
18014
18015         # clean up
18016         rm -f $file1
18017 }
18018 run_test 187a "Test data version change"
18019
18020 test_187b() {
18021         remote_mds_nodsh && skip "remote MDS with nodsh"
18022         [ $MDS1_VERSION -lt $(version_code 2.3.0) ] &&
18023                 skip "Need MDS version at least 2.3.0"
18024
18025         local dir0=$DIR/$tdir/$testnum
18026         mkdir -p $dir0 || error "creating dir $dir0"
18027
18028         declare -a DV=$($MULTIOP $dir0 Vw1000xYw1000xY | cut -f3 -d" ")
18029         [[ ${DV[0]} != ${DV[1]} ]] ||
18030                 error "data version did not change on write"\
18031                       " ${DV[0]} == ${DV[1]}"
18032
18033         # clean up
18034         rm -f $file1
18035 }
18036 run_test 187b "Test data version change on volatile file"
18037
18038 test_200() {
18039         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18040         remote_mgs_nodsh && skip "remote MGS with nodsh"
18041         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
18042
18043         local POOL=${POOL:-cea1}
18044         local POOL_ROOT=${POOL_ROOT:-$DIR/d200.pools}
18045         local POOL_DIR_NAME=${POOL_DIR_NAME:-dir_tst}
18046         # Pool OST targets
18047         local first_ost=0
18048         local last_ost=$(($OSTCOUNT - 1))
18049         local ost_step=2
18050         local ost_list=$(seq $first_ost $ost_step $last_ost)
18051         local ost_range="$first_ost $last_ost $ost_step"
18052         local test_path=$POOL_ROOT/$POOL_DIR_NAME
18053         local file_dir=$POOL_ROOT/file_tst
18054         local subdir=$test_path/subdir
18055         local rc=0
18056
18057         while : ; do
18058                 # former test_200a test_200b
18059                 pool_add $POOL                          || { rc=$? ; break; }
18060                 pool_add_targets  $POOL $ost_range      || { rc=$? ; break; }
18061                 # former test_200c test_200d
18062                 mkdir -p $test_path
18063                 pool_set_dir      $POOL $test_path      || { rc=$? ; break; }
18064                 pool_check_dir    $POOL $test_path      || { rc=$? ; break; }
18065                 mkdir -p $subdir
18066                 pool_check_dir    $POOL $subdir         || { rc=$? ; break; }
18067                 pool_dir_rel_path $POOL $POOL_DIR_NAME $POOL_ROOT \
18068                                                         || { rc=$? ; break; }
18069                 # former test_200e test_200f
18070                 local files=$((OSTCOUNT*3))
18071                 pool_alloc_files  $POOL $test_path $files "$ost_list" \
18072                                                         || { rc=$? ; break; }
18073                 pool_create_files $POOL $file_dir $files "$ost_list" \
18074                                                         || { rc=$? ; break; }
18075                 # former test_200g test_200h
18076                 pool_lfs_df $POOL                       || { rc=$? ; break; }
18077                 pool_file_rel_path $POOL $test_path     || { rc=$? ; break; }
18078
18079                 # former test_201a test_201b test_201c
18080                 pool_remove_first_target $POOL          || { rc=$? ; break; }
18081
18082                 local f=$test_path/$tfile
18083                 pool_remove_all_targets $POOL $f        || { rc=$? ; break; }
18084                 pool_remove $POOL $f                    || { rc=$? ; break; }
18085                 break
18086         done
18087
18088         destroy_test_pools
18089
18090         return $rc
18091 }
18092 run_test 200 "OST pools"
18093
18094 # usage: default_attr <count | size | offset>
18095 default_attr() {
18096         $LCTL get_param -n lov.$FSNAME-clilov-\*.stripe${1}
18097 }
18098
18099 # usage: check_default_stripe_attr
18100 check_default_stripe_attr() {
18101         ACTUAL=$($LFS getstripe $* $DIR/$tdir)
18102         case $1 in
18103         --stripe-count|-c)
18104                 [ -n "$2" ] && EXPECTED=0 || EXPECTED=$(default_attr count);;
18105         --stripe-size|-S)
18106                 [ -n "$2" ] && EXPECTED=0 || EXPECTED=$(default_attr size);;
18107         --stripe-index|-i)
18108                 EXPECTED=-1;;
18109         *)
18110                 error "unknown getstripe attr '$1'"
18111         esac
18112
18113         [ $ACTUAL == $EXPECTED ] ||
18114                 error "$DIR/$tdir has $1 '$ACTUAL', not '$EXPECTED'"
18115 }
18116
18117 test_204a() {
18118         test_mkdir $DIR/$tdir
18119         $LFS setstripe --stripe-count 0 --stripe-size 0 --stripe-index -1 $DIR/$tdir
18120
18121         check_default_stripe_attr --stripe-count
18122         check_default_stripe_attr --stripe-size
18123         check_default_stripe_attr --stripe-index
18124 }
18125 run_test 204a "Print default stripe attributes"
18126
18127 test_204b() {
18128         test_mkdir $DIR/$tdir
18129         $LFS setstripe --stripe-count 1 $DIR/$tdir
18130
18131         check_default_stripe_attr --stripe-size
18132         check_default_stripe_attr --stripe-index
18133 }
18134 run_test 204b "Print default stripe size and offset"
18135
18136 test_204c() {
18137         test_mkdir $DIR/$tdir
18138         $LFS setstripe --stripe-size 65536 $DIR/$tdir
18139
18140         check_default_stripe_attr --stripe-count
18141         check_default_stripe_attr --stripe-index
18142 }
18143 run_test 204c "Print default stripe count and offset"
18144
18145 test_204d() {
18146         test_mkdir $DIR/$tdir
18147         $LFS setstripe --stripe-index 0 $DIR/$tdir
18148
18149         check_default_stripe_attr --stripe-count
18150         check_default_stripe_attr --stripe-size
18151 }
18152 run_test 204d "Print default stripe count and size"
18153
18154 test_204e() {
18155         test_mkdir $DIR/$tdir
18156         $LFS setstripe -d $DIR/$tdir
18157
18158         check_default_stripe_attr --stripe-count --raw
18159         check_default_stripe_attr --stripe-size --raw
18160         check_default_stripe_attr --stripe-index --raw
18161 }
18162 run_test 204e "Print raw stripe attributes"
18163
18164 test_204f() {
18165         test_mkdir $DIR/$tdir
18166         $LFS setstripe --stripe-count 1 $DIR/$tdir
18167
18168         check_default_stripe_attr --stripe-size --raw
18169         check_default_stripe_attr --stripe-index --raw
18170 }
18171 run_test 204f "Print raw stripe size and offset"
18172
18173 test_204g() {
18174         test_mkdir $DIR/$tdir
18175         $LFS setstripe --stripe-size 65536 $DIR/$tdir
18176
18177         check_default_stripe_attr --stripe-count --raw
18178         check_default_stripe_attr --stripe-index --raw
18179 }
18180 run_test 204g "Print raw stripe count and offset"
18181
18182 test_204h() {
18183         test_mkdir $DIR/$tdir
18184         $LFS setstripe --stripe-index 0 $DIR/$tdir
18185
18186         check_default_stripe_attr --stripe-count --raw
18187         check_default_stripe_attr --stripe-size --raw
18188 }
18189 run_test 204h "Print raw stripe count and size"
18190
18191 # Figure out which job scheduler is being used, if any,
18192 # or use a fake one
18193 if [ -n "$SLURM_JOB_ID" ]; then # SLURM
18194         JOBENV=SLURM_JOB_ID
18195 elif [ -n "$LSB_JOBID" ]; then # Load Sharing Facility
18196         JOBENV=LSB_JOBID
18197 elif [ -n "$PBS_JOBID" ]; then # PBS/Maui/Moab
18198         JOBENV=PBS_JOBID
18199 elif [ -n "$LOADL_STEPID" ]; then # LoadLeveller
18200         JOBENV=LOADL_STEP_ID
18201 elif [ -n "$JOB_ID" ]; then # Sun Grid Engine
18202         JOBENV=JOB_ID
18203 else
18204         $LCTL list_param jobid_name > /dev/null 2>&1
18205         if [ $? -eq 0 ]; then
18206                 JOBENV=nodelocal
18207         else
18208                 JOBENV=FAKE_JOBID
18209         fi
18210 fi
18211 LUSTRE_JOBID_SIZE=31 # plus NUL terminator
18212
18213 verify_jobstats() {
18214         local cmd=($1)
18215         shift
18216         local facets="$@"
18217
18218 # we don't really need to clear the stats for this test to work, since each
18219 # command has a unique jobid, but it makes debugging easier if needed.
18220 #       for facet in $facets; do
18221 #               local dev=$(convert_facet2label $facet)
18222 #               # clear old jobstats
18223 #               do_facet $facet lctl set_param *.$dev.job_stats="clear"
18224 #       done
18225
18226         # use a new JobID for each test, or we might see an old one
18227         [ "$JOBENV" = "FAKE_JOBID" ] &&
18228                 FAKE_JOBID=id.$testnum.$(basename ${cmd[0]}).$RANDOM
18229
18230         JOBVAL=${!JOBENV:0:$LUSTRE_JOBID_SIZE}
18231
18232         [ "$JOBENV" = "nodelocal" ] && {
18233                 FAKE_JOBID=id.$testnum.%e.$RANDOM
18234                 $LCTL set_param jobid_name=$FAKE_JOBID
18235                 JOBVAL=${FAKE_JOBID/\%e/$(basename ${cmd[0]})}
18236         }
18237
18238         log "Test: ${cmd[*]}"
18239         log "Using JobID environment $($LCTL get_param -n jobid_var)=$JOBVAL"
18240
18241         if [ $JOBENV = "FAKE_JOBID" ]; then
18242                 FAKE_JOBID=$JOBVAL ${cmd[*]}
18243         else
18244                 ${cmd[*]}
18245         fi
18246
18247         # all files are created on OST0000
18248         for facet in $facets; do
18249                 local stats="*.$(convert_facet2label $facet).job_stats"
18250
18251                 # strip out libtool wrappers for in-tree executables
18252                 if [ $(do_facet $facet lctl get_param $stats |
18253                        sed -e 's/\.lt-/./' | grep -c $JOBVAL) -ne 1 ]; then
18254                         do_facet $facet lctl get_param $stats
18255                         error "No jobstats for $JOBVAL found on $facet::$stats"
18256                 fi
18257         done
18258 }
18259
18260 jobstats_set() {
18261         local new_jobenv=$1
18262
18263         set_persistent_param_and_check client "jobid_var" \
18264                 "$FSNAME.sys.jobid_var" $new_jobenv
18265 }
18266
18267 test_205a() { # Job stats
18268         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18269         [[ $MDS1_VERSION -ge $(version_code 2.7.1) ]] ||
18270                 skip "Need MDS version with at least 2.7.1"
18271         remote_mgs_nodsh && skip "remote MGS with nodsh"
18272         remote_mds_nodsh && skip "remote MDS with nodsh"
18273         remote_ost_nodsh && skip "remote OST with nodsh"
18274         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep jobstats)" ] &&
18275                 skip "Server doesn't support jobstats"
18276         [[ $JOBID_VAR = disable ]] && skip_env "jobstats is disabled"
18277
18278         local old_jobenv=$($LCTL get_param -n jobid_var)
18279         [ $old_jobenv != $JOBENV ] && jobstats_set $JOBENV
18280
18281         if [[ $PERM_CMD == *"set_param -P"* ]]; then
18282                 stack_trap "do_facet mgs $PERM_CMD jobid_var=$old_jobenv" EXIT
18283         else
18284                 stack_trap "do_facet mgs $PERM_CMD \
18285                         $FSNAME.sys.jobid_var=$old_jobenv" EXIT
18286         fi
18287         changelog_register
18288
18289         local old_interval=$(do_facet $SINGLEMDS lctl get_param -n \
18290                                 mdt.*.job_cleanup_interval | head -n 1)
18291         local new_interval=5
18292         do_facet $SINGLEMDS \
18293                 $LCTL set_param mdt.*.job_cleanup_interval=$new_interval
18294         stack_trap "do_facet $SINGLEMDS \
18295                 $LCTL set_param mdt.*.job_cleanup_interval=$old_interval" EXIT
18296         local start=$SECONDS
18297
18298         local cmd
18299         # mkdir
18300         cmd="$LFS mkdir -i 0 -c 1 $DIR/$tdir"
18301         verify_jobstats "$cmd" "$SINGLEMDS"
18302         # rmdir
18303         cmd="rmdir $DIR/$tdir"
18304         verify_jobstats "$cmd" "$SINGLEMDS"
18305         # mkdir on secondary MDT
18306         if [ $MDSCOUNT -gt 1 ]; then
18307                 cmd="lfs mkdir -i 1 $DIR/$tdir.remote"
18308                 verify_jobstats "$cmd" "mds2"
18309         fi
18310         # mknod
18311         cmd="mknod $DIR/$tfile c 1 3"
18312         verify_jobstats "$cmd" "$SINGLEMDS"
18313         # unlink
18314         cmd="rm -f $DIR/$tfile"
18315         verify_jobstats "$cmd" "$SINGLEMDS"
18316         # create all files on OST0000 so verify_jobstats can find OST stats
18317         # open & close
18318         cmd="$LFS setstripe -i 0 -c 1 $DIR/$tfile"
18319         verify_jobstats "$cmd" "$SINGLEMDS"
18320         # setattr
18321         cmd="touch $DIR/$tfile"
18322         verify_jobstats "$cmd" "$SINGLEMDS ost1"
18323         # write
18324         cmd="dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=sync"
18325         verify_jobstats "$cmd" "ost1"
18326         # read
18327         cancel_lru_locks osc
18328         cmd="dd if=$DIR/$tfile of=/dev/null bs=1M count=1 iflag=direct"
18329         verify_jobstats "$cmd" "ost1"
18330         # truncate
18331         cmd="$TRUNCATE $DIR/$tfile 0"
18332         verify_jobstats "$cmd" "$SINGLEMDS ost1"
18333         # rename
18334         cmd="mv -f $DIR/$tfile $DIR/$tdir.rename"
18335         verify_jobstats "$cmd" "$SINGLEMDS"
18336         # jobstats expiry - sleep until old stats should be expired
18337         local left=$((new_interval + 5 - (SECONDS - start)))
18338         [ $left -ge 0 ] && wait_update_facet $SINGLEMDS \
18339                 "lctl get_param *.*.job_stats | grep -c 'job_id.*mkdir'" \
18340                         "0" $left
18341         cmd="$LFS mkdir -i 0 -c 1 $DIR/$tdir.expire"
18342         verify_jobstats "$cmd" "$SINGLEMDS"
18343         [ $(do_facet $SINGLEMDS lctl get_param *.*.job_stats |
18344             grep -c "job_id.*mkdir") -gt 1 ] && error "old jobstats not expired"
18345
18346         # Ensure that jobid are present in changelog (if supported by MDS)
18347         if [ $MDS1_VERSION -ge $(version_code 2.6.52) ];then
18348                 changelog_dump | tail -10
18349                 jobids=$(changelog_dump | tail -9 | grep -c "j=")
18350                 [ $jobids -eq 9 ] ||
18351                         error "Wrong changelog jobid count $jobids != 9"
18352
18353                 # LU-5862
18354                 JOBENV="disable"
18355                 jobstats_set $JOBENV
18356                 touch $DIR/$tfile
18357                 changelog_dump | grep $tfile
18358                 jobids=$(changelog_dump | grep $tfile | tail -1 | grep -c "j=")
18359                 [ $jobids -eq 0 ] ||
18360                         error "Unexpected jobids when jobid_var=$JOBENV"
18361         fi
18362
18363         # test '%j' access to environment variable - if supported
18364         if lctl set_param jobid_var=USER jobid_name="S.%j.%e.%u.%h.E"; then
18365                 JOBENV="JOBCOMPLEX"
18366                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname).E"
18367
18368                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
18369         fi
18370
18371         if lctl set_param jobid_var=USER jobid_name="S.%j.%e.%u.%H.E"; then
18372                 JOBENV="JOBCOMPLEX"
18373                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname -s).E"
18374
18375                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
18376         fi
18377
18378         # test '%j' access to per-session jobid - if supported
18379         if lctl list_param jobid_this_session > /dev/null 2>&1
18380         then
18381                 lctl set_param jobid_var=session jobid_name="S.%j.%e.%u.%h.E"
18382                 lctl set_param jobid_this_session=$USER
18383
18384                 JOBENV="JOBCOMPLEX"
18385                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname).E"
18386
18387                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
18388         fi
18389 }
18390 run_test 205a "Verify job stats"
18391
18392 # LU-13117, LU-13597
18393 test_205b() {
18394         (( $MDS1_VERSION >= $(version_code 2.13.54.91) )) ||
18395                 skip "Need MDS version at least 2.13.54.91"
18396
18397         job_stats="mdt.*.job_stats"
18398         $LCTL set_param $job_stats=clear
18399         # Setting jobid_var to USER might not be supported
18400         $LCTL set_param jobid_var=USER || true
18401         $LCTL set_param jobid_name="%e.%u"
18402         env -i USERTESTJOBSTATS=foolish touch $DIR/$tfile.1
18403         do_facet $SINGLEMDS $LCTL get_param $job_stats |
18404                 grep "job_id:.*foolish" &&
18405                         error "Unexpected jobid found"
18406         do_facet $SINGLEMDS $LCTL get_param $job_stats |
18407                 grep "open:.*min.*max.*sum" ||
18408                         error "wrong job_stats format found"
18409 }
18410 run_test 205b "Verify job stats jobid and output format"
18411
18412 # LU-13733
18413 test_205c() {
18414         $LCTL set_param llite.*.stats=0
18415         dd if=/dev/zero of=$DIR/$tfile.1 bs=4k count=1
18416         $LCTL get_param llite.*.stats
18417         $LCTL get_param llite.*.stats | grep \
18418                 "write_bytes *1 samples \[bytes\] 4096 4096 4096 16777216" ||
18419                         error "wrong client stats format found"
18420 }
18421 run_test 205c "Verify client stats format"
18422
18423 # LU-1480, LU-1773 and LU-1657
18424 test_206() {
18425         mkdir -p $DIR/$tdir
18426         $LFS setstripe -c -1 $DIR/$tdir
18427 #define OBD_FAIL_LOV_INIT 0x1403
18428         $LCTL set_param fail_loc=0xa0001403
18429         $LCTL set_param fail_val=1
18430         touch $DIR/$tdir/$tfile || true
18431 }
18432 run_test 206 "fail lov_init_raid0() doesn't lbug"
18433
18434 test_207a() {
18435         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((RANDOM%10+1))
18436         local fsz=`stat -c %s $DIR/$tfile`
18437         cancel_lru_locks mdc
18438
18439         # do not return layout in getattr intent
18440 #define OBD_FAIL_MDS_NO_LL_GETATTR 0x170
18441         $LCTL set_param fail_loc=0x170
18442         local sz=`stat -c %s $DIR/$tfile`
18443
18444         [ $fsz -eq $sz ] || error "file size expected $fsz, actual $sz"
18445
18446         rm -rf $DIR/$tfile
18447 }
18448 run_test 207a "can refresh layout at glimpse"
18449
18450 test_207b() {
18451         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((RANDOM%10+1))
18452         local cksum=`md5sum $DIR/$tfile`
18453         local fsz=`stat -c %s $DIR/$tfile`
18454         cancel_lru_locks mdc
18455         cancel_lru_locks osc
18456
18457         # do not return layout in getattr intent
18458 #define OBD_FAIL_MDS_NO_LL_OPEN 0x171
18459         $LCTL set_param fail_loc=0x171
18460
18461         # it will refresh layout after the file is opened but before read issues
18462         echo checksum is "$cksum"
18463         echo "$cksum" |md5sum -c --quiet || error "file differs"
18464
18465         rm -rf $DIR/$tfile
18466 }
18467 run_test 207b "can refresh layout at open"
18468
18469 test_208() {
18470         # FIXME: in this test suite, only RD lease is used. This is okay
18471         # for now as only exclusive open is supported. After generic lease
18472         # is done, this test suite should be revised. - Jinshan
18473
18474         remote_mds_nodsh && skip "remote MDS with nodsh"
18475         [[ $MDS1_VERSION -ge $(version_code 2.4.52) ]] ||
18476                 skip "Need MDS version at least 2.4.52"
18477
18478         echo "==== test 1: verify get lease work"
18479         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:eRE+eU || error "get lease error"
18480
18481         echo "==== test 2: verify lease can be broken by upcoming open"
18482         $MULTIOP $DIR/$tfile oO_RDWR:eR_E-eUc &
18483         local PID=$!
18484         sleep 1
18485
18486         $MULTIOP $DIR/$tfile oO_RDWR:c
18487         kill -USR1 $PID && wait $PID || error "break lease error"
18488
18489         echo "==== test 3: verify lease can't be granted if an open already exists"
18490         $MULTIOP $DIR/$tfile oO_RDWR:_c &
18491         local PID=$!
18492         sleep 1
18493
18494         $MULTIOP $DIR/$tfile oO_RDWR:eReUc && error "apply lease should fail"
18495         kill -USR1 $PID && wait $PID || error "open file error"
18496
18497         echo "==== test 4: lease can sustain over recovery"
18498         $MULTIOP $DIR/$tfile oO_RDWR:eR_E+eUc &
18499         PID=$!
18500         sleep 1
18501
18502         fail mds1
18503
18504         kill -USR1 $PID && wait $PID || error "lease broken over recovery"
18505
18506         echo "==== test 5: lease broken can't be regained by replay"
18507         $MULTIOP $DIR/$tfile oO_RDWR:eR_E-eUc &
18508         PID=$!
18509         sleep 1
18510
18511         # open file to break lease and then recovery
18512         $MULTIOP $DIR/$tfile oO_RDWR:c || error "open file error"
18513         fail mds1
18514
18515         kill -USR1 $PID && wait $PID || error "lease not broken over recovery"
18516
18517         rm -f $DIR/$tfile
18518 }
18519 run_test 208 "Exclusive open"
18520
18521 test_209() {
18522         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep disp_stripe)" ] &&
18523                 skip_env "must have disp_stripe"
18524
18525         touch $DIR/$tfile
18526         sync; sleep 5; sync;
18527
18528         echo 3 > /proc/sys/vm/drop_caches
18529         [ -f /sys/kernel/slab/ptlrpc_cache/shrink ] &&
18530                 echo 1 > /sys/kernel/slab/ptlrpc_cache/shrink
18531         req_before=$(awk '/ptlrpc_cache / { print $2 }' /proc/slabinfo)
18532
18533         # open/close 500 times
18534         for i in $(seq 500); do
18535                 cat $DIR/$tfile
18536         done
18537
18538         echo 3 > /proc/sys/vm/drop_caches
18539         [ -f /sys/kernel/slab/ptlrpc_cache/shrink ] &&
18540                 echo 1 > /sys/kernel/slab/ptlrpc_cache/shrink
18541         req_after=$(awk '/ptlrpc_cache / { print $2 }' /proc/slabinfo)
18542
18543         echo "before: $req_before, after: $req_after"
18544         [ $((req_after - req_before)) -ge 300 ] &&
18545                 error "open/close requests are not freed"
18546         return 0
18547 }
18548 run_test 209 "read-only open/close requests should be freed promptly"
18549
18550 test_210() {
18551         local pid
18552
18553         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:eW_E+eUc &
18554         pid=$!
18555         sleep 1
18556
18557         $LFS getstripe $DIR/$tfile
18558         kill -USR1 $pid
18559         wait $pid || error "multiop failed"
18560
18561         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E+eUc &
18562         pid=$!
18563         sleep 1
18564
18565         $LFS getstripe $DIR/$tfile
18566         kill -USR1 $pid
18567         wait $pid || error "multiop failed"
18568 }
18569 run_test 210 "lfs getstripe does not break leases"
18570
18571 test_212() {
18572         size=`date +%s`
18573         size=$((size % 8192 + 1))
18574         dd if=/dev/urandom of=$DIR/f212 bs=1k count=$size
18575         sendfile $DIR/f212 $DIR/f212.xyz || error "sendfile wrong"
18576         rm -f $DIR/f212 $DIR/f212.xyz
18577 }
18578 run_test 212 "Sendfile test ============================================"
18579
18580 test_213() {
18581         dd if=/dev/zero of=$DIR/$tfile bs=4k count=4
18582         cancel_lru_locks osc
18583         lctl set_param fail_loc=0x8000040f
18584         # generate a read lock
18585         cat $DIR/$tfile > /dev/null
18586         # write to the file, it will try to cancel the above read lock.
18587         cat /etc/hosts >> $DIR/$tfile
18588 }
18589 run_test 213 "OSC lock completion and cancel race don't crash - bug 18829"
18590
18591 test_214() { # for bug 20133
18592         mkdir -p $DIR/$tdir/d214c || error "mkdir $DIR/$tdir/d214c failed"
18593         for (( i=0; i < 340; i++ )) ; do
18594                 touch $DIR/$tdir/d214c/a$i
18595         done
18596
18597         ls -l $DIR/$tdir || error "ls -l $DIR/d214p failed"
18598         mv $DIR/$tdir/d214c $DIR/ || error "mv $DIR/d214p/d214c $DIR/ failed"
18599         ls $DIR/d214c || error "ls $DIR/d214c failed"
18600         rm -rf $DIR/$tdir || error "rm -rf $DIR/d214* failed"
18601         rm -rf $DIR/d214* || error "rm -rf $DIR/d214* failed"
18602 }
18603 run_test 214 "hash-indexed directory test - bug 20133"
18604
18605 # having "abc" as 1st arg, creates $TMP/lnet_abc.out and $TMP/lnet_abc.sys
18606 create_lnet_proc_files() {
18607         lctl get_param -n $1 >$TMP/lnet_$1.sys || error "cannot read lnet.$1"
18608 }
18609
18610 # counterpart of create_lnet_proc_files
18611 remove_lnet_proc_files() {
18612         rm -f $TMP/lnet_$1.sys
18613 }
18614
18615 # uses 1st arg as trailing part of filename, 2nd arg as description for reports,
18616 # 3rd arg as regexp for body
18617 check_lnet_proc_stats() {
18618         local l=$(cat "$TMP/lnet_$1" |wc -l)
18619         [ $l = 1 ] || (cat "$TMP/lnet_$1" && error "$2 is not of 1 line: $l")
18620
18621         grep -E "$3" "$TMP/lnet_$1" || (cat "$TMP/lnet_$1" && error "$2 misformatted")
18622 }
18623
18624 # uses 1st arg as trailing part of filename, 2nd arg as description for reports,
18625 # 3rd arg as regexp for body, 4th arg as regexp for 1st line, 5th arg is
18626 # optional and can be regexp for 2nd line (lnet.routes case)
18627 check_lnet_proc_entry() {
18628         local blp=2          # blp stands for 'position of 1st line of body'
18629         [ -z "$5" ] || blp=3 # lnet.routes case
18630
18631         local l=$(cat "$TMP/lnet_$1" |wc -l)
18632         # subtracting one from $blp because the body can be empty
18633         [ "$l" -ge "$(($blp - 1))" ] || (cat "$TMP/lnet_$1" && error "$2 is too short: $l")
18634
18635         sed -n '1 p' "$TMP/lnet_$1" |grep -E "$4" >/dev/null ||
18636                 (cat "$TMP/lnet_$1" && error "1st line of $2 misformatted")
18637
18638         [ "$5" = "" ] || sed -n '2 p' "$TMP/lnet_$1" |grep -E "$5" >/dev/null ||
18639                 (cat "$TMP/lnet_$1" && error "2nd line of $2 misformatted")
18640
18641         # bail out if any unexpected line happened
18642         sed -n "$blp p" "$TMP/lnet_$1" | grep -Ev "$3"
18643         [ "$?" != 0 ] || error "$2 misformatted"
18644 }
18645
18646 test_215() { # for bugs 18102, 21079, 21517
18647         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18648
18649         local N='(0|[1-9][0-9]*)'       # non-negative numeric
18650         local P='[1-9][0-9]*'           # positive numeric
18651         local I='(0|-?[1-9][0-9]*|NA)'  # any numeric (0 | >0 | <0) or NA if no value
18652         local NET='[a-z][a-z0-9]*'      # LNET net like o2ib2
18653         local ADDR='[0-9.]+'            # LNET addr like 10.0.0.1
18654         local NID="$ADDR@$NET"          # LNET nid like 10.0.0.1@o2ib2
18655
18656         local L1 # regexp for 1st line
18657         local L2 # regexp for 2nd line (optional)
18658         local BR # regexp for the rest (body)
18659
18660         # lnet.stats should look as 11 space-separated non-negative numerics
18661         BR="^$N $N $N $N $N $N $N $N $N $N $N$"
18662         create_lnet_proc_files "stats"
18663         check_lnet_proc_stats "stats.sys" "lnet.stats" "$BR"
18664         remove_lnet_proc_files "stats"
18665
18666         # lnet.routes should look like this:
18667         # Routing disabled/enabled
18668         # net hops priority state router
18669         # where net is a string like tcp0, hops > 0, priority >= 0,
18670         # state is up/down,
18671         # router is a string like 192.168.1.1@tcp2
18672         L1="^Routing (disabled|enabled)$"
18673         L2="^net +hops +priority +state +router$"
18674         BR="^$NET +$N +(0|1) +(up|down) +$NID$"
18675         create_lnet_proc_files "routes"
18676         check_lnet_proc_entry "routes.sys" "lnet.routes" "$BR" "$L1" "$L2"
18677         remove_lnet_proc_files "routes"
18678
18679         # lnet.routers should look like this:
18680         # ref rtr_ref alive_cnt state last_ping ping_sent deadline down_ni router
18681         # where ref > 0, rtr_ref > 0, alive_cnt >= 0, state is up/down,
18682         # last_ping >= 0, ping_sent is boolean (0/1), deadline and down_ni are
18683         # numeric (0 or >0 or <0), router is a string like 192.168.1.1@tcp2
18684         L1="^ref +rtr_ref +alive +router$"
18685         BR="^$P +$P +(up|down) +$NID$"
18686         create_lnet_proc_files "routers"
18687         check_lnet_proc_entry "routers.sys" "lnet.routers" "$BR" "$L1"
18688         remove_lnet_proc_files "routers"
18689
18690         # lnet.peers should look like this:
18691         # nid refs state last max rtr min tx min queue
18692         # where nid is a string like 192.168.1.1@tcp2, refs > 0,
18693         # state is up/down/NA, max >= 0. last, rtr, min, tx, min are
18694         # numeric (0 or >0 or <0), queue >= 0.
18695         L1="^nid +refs +state +last +max +rtr +min +tx +min +queue$"
18696         BR="^$NID +$P +(up|down|NA) +$I +$N +$I +$I +$I +$I +$N$"
18697         create_lnet_proc_files "peers"
18698         check_lnet_proc_entry "peers.sys" "lnet.peers" "$BR" "$L1"
18699         remove_lnet_proc_files "peers"
18700
18701         # lnet.buffers  should look like this:
18702         # pages count credits min
18703         # where pages >=0, count >=0, credits and min are numeric (0 or >0 or <0)
18704         L1="^pages +count +credits +min$"
18705         BR="^ +$N +$N +$I +$I$"
18706         create_lnet_proc_files "buffers"
18707         check_lnet_proc_entry "buffers.sys" "lnet.buffers" "$BR" "$L1"
18708         remove_lnet_proc_files "buffers"
18709
18710         # lnet.nis should look like this:
18711         # nid status alive refs peer rtr max tx min
18712         # where nid is a string like 192.168.1.1@tcp2, status is up/down,
18713         # alive is numeric (0 or >0 or <0), refs >= 0, peer >= 0,
18714         # rtr >= 0, max >=0, tx and min are numeric (0 or >0 or <0).
18715         L1="^nid +status +alive +refs +peer +rtr +max +tx +min$"
18716         BR="^$NID +(up|down) +$I +$N +$N +$N +$N +$I +$I$"
18717         create_lnet_proc_files "nis"
18718         check_lnet_proc_entry "nis.sys" "lnet.nis" "$BR" "$L1"
18719         remove_lnet_proc_files "nis"
18720
18721         # can we successfully write to lnet.stats?
18722         lctl set_param -n stats=0 || error "cannot write to lnet.stats"
18723 }
18724 run_test 215 "lnet exists and has proper content - bugs 18102, 21079, 21517"
18725
18726 test_216() { # bug 20317
18727         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18728         remote_ost_nodsh && skip "remote OST with nodsh"
18729
18730         local node
18731         local facets=$(get_facets OST)
18732         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
18733
18734         save_lustre_params client "osc.*.contention_seconds" > $p
18735         save_lustre_params $facets \
18736                 "ldlm.namespaces.filter-*.max_nolock_bytes" >> $p
18737         save_lustre_params $facets \
18738                 "ldlm.namespaces.filter-*.contended_locks" >> $p
18739         save_lustre_params $facets \
18740                 "ldlm.namespaces.filter-*.contention_seconds" >> $p
18741         clear_stats osc.*.osc_stats
18742
18743         # agressive lockless i/o settings
18744         do_nodes $(comma_list $(osts_nodes)) \
18745                 "lctl set_param -n ldlm.namespaces.*.max_nolock_bytes=2000000 \
18746                         ldlm.namespaces.filter-*.contended_locks=0 \
18747                         ldlm.namespaces.filter-*.contention_seconds=60"
18748         lctl set_param -n osc.*.contention_seconds=60
18749
18750         $DIRECTIO write $DIR/$tfile 0 10 4096
18751         $CHECKSTAT -s 40960 $DIR/$tfile
18752
18753         # disable lockless i/o
18754         do_nodes $(comma_list $(osts_nodes)) \
18755                 "lctl set_param -n ldlm.namespaces.filter-*.max_nolock_bytes=0 \
18756                         ldlm.namespaces.filter-*.contended_locks=32 \
18757                         ldlm.namespaces.filter-*.contention_seconds=0"
18758         lctl set_param -n osc.*.contention_seconds=0
18759         clear_stats osc.*.osc_stats
18760
18761         dd if=/dev/zero of=$DIR/$tfile count=0
18762         $CHECKSTAT -s 0 $DIR/$tfile
18763
18764         restore_lustre_params <$p
18765         rm -f $p
18766         rm $DIR/$tfile
18767 }
18768 run_test 216 "check lockless direct write updates file size and kms correctly"
18769
18770 test_217() { # bug 22430
18771         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18772
18773         local node
18774         local nid
18775
18776         for node in $(nodes_list); do
18777                 nid=$(host_nids_address $node $NETTYPE)
18778                 if [[ $nid = *-* ]] ; then
18779                         echo "lctl ping $(h2nettype $nid)"
18780                         lctl ping $(h2nettype $nid)
18781                 else
18782                         echo "skipping $node (no hyphen detected)"
18783                 fi
18784         done
18785 }
18786 run_test 217 "check lctl ping for hostnames with hiphen ('-')"
18787
18788 test_218() {
18789        # do directio so as not to populate the page cache
18790        log "creating a 10 Mb file"
18791        $MULTIOP $DIR/$tfile oO_CREAT:O_DIRECT:O_RDWR:w$((10*1048576))c || error "multiop failed while creating a file"
18792        log "starting reads"
18793        dd if=$DIR/$tfile of=/dev/null bs=4096 &
18794        log "truncating the file"
18795        $MULTIOP $DIR/$tfile oO_TRUNC:c || error "multiop failed while truncating the file"
18796        log "killing dd"
18797        kill %+ || true # reads might have finished
18798        echo "wait until dd is finished"
18799        wait
18800        log "removing the temporary file"
18801        rm -rf $DIR/$tfile || error "tmp file removal failed"
18802 }
18803 run_test 218 "parallel read and truncate should not deadlock"
18804
18805 test_219() {
18806         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18807
18808         # write one partial page
18809         dd if=/dev/zero of=$DIR/$tfile bs=1024 count=1
18810         # set no grant so vvp_io_commit_write will do sync write
18811         $LCTL set_param fail_loc=0x411
18812         # write a full page at the end of file
18813         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 seek=1 conv=notrunc
18814
18815         $LCTL set_param fail_loc=0
18816         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 seek=3
18817         $LCTL set_param fail_loc=0x411
18818         dd if=/dev/zero of=$DIR/$tfile bs=1024 count=1 seek=2 conv=notrunc
18819
18820         # LU-4201
18821         dd if=/dev/zero of=$DIR/$tfile-2 bs=1024 count=1
18822         $CHECKSTAT -s 1024 $DIR/$tfile-2 || error "checkstat wrong size"
18823 }
18824 run_test 219 "LU-394: Write partial won't cause uncontiguous pages vec at LND"
18825
18826 test_220() { #LU-325
18827         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18828         remote_ost_nodsh && skip "remote OST with nodsh"
18829         remote_mds_nodsh && skip "remote MDS with nodsh"
18830         remote_mgs_nodsh && skip "remote MGS with nodsh"
18831
18832         local OSTIDX=0
18833
18834         # create on MDT0000 so the last_id and next_id are correct
18835         mkdir_on_mdt0 $DIR/$tdir
18836         local OST=$($LFS df $DIR | awk '/OST:'$OSTIDX'/ { print $1 }')
18837         OST=${OST%_UUID}
18838
18839         # on the mdt's osc
18840         local mdtosc_proc1=$(get_mdtosc_proc_path $SINGLEMDS $OST)
18841         local last_id=$(do_facet $SINGLEMDS lctl get_param -n \
18842                         osp.$mdtosc_proc1.prealloc_last_id)
18843         local next_id=$(do_facet $SINGLEMDS lctl get_param -n \
18844                         osp.$mdtosc_proc1.prealloc_next_id)
18845
18846         $LFS df -i
18847
18848         do_facet ost$((OSTIDX + 1)) lctl set_param fail_val=-1
18849         #define OBD_FAIL_OST_ENOINO              0x229
18850         do_facet ost$((OSTIDX + 1)) lctl set_param fail_loc=0x229
18851         create_pool $FSNAME.$TESTNAME || return 1
18852         do_facet mgs $LCTL pool_add $FSNAME.$TESTNAME $OST || return 2
18853
18854         $LFS setstripe $DIR/$tdir -i $OSTIDX -c 1 -p $FSNAME.$TESTNAME
18855
18856         MDSOBJS=$((last_id - next_id))
18857         echo "preallocated objects on MDS is $MDSOBJS" "($last_id - $next_id)"
18858
18859         blocks=$($LFS df $MOUNT | awk '($1 == '$OSTIDX') { print $4 }')
18860         echo "OST still has $count kbytes free"
18861
18862         echo "create $MDSOBJS files @next_id..."
18863         createmany -o $DIR/$tdir/f $MDSOBJS || return 3
18864
18865         local last_id2=$(do_facet mds${MDSIDX} lctl get_param -n \
18866                         osp.$mdtosc_proc1.prealloc_last_id)
18867         local next_id2=$(do_facet mds${MDSIDX} lctl get_param -n \
18868                         osp.$mdtosc_proc1.prealloc_next_id)
18869
18870         echo "after creation, last_id=$last_id2, next_id=$next_id2"
18871         $LFS df -i
18872
18873         echo "cleanup..."
18874
18875         do_facet ost$((OSTIDX + 1)) lctl set_param fail_val=0
18876         do_facet ost$((OSTIDX + 1)) lctl set_param fail_loc=0
18877
18878         do_facet mgs $LCTL pool_remove $FSNAME.$TESTNAME $OST ||
18879                 error "$LCTL pool_remove $FSNAME.$TESTNAME $OST failed"
18880         do_facet mgs $LCTL pool_destroy $FSNAME.$TESTNAME ||
18881                 error "$LCTL pool_destroy $FSNAME.$TESTNAME failed"
18882         echo "unlink $MDSOBJS files @$next_id..."
18883         unlinkmany $DIR/$tdir/f $MDSOBJS || error "unlinkmany failed"
18884 }
18885 run_test 220 "preallocated MDS objects still used if ENOSPC from OST"
18886
18887 test_221() {
18888         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18889
18890         dd if=`which date` of=$MOUNT/date oflag=sync
18891         chmod +x $MOUNT/date
18892
18893         #define OBD_FAIL_LLITE_FAULT_TRUNC_RACE  0x1401
18894         $LCTL set_param fail_loc=0x80001401
18895
18896         $MOUNT/date > /dev/null
18897         rm -f $MOUNT/date
18898 }
18899 run_test 221 "make sure fault and truncate race to not cause OOM"
18900
18901 test_222a () {
18902         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18903
18904         rm -rf $DIR/$tdir
18905         test_mkdir $DIR/$tdir
18906         $LFS setstripe -c 1 -i 0 $DIR/$tdir
18907         createmany -o $DIR/$tdir/$tfile 10
18908         cancel_lru_locks mdc
18909         cancel_lru_locks osc
18910         #define OBD_FAIL_LDLM_AGL_DELAY           0x31a
18911         $LCTL set_param fail_loc=0x31a
18912         ls -l $DIR/$tdir > /dev/null || error "AGL for ls failed"
18913         $LCTL set_param fail_loc=0
18914         rm -r $DIR/$tdir
18915 }
18916 run_test 222a "AGL for ls should not trigger CLIO lock failure"
18917
18918 test_222b () {
18919         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18920
18921         rm -rf $DIR/$tdir
18922         test_mkdir $DIR/$tdir
18923         $LFS setstripe -c 1 -i 0 $DIR/$tdir
18924         createmany -o $DIR/$tdir/$tfile 10
18925         cancel_lru_locks mdc
18926         cancel_lru_locks osc
18927         #define OBD_FAIL_LDLM_AGL_DELAY           0x31a
18928         $LCTL set_param fail_loc=0x31a
18929         rm -r $DIR/$tdir || error "AGL for rmdir failed"
18930         $LCTL set_param fail_loc=0
18931 }
18932 run_test 222b "AGL for rmdir should not trigger CLIO lock failure"
18933
18934 test_223 () {
18935         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18936
18937         rm -rf $DIR/$tdir
18938         test_mkdir $DIR/$tdir
18939         $LFS setstripe -c 1 -i 0 $DIR/$tdir
18940         createmany -o $DIR/$tdir/$tfile 10
18941         cancel_lru_locks mdc
18942         cancel_lru_locks osc
18943         #define OBD_FAIL_LDLM_AGL_NOLOCK          0x31b
18944         $LCTL set_param fail_loc=0x31b
18945         ls -l $DIR/$tdir > /dev/null || error "reenqueue failed"
18946         $LCTL set_param fail_loc=0
18947         rm -r $DIR/$tdir
18948 }
18949 run_test 223 "osc reenqueue if without AGL lock granted ======================="
18950
18951 test_224a() { # LU-1039, MRP-303
18952         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18953         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB   0x508
18954         $LCTL set_param fail_loc=0x508
18955         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 conv=fsync
18956         $LCTL set_param fail_loc=0
18957         df $DIR
18958 }
18959 run_test 224a "Don't panic on bulk IO failure"
18960
18961 test_224bd_sub() { # LU-1039, MRP-303
18962         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18963         local timeout=$1
18964
18965         shift
18966         dd if=/dev/urandom of=$TMP/$tfile bs=1M count=1
18967
18968         $LFS setstripe -c 1 -i 0 $DIR/$tfile
18969
18970         dd if=$TMP/$tfile of=$DIR/$tfile bs=1M count=1
18971         cancel_lru_locks osc
18972         set_checksums 0
18973         stack_trap "set_checksums $ORIG_CSUM" EXIT
18974         local at_max_saved=0
18975
18976         # adaptive timeouts may prevent seeing the issue
18977         if at_is_enabled; then
18978                 at_max_saved=$(at_max_get mds)
18979                 at_max_set 0 mds client
18980                 stack_trap "at_max_set $at_max_saved mds client" EXIT
18981         fi
18982
18983         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB2   0x515
18984         do_facet ost1 $LCTL set_param fail_val=$timeout fail_loc=0x80000515
18985         dd of=$TMP/$tfile.new if=$DIR/$tfile bs=1M count=1 || "$@"
18986
18987         do_facet ost1 $LCTL set_param fail_loc=0
18988         cmp $TMP/$tfile $TMP/$tfile.new || error "file contents wrong"
18989         df $DIR
18990 }
18991
18992 test_224b() {
18993         test_224bd_sub 3 error "dd failed"
18994 }
18995 run_test 224b "Don't panic on bulk IO failure"
18996
18997 test_224c() { # LU-6441
18998         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18999         remote_mds_nodsh && skip "remote MDS with nodsh"
19000
19001         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
19002         save_writethrough $p
19003         set_cache writethrough on
19004
19005         local pages_per_rpc=$($LCTL get_param osc.*.max_pages_per_rpc)
19006         local at_max=$($LCTL get_param -n at_max)
19007         local timeout=$($LCTL get_param -n timeout)
19008         local test_at="at_max"
19009         local param_at="$FSNAME.sys.at_max"
19010         local test_timeout="timeout"
19011         local param_timeout="$FSNAME.sys.timeout"
19012
19013         $LCTL set_param -n osc.*.max_pages_per_rpc=1024
19014
19015         set_persistent_param_and_check client "$test_at" "$param_at" 0
19016         set_persistent_param_and_check client "$test_timeout" "$param_timeout" 5
19017
19018         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB3 0x520
19019         do_facet ost1 "$LCTL set_param fail_loc=0x520"
19020         $LFS setstripe -c 1 -i 0 $DIR/$tfile
19021         dd if=/dev/zero of=$DIR/$tfile bs=8MB count=1
19022         sync
19023         do_facet ost1 "$LCTL set_param fail_loc=0"
19024
19025         set_persistent_param_and_check client "$test_at" "$param_at" $at_max
19026         set_persistent_param_and_check client "$test_timeout" "$param_timeout" \
19027                 $timeout
19028
19029         $LCTL set_param -n $pages_per_rpc
19030         restore_lustre_params < $p
19031         rm -f $p
19032 }
19033 run_test 224c "Don't hang if one of md lost during large bulk RPC"
19034
19035 test_224d() { # LU-11169
19036         test_224bd_sub $((TIMEOUT + 2)) error "dd failed"
19037 }
19038 run_test 224d "Don't corrupt data on bulk IO timeout"
19039
19040 MDSSURVEY=${MDSSURVEY:-$(which mds-survey 2>/dev/null || true)}
19041 test_225a () {
19042         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19043         if [ -z ${MDSSURVEY} ]; then
19044                 skip_env "mds-survey not found"
19045         fi
19046         [ $MDS1_VERSION -ge $(version_code 2.2.51) ] ||
19047                 skip "Need MDS version at least 2.2.51"
19048
19049         local mds=$(facet_host $SINGLEMDS)
19050         local target=$(do_nodes $mds 'lctl dl' |
19051                        awk '{ if ($2 == "UP" && $3 == "mdt") { print $4 }}')
19052
19053         local cmd1="file_count=1000 thrhi=4"
19054         local cmd2="dir_count=2 layer=mdd stripe_count=0"
19055         local cmd3="rslt_loc=${TMP} targets=\"$mds:$target\" $MDSSURVEY"
19056         local cmd="$cmd1 $cmd2 $cmd3"
19057
19058         rm -f ${TMP}/mds_survey*
19059         echo + $cmd
19060         eval $cmd || error "mds-survey with zero-stripe failed"
19061         cat ${TMP}/mds_survey*
19062         rm -f ${TMP}/mds_survey*
19063 }
19064 run_test 225a "Metadata survey sanity with zero-stripe"
19065
19066 test_225b () {
19067         if [ -z ${MDSSURVEY} ]; then
19068                 skip_env "mds-survey not found"
19069         fi
19070         [ $MDS1_VERSION -ge $(version_code 2.2.51) ] ||
19071                 skip "Need MDS version at least 2.2.51"
19072         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19073         remote_mds_nodsh && skip "remote MDS with nodsh"
19074         if [ $($LCTL dl | grep -c osc) -eq 0 ]; then
19075                 skip_env "Need to mount OST to test"
19076         fi
19077
19078         local mds=$(facet_host $SINGLEMDS)
19079         local target=$(do_nodes $mds 'lctl dl' |
19080                        awk '{ if ($2 == "UP" && $3 == "mdt") { print $4 }}')
19081
19082         local cmd1="file_count=1000 thrhi=4"
19083         local cmd2="dir_count=2 layer=mdd stripe_count=1"
19084         local cmd3="rslt_loc=${TMP} targets=\"$mds:$target\" $MDSSURVEY"
19085         local cmd="$cmd1 $cmd2 $cmd3"
19086
19087         rm -f ${TMP}/mds_survey*
19088         echo + $cmd
19089         eval $cmd || error "mds-survey with stripe_count failed"
19090         cat ${TMP}/mds_survey*
19091         rm -f ${TMP}/mds_survey*
19092 }
19093 run_test 225b "Metadata survey sanity with stripe_count = 1"
19094
19095 mcreate_path2fid () {
19096         local mode=$1
19097         local major=$2
19098         local minor=$3
19099         local name=$4
19100         local desc=$5
19101         local path=$DIR/$tdir/$name
19102         local fid
19103         local rc
19104         local fid_path
19105
19106         $MCREATE --mode=$1 --major=$2 --minor=$3 $path ||
19107                 error "cannot create $desc"
19108
19109         fid=$($LFS path2fid $path | tr -d '[' | tr -d ']')
19110         rc=$?
19111         [ $rc -ne 0 ] && error "cannot get fid of a $desc"
19112
19113         fid_path=$($LFS fid2path $MOUNT $fid)
19114         rc=$?
19115         [ $rc -ne 0 ] && error "cannot get path of $desc by $DIR $path $fid"
19116
19117         [ "$path" == "$fid_path" ] ||
19118                 error "fid2path returned $fid_path, expected $path"
19119
19120         echo "pass with $path and $fid"
19121 }
19122
19123 test_226a () {
19124         rm -rf $DIR/$tdir
19125         mkdir -p $DIR/$tdir
19126
19127         mcreate_path2fid 0010666 0 0 fifo "FIFO"
19128         mcreate_path2fid 0020666 1 3 null "character special file (null)"
19129         mcreate_path2fid 0020666 1 255 none "character special file (no device)"
19130         mcreate_path2fid 0040666 0 0 dir "directory"
19131         mcreate_path2fid 0060666 7 0 loop0 "block special file (loop)"
19132         mcreate_path2fid 0100666 0 0 file "regular file"
19133         mcreate_path2fid 0120666 0 0 link "symbolic link"
19134         mcreate_path2fid 0140666 0 0 sock "socket"
19135 }
19136 run_test 226a "call path2fid and fid2path on files of all type"
19137
19138 test_226b () {
19139         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19140
19141         local MDTIDX=1
19142
19143         rm -rf $DIR/$tdir
19144         mkdir -p $DIR/$tdir
19145         $LFS setdirstripe -i $MDTIDX $DIR/$tdir/remote_dir ||
19146                 error "create remote directory failed"
19147         mcreate_path2fid 0010666 0 0 "remote_dir/fifo" "FIFO"
19148         mcreate_path2fid 0020666 1 3 "remote_dir/null" \
19149                                 "character special file (null)"
19150         mcreate_path2fid 0020666 1 255 "remote_dir/none" \
19151                                 "character special file (no device)"
19152         mcreate_path2fid 0040666 0 0 "remote_dir/dir" "directory"
19153         mcreate_path2fid 0060666 7 0 "remote_dir/loop0" \
19154                                 "block special file (loop)"
19155         mcreate_path2fid 0100666 0 0 "remote_dir/file" "regular file"
19156         mcreate_path2fid 0120666 0 0 "remote_dir/link" "symbolic link"
19157         mcreate_path2fid 0140666 0 0 "remote_dir/sock" "socket"
19158 }
19159 run_test 226b "call path2fid and fid2path on files of all type under remote dir"
19160
19161 test_226c () {
19162         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19163         [[ $MDS1_VERSION -ge $(version_code 2.13.55) ]] ||
19164                 skip "Need MDS version at least 2.13.55"
19165
19166         local submnt=/mnt/submnt
19167         local srcfile=/etc/passwd
19168         local dstfile=$submnt/passwd
19169         local path
19170         local fid
19171
19172         rm -rf $DIR/$tdir
19173         rm -rf $submnt
19174         $LFS setdirstripe -c -1 -i 1 $DIR/$tdir ||
19175                 error "create remote directory failed"
19176         mkdir -p $submnt || error "create $submnt failed"
19177         $MOUNT_CMD $MGSNID:/$FSNAME/$tdir $submnt ||
19178                 error "mount $submnt failed"
19179         stack_trap "umount $submnt" EXIT
19180
19181         cp $srcfile $dstfile
19182         fid=$($LFS path2fid $dstfile)
19183         path=$($LFS fid2path $submnt "$fid")
19184         [ "$path" = "$dstfile" ] ||
19185                 error "fid2path $submnt $fid failed ($path != $dstfile)"
19186 }
19187 run_test 226c "call path2fid and fid2path under remote dir with subdir mount"
19188
19189 # LU-1299 Executing or running ldd on a truncated executable does not
19190 # cause an out-of-memory condition.
19191 test_227() {
19192         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19193         [ -z "$(which ldd)" ] && skip_env "should have ldd tool"
19194
19195         dd if=$(which date) of=$MOUNT/date bs=1k count=1
19196         chmod +x $MOUNT/date
19197
19198         $MOUNT/date > /dev/null
19199         ldd $MOUNT/date > /dev/null
19200         rm -f $MOUNT/date
19201 }
19202 run_test 227 "running truncated executable does not cause OOM"
19203
19204 # LU-1512 try to reuse idle OI blocks
19205 test_228a() {
19206         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19207         remote_mds_nodsh && skip "remote MDS with nodsh"
19208         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
19209
19210         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
19211         local myDIR=$DIR/$tdir
19212
19213         mkdir -p $myDIR
19214         #define OBD_FAIL_SEQ_EXHAUST             0x1002
19215         $LCTL set_param fail_loc=0x80001002
19216         createmany -o $myDIR/t- 10000
19217         $LCTL set_param fail_loc=0
19218         # The guard is current the largest FID holder
19219         touch $myDIR/guard
19220         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
19221                     tr -d '[')
19222         local IDX=$(($SEQ % 64))
19223
19224         do_facet $SINGLEMDS sync
19225         # Make sure journal flushed.
19226         sleep 6
19227         local blk1=$(do_facet $SINGLEMDS \
19228                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
19229                      grep Blockcount | awk '{print $4}')
19230
19231         # Remove old files, some OI blocks will become idle.
19232         unlinkmany $myDIR/t- 10000
19233         # Create new files, idle OI blocks should be reused.
19234         createmany -o $myDIR/t- 2000
19235         do_facet $SINGLEMDS sync
19236         # Make sure journal flushed.
19237         sleep 6
19238         local blk2=$(do_facet $SINGLEMDS \
19239                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
19240                      grep Blockcount | awk '{print $4}')
19241
19242         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
19243 }
19244 run_test 228a "try to reuse idle OI blocks"
19245
19246 test_228b() {
19247         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19248         remote_mds_nodsh && skip "remote MDS with nodsh"
19249         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
19250
19251         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
19252         local myDIR=$DIR/$tdir
19253
19254         mkdir -p $myDIR
19255         #define OBD_FAIL_SEQ_EXHAUST             0x1002
19256         $LCTL set_param fail_loc=0x80001002
19257         createmany -o $myDIR/t- 10000
19258         $LCTL set_param fail_loc=0
19259         # The guard is current the largest FID holder
19260         touch $myDIR/guard
19261         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
19262                     tr -d '[')
19263         local IDX=$(($SEQ % 64))
19264
19265         do_facet $SINGLEMDS sync
19266         # Make sure journal flushed.
19267         sleep 6
19268         local blk1=$(do_facet $SINGLEMDS \
19269                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
19270                      grep Blockcount | awk '{print $4}')
19271
19272         # Remove old files, some OI blocks will become idle.
19273         unlinkmany $myDIR/t- 10000
19274
19275         # stop the MDT
19276         stop $SINGLEMDS || error "Fail to stop MDT."
19277         # remount the MDT
19278         start $SINGLEMDS $MDT_DEV $MDS_MOUNT_OPTS || error "Fail to start MDT."
19279
19280         df $MOUNT || error "Fail to df."
19281         # Create new files, idle OI blocks should be reused.
19282         createmany -o $myDIR/t- 2000
19283         do_facet $SINGLEMDS sync
19284         # Make sure journal flushed.
19285         sleep 6
19286         local blk2=$(do_facet $SINGLEMDS \
19287                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
19288                      grep Blockcount | awk '{print $4}')
19289
19290         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
19291 }
19292 run_test 228b "idle OI blocks can be reused after MDT restart"
19293
19294 #LU-1881
19295 test_228c() {
19296         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19297         remote_mds_nodsh && skip "remote MDS with nodsh"
19298         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
19299
19300         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
19301         local myDIR=$DIR/$tdir
19302
19303         mkdir -p $myDIR
19304         #define OBD_FAIL_SEQ_EXHAUST             0x1002
19305         $LCTL set_param fail_loc=0x80001002
19306         # 20000 files can guarantee there are index nodes in the OI file
19307         createmany -o $myDIR/t- 20000
19308         $LCTL set_param fail_loc=0
19309         # The guard is current the largest FID holder
19310         touch $myDIR/guard
19311         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
19312                     tr -d '[')
19313         local IDX=$(($SEQ % 64))
19314
19315         do_facet $SINGLEMDS sync
19316         # Make sure journal flushed.
19317         sleep 6
19318         local blk1=$(do_facet $SINGLEMDS \
19319                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
19320                      grep Blockcount | awk '{print $4}')
19321
19322         # Remove old files, some OI blocks will become idle.
19323         unlinkmany $myDIR/t- 20000
19324         rm -f $myDIR/guard
19325         # The OI file should become empty now
19326
19327         # Create new files, idle OI blocks should be reused.
19328         createmany -o $myDIR/t- 2000
19329         do_facet $SINGLEMDS sync
19330         # Make sure journal flushed.
19331         sleep 6
19332         local blk2=$(do_facet $SINGLEMDS \
19333                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
19334                      grep Blockcount | awk '{print $4}')
19335
19336         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
19337 }
19338 run_test 228c "NOT shrink the last entry in OI index node to recycle idle leaf"
19339
19340 test_229() { # LU-2482, LU-3448
19341         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19342         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
19343         [ $MDS1_VERSION -lt $(version_code 2.4.53) ] &&
19344                 skip "No HSM $(lustre_build_version $SINGLEMDS) MDS < 2.4.53"
19345
19346         rm -f $DIR/$tfile
19347
19348         # Create a file with a released layout and stripe count 2.
19349         $MULTIOP $DIR/$tfile H2c ||
19350                 error "failed to create file with released layout"
19351
19352         $LFS getstripe -v $DIR/$tfile
19353
19354         local pattern=$($LFS getstripe -L $DIR/$tfile)
19355         [ X"$pattern" = X"released" ] || error "pattern error ($pattern)"
19356
19357         local stripe_count=$($LFS getstripe -c $DIR/$tfile) ||
19358                 error "getstripe"
19359         [ $stripe_count -eq 2 ] || error "stripe count not 2 ($stripe_count)"
19360         stat $DIR/$tfile || error "failed to stat released file"
19361
19362         chown $RUNAS_ID $DIR/$tfile ||
19363                 error "chown $RUNAS_ID $DIR/$tfile failed"
19364
19365         chgrp $RUNAS_ID $DIR/$tfile ||
19366                 error "chgrp $RUNAS_ID $DIR/$tfile failed"
19367
19368         touch $DIR/$tfile || error "touch $DIR/$tfile failed"
19369         rm $DIR/$tfile || error "failed to remove released file"
19370 }
19371 run_test 229 "getstripe/stat/rm/attr changes work on released files"
19372
19373 test_230a() {
19374         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19375         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19376         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
19377                 skip "Need MDS version at least 2.11.52"
19378
19379         local MDTIDX=1
19380
19381         test_mkdir $DIR/$tdir
19382         test_mkdir -i0 -c1 $DIR/$tdir/test_230_local
19383         local mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230_local)
19384         [ $mdt_idx -ne 0 ] &&
19385                 error "create local directory on wrong MDT $mdt_idx"
19386
19387         $LFS mkdir -i $MDTIDX $DIR/$tdir/test_230 ||
19388                         error "create remote directory failed"
19389         local mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230)
19390         [ $mdt_idx -ne $MDTIDX ] &&
19391                 error "create remote directory on wrong MDT $mdt_idx"
19392
19393         createmany -o $DIR/$tdir/test_230/t- 10 ||
19394                 error "create files on remote directory failed"
19395         mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230/t-0)
19396         [ $mdt_idx -ne $MDTIDX ] && error "create files on wrong MDT $mdt_idx"
19397         rm -r $DIR/$tdir || error "unlink remote directory failed"
19398 }
19399 run_test 230a "Create remote directory and files under the remote directory"
19400
19401 test_230b() {
19402         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19403         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19404         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
19405                 skip "Need MDS version at least 2.11.52"
19406
19407         local MDTIDX=1
19408         local mdt_index
19409         local i
19410         local file
19411         local pid
19412         local stripe_count
19413         local migrate_dir=$DIR/$tdir/migrate_dir
19414         local other_dir=$DIR/$tdir/other_dir
19415
19416         test_mkdir $DIR/$tdir
19417         test_mkdir -i0 -c1 $migrate_dir
19418         test_mkdir -i0 -c1 $other_dir
19419         for ((i=0; i<10; i++)); do
19420                 mkdir -p $migrate_dir/dir_${i}
19421                 createmany -o $migrate_dir/dir_${i}/f 10 ||
19422                         error "create files under remote dir failed $i"
19423         done
19424
19425         cp /etc/passwd $migrate_dir/$tfile
19426         cp /etc/passwd $other_dir/$tfile
19427         chattr +SAD $migrate_dir
19428         chattr +SAD $migrate_dir/$tfile
19429
19430         local old_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
19431         local old_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
19432         local old_dir_mode=$(stat -c%f $migrate_dir)
19433         local old_file_mode=$(stat -c%f $migrate_dir/$tfile)
19434
19435         mkdir -p $migrate_dir/dir_default_stripe2
19436         $LFS setstripe -c 2 $migrate_dir/dir_default_stripe2
19437         $LFS setstripe -c 2 $migrate_dir/${tfile}_stripe2
19438
19439         mkdir -p $other_dir
19440         ln $migrate_dir/$tfile $other_dir/luna
19441         ln $migrate_dir/$tfile $migrate_dir/sofia
19442         ln $other_dir/$tfile $migrate_dir/david
19443         ln -s $migrate_dir/$tfile $other_dir/zachary
19444         ln -s $migrate_dir/$tfile $migrate_dir/${tfile}_ln
19445         ln -s $other_dir/$tfile $migrate_dir/${tfile}_ln_other
19446
19447         local len
19448         local lnktgt
19449
19450         # inline symlink
19451         for len in 58 59 60; do
19452                 lnktgt=$(str_repeat 'l' $len)
19453                 touch $migrate_dir/$lnktgt
19454                 ln -s $lnktgt $migrate_dir/${len}char_ln
19455         done
19456
19457         # PATH_MAX
19458         for len in 4094 4095; do
19459                 lnktgt=$(str_repeat 'l' $len)
19460                 ln -s $lnktgt $migrate_dir/${len}char_ln
19461         done
19462
19463         # NAME_MAX
19464         for len in 254 255; do
19465                 touch $migrate_dir/$(str_repeat 'l' $len)
19466         done
19467
19468         $LFS migrate -m $MDTIDX $migrate_dir ||
19469                 error "fails on migrating remote dir to MDT1"
19470
19471         echo "migratate to MDT1, then checking.."
19472         for ((i = 0; i < 10; i++)); do
19473                 for file in $(find $migrate_dir/dir_${i}); do
19474                         mdt_index=$($LFS getstripe -m $file)
19475                         # broken symlink getstripe will fail
19476                         [ $mdt_index -ne $MDTIDX ] && stat -L $file &&
19477                                 error "$file is not on MDT${MDTIDX}"
19478                 done
19479         done
19480
19481         # the multiple link file should still in MDT0
19482         mdt_index=$($LFS getstripe -m $migrate_dir/$tfile)
19483         [ $mdt_index == 0 ] ||
19484                 error "$file is not on MDT${MDTIDX}"
19485
19486         local new_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
19487         [ "$old_dir_flag" = "$new_dir_flag" ] ||
19488                 error " expect $old_dir_flag get $new_dir_flag"
19489
19490         local new_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
19491         [ "$old_file_flag" = "$new_file_flag" ] ||
19492                 error " expect $old_file_flag get $new_file_flag"
19493
19494         local new_dir_mode=$(stat -c%f $migrate_dir)
19495         [ "$old_dir_mode" = "$new_dir_mode" ] ||
19496                 error "expect mode $old_dir_mode get $new_dir_mode"
19497
19498         local new_file_mode=$(stat -c%f $migrate_dir/$tfile)
19499         [ "$old_file_mode" = "$new_file_mode" ] ||
19500                 error "expect mode $old_file_mode get $new_file_mode"
19501
19502         diff /etc/passwd $migrate_dir/$tfile ||
19503                 error "$tfile different after migration"
19504
19505         diff /etc/passwd $other_dir/luna ||
19506                 error "luna different after migration"
19507
19508         diff /etc/passwd $migrate_dir/sofia ||
19509                 error "sofia different after migration"
19510
19511         diff /etc/passwd $migrate_dir/david ||
19512                 error "david different after migration"
19513
19514         diff /etc/passwd $other_dir/zachary ||
19515                 error "zachary different after migration"
19516
19517         diff /etc/passwd $migrate_dir/${tfile}_ln ||
19518                 error "${tfile}_ln different after migration"
19519
19520         diff /etc/passwd $migrate_dir/${tfile}_ln_other ||
19521                 error "${tfile}_ln_other different after migration"
19522
19523         stripe_count=$($LFS getstripe -c $migrate_dir/dir_default_stripe2)
19524         [ $stripe_count = 2 ] ||
19525                 error "dir strpe_count $d != 2 after migration."
19526
19527         stripe_count=$($LFS getstripe -c $migrate_dir/${tfile}_stripe2)
19528         [ $stripe_count = 2 ] ||
19529                 error "file strpe_count $d != 2 after migration."
19530
19531         #migrate back to MDT0
19532         MDTIDX=0
19533
19534         $LFS migrate -m $MDTIDX $migrate_dir ||
19535                 error "fails on migrating remote dir to MDT0"
19536
19537         echo "migrate back to MDT0, checking.."
19538         for file in $(find $migrate_dir); do
19539                 mdt_index=$($LFS getstripe -m $file)
19540                 [ $mdt_index -ne $MDTIDX ] && stat -L $file &&
19541                         error "$file is not on MDT${MDTIDX}"
19542         done
19543
19544         local new_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
19545         [ "$old_dir_flag" = "$new_dir_flag" ] ||
19546                 error " expect $old_dir_flag get $new_dir_flag"
19547
19548         local new_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
19549         [ "$old_file_flag" = "$new_file_flag" ] ||
19550                 error " expect $old_file_flag get $new_file_flag"
19551
19552         local new_dir_mode=$(stat -c%f $migrate_dir)
19553         [ "$old_dir_mode" = "$new_dir_mode" ] ||
19554                 error "expect mode $old_dir_mode get $new_dir_mode"
19555
19556         local new_file_mode=$(stat -c%f $migrate_dir/$tfile)
19557         [ "$old_file_mode" = "$new_file_mode" ] ||
19558                 error "expect mode $old_file_mode get $new_file_mode"
19559
19560         diff /etc/passwd ${migrate_dir}/$tfile ||
19561                 error "$tfile different after migration"
19562
19563         diff /etc/passwd ${other_dir}/luna ||
19564                 error "luna different after migration"
19565
19566         diff /etc/passwd ${migrate_dir}/sofia ||
19567                 error "sofia different after migration"
19568
19569         diff /etc/passwd ${other_dir}/zachary ||
19570                 error "zachary different after migration"
19571
19572         diff /etc/passwd $migrate_dir/${tfile}_ln ||
19573                 error "${tfile}_ln different after migration"
19574
19575         diff /etc/passwd $migrate_dir/${tfile}_ln_other ||
19576                 error "${tfile}_ln_other different after migration"
19577
19578         stripe_count=$($LFS getstripe -c ${migrate_dir}/dir_default_stripe2)
19579         [ $stripe_count = 2 ] ||
19580                 error "dir strpe_count $d != 2 after migration."
19581
19582         stripe_count=$($LFS getstripe -c ${migrate_dir}/${tfile}_stripe2)
19583         [ $stripe_count = 2 ] ||
19584                 error "file strpe_count $d != 2 after migration."
19585
19586         rm -rf $DIR/$tdir || error "rm dir failed after migration"
19587 }
19588 run_test 230b "migrate directory"
19589
19590 test_230c() {
19591         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19592         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19593         remote_mds_nodsh && skip "remote MDS with nodsh"
19594         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
19595                 skip "Need MDS version at least 2.11.52"
19596
19597         local MDTIDX=1
19598         local total=3
19599         local mdt_index
19600         local file
19601         local migrate_dir=$DIR/$tdir/migrate_dir
19602
19603         #If migrating directory fails in the middle, all entries of
19604         #the directory is still accessiable.
19605         test_mkdir $DIR/$tdir
19606         test_mkdir -i0 -c1 $migrate_dir
19607         test_mkdir -i1 -c1 $DIR/$tdir/remote_dir
19608         stat $migrate_dir
19609         createmany -o $migrate_dir/f $total ||
19610                 error "create files under ${migrate_dir} failed"
19611
19612         # fail after migrating top dir, and this will fail only once, so the
19613         # first sub file migration will fail (currently f3), others succeed.
19614         #OBD_FAIL_MIGRATE_ENTRIES       0x1801
19615         do_facet mds1 lctl set_param fail_loc=0x1801
19616         local t=$(ls $migrate_dir | wc -l)
19617         $LFS migrate --mdt-index $MDTIDX $migrate_dir &&
19618                 error "migrate should fail"
19619         local u=$(ls $migrate_dir | wc -l)
19620         [ "$u" == "$t" ] || error "$u != $t during migration"
19621
19622         # add new dir/file should succeed
19623         mkdir $migrate_dir/dir ||
19624                 error "mkdir failed under migrating directory"
19625         touch $migrate_dir/file ||
19626                 error "create file failed under migrating directory"
19627
19628         # add file with existing name should fail
19629         for file in $migrate_dir/f*; do
19630                 stat $file > /dev/null || error "stat $file failed"
19631                 $OPENFILE -f O_CREAT:O_EXCL $file &&
19632                         error "open(O_CREAT|O_EXCL) $file should fail"
19633                 $MULTIOP $file m && error "create $file should fail"
19634                 touch $DIR/$tdir/remote_dir/$tfile ||
19635                         error "touch $tfile failed"
19636                 ln $DIR/$tdir/remote_dir/$tfile $file &&
19637                         error "link $file should fail"
19638                 mdt_index=$($LFS getstripe -m $file)
19639                 if [ $mdt_index == 0 ]; then
19640                         # file failed to migrate is not allowed to rename to
19641                         mv $DIR/$tdir/remote_dir/$tfile $file &&
19642                                 error "rename to $file should fail"
19643                 else
19644                         mv $DIR/$tdir/remote_dir/$tfile $file ||
19645                                 error "rename to $file failed"
19646                 fi
19647                 echo hello >> $file || error "write $file failed"
19648         done
19649
19650         # resume migration with different options should fail
19651         $LFS migrate -m 0 $migrate_dir &&
19652                 error "migrate -m 0 $migrate_dir should fail"
19653
19654         $LFS migrate -m $MDTIDX -c 2 $migrate_dir &&
19655                 error "migrate -c 2 $migrate_dir should fail"
19656
19657         # resume migration should succeed
19658         $LFS migrate -m $MDTIDX $migrate_dir ||
19659                 error "migrate $migrate_dir failed"
19660
19661         echo "Finish migration, then checking.."
19662         for file in $(find $migrate_dir); do
19663                 mdt_index=$($LFS getstripe -m $file)
19664                 [ $mdt_index == $MDTIDX ] ||
19665                         error "$file is not on MDT${MDTIDX}"
19666         done
19667
19668         rm -rf $DIR/$tdir || error "rm dir failed after migration"
19669 }
19670 run_test 230c "check directory accessiblity if migration failed"
19671
19672 test_230d() {
19673         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19674         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19675         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
19676                 skip "Need MDS version at least 2.11.52"
19677         # LU-11235
19678         [ "$mds1_FSTYPE" == "zfs" ] && skip "skip ZFS backend"
19679
19680         local migrate_dir=$DIR/$tdir/migrate_dir
19681         local old_index
19682         local new_index
19683         local old_count
19684         local new_count
19685         local new_hash
19686         local mdt_index
19687         local i
19688         local j
19689
19690         old_index=$((RANDOM % MDSCOUNT))
19691         old_count=$((MDSCOUNT - old_index))
19692         new_index=$((RANDOM % MDSCOUNT))
19693         new_count=$((MDSCOUNT - new_index))
19694         new_hash=1 # for all_char
19695
19696         [ $old_count -gt 1 ] && old_count=$((old_count - RANDOM % old_count))
19697         [ $new_count -gt 1 ] && new_count=$((new_count - RANDOM % new_count))
19698
19699         test_mkdir $DIR/$tdir
19700         test_mkdir -i $old_index -c $old_count $migrate_dir
19701
19702         for ((i=0; i<100; i++)); do
19703                 test_mkdir -i0 -c1 $migrate_dir/dir_${i}
19704                 createmany -o $migrate_dir/dir_${i}/f 100 ||
19705                         error "create files under remote dir failed $i"
19706         done
19707
19708         echo -n "Migrate from MDT$old_index "
19709         [ $old_count -gt 1 ] && echo -n "... MDT$((old_index + old_count - 1)) "
19710         echo -n "to MDT$new_index"
19711         [ $new_count -gt 1 ] && echo -n " ... MDT$((new_index + new_count - 1))"
19712         echo
19713
19714         echo "$LFS migrate -m$new_index -c$new_count -H $new_hash $migrate_dir"
19715         $LFS migrate -m $new_index -c $new_count -H $new_hash $migrate_dir ||
19716                 error "migrate remote dir error"
19717
19718         echo "Finish migration, then checking.."
19719         for file in $(find $migrate_dir -maxdepth 1); do
19720                 mdt_index=$($LFS getstripe -m $file)
19721                 if [ $mdt_index -lt $new_index ] ||
19722                    [ $mdt_index -gt $((new_index + new_count - 1)) ]; then
19723                         error "$file is on MDT$mdt_index"
19724                 fi
19725         done
19726
19727         rm -rf $DIR/$tdir || error "rm dir failed after migration"
19728 }
19729 run_test 230d "check migrate big directory"
19730
19731 test_230e() {
19732         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19733         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19734         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
19735                 skip "Need MDS version at least 2.11.52"
19736
19737         local i
19738         local j
19739         local a_fid
19740         local b_fid
19741
19742         mkdir_on_mdt0 $DIR/$tdir
19743         mkdir $DIR/$tdir/migrate_dir
19744         mkdir $DIR/$tdir/other_dir
19745         touch $DIR/$tdir/migrate_dir/a
19746         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/b
19747         ls $DIR/$tdir/other_dir
19748
19749         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
19750                 error "migrate dir fails"
19751
19752         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir)
19753         [ $mdt_index == 1 ] || error "migrate_dir is not on MDT1"
19754
19755         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
19756         [ $mdt_index == 0 ] || error "a is not on MDT0"
19757
19758         $LFS migrate -m 1 $DIR/$tdir/other_dir ||
19759                 error "migrate dir fails"
19760
19761         mdt_index=$($LFS getstripe -m $DIR/$tdir/other_dir)
19762         [ $mdt_index == 1 ] || error "other_dir is not on MDT1"
19763
19764         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
19765         [ $mdt_index == 1 ] || error "a is not on MDT1"
19766
19767         mdt_index=$($LFS getstripe -m $DIR/$tdir/other_dir/b)
19768         [ $mdt_index == 1 ] || error "b is not on MDT1"
19769
19770         a_fid=$($LFS path2fid $DIR/$tdir/migrate_dir/a)
19771         b_fid=$($LFS path2fid $DIR/$tdir/other_dir/b)
19772
19773         [ "$a_fid" = "$b_fid" ] || error "different fid after migration"
19774
19775         rm -rf $DIR/$tdir || error "rm dir failed after migration"
19776 }
19777 run_test 230e "migrate mulitple local link files"
19778
19779 test_230f() {
19780         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19781         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19782         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
19783                 skip "Need MDS version at least 2.11.52"
19784
19785         local a_fid
19786         local ln_fid
19787
19788         mkdir -p $DIR/$tdir
19789         mkdir $DIR/$tdir/migrate_dir
19790         $LFS mkdir -i1 $DIR/$tdir/other_dir
19791         touch $DIR/$tdir/migrate_dir/a
19792         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/ln1
19793         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/ln2
19794         ls $DIR/$tdir/other_dir
19795
19796         # a should be migrated to MDT1, since no other links on MDT0
19797         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
19798                 error "#1 migrate dir fails"
19799         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir)
19800         [ $mdt_index == 1 ] || error "migrate_dir is not on MDT1"
19801         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
19802         [ $mdt_index == 1 ] || error "a is not on MDT1"
19803
19804         # a should stay on MDT1, because it is a mulitple link file
19805         $LFS migrate -m 0 $DIR/$tdir/migrate_dir ||
19806                 error "#2 migrate dir fails"
19807         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
19808         [ $mdt_index == 1 ] || error "a is not on MDT1"
19809
19810         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
19811                 error "#3 migrate dir fails"
19812
19813         a_fid=$($LFS path2fid $DIR/$tdir/migrate_dir/a)
19814         ln_fid=$($LFS path2fid $DIR/$tdir/other_dir/ln1)
19815         [ "$a_fid" = "$ln_fid" ] || error "different fid after migrate to MDT1"
19816
19817         rm -rf $DIR/$tdir/other_dir/ln1 || error "unlink ln1 fails"
19818         rm -rf $DIR/$tdir/other_dir/ln2 || error "unlink ln2 fails"
19819
19820         # a should be migrated to MDT0, since no other links on MDT1
19821         $LFS migrate -m 0 $DIR/$tdir/migrate_dir ||
19822                 error "#4 migrate dir fails"
19823         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
19824         [ $mdt_index == 0 ] || error "a is not on MDT0"
19825
19826         rm -rf $DIR/$tdir || error "rm dir failed after migration"
19827 }
19828 run_test 230f "migrate mulitple remote link files"
19829
19830 test_230g() {
19831         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19832         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19833         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
19834                 skip "Need MDS version at least 2.11.52"
19835
19836         mkdir -p $DIR/$tdir/migrate_dir
19837
19838         $LFS migrate -m 1000 $DIR/$tdir/migrate_dir &&
19839                 error "migrating dir to non-exist MDT succeeds"
19840         true
19841 }
19842 run_test 230g "migrate dir to non-exist MDT"
19843
19844 test_230h() {
19845         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19846         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19847         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
19848                 skip "Need MDS version at least 2.11.52"
19849
19850         local mdt_index
19851
19852         mkdir -p $DIR/$tdir/migrate_dir
19853
19854         $LFS migrate -m1 $DIR &&
19855                 error "migrating mountpoint1 should fail"
19856
19857         $LFS migrate -m1 $DIR/$tdir/.. &&
19858                 error "migrating mountpoint2 should fail"
19859
19860         # same as mv
19861         $LFS migrate -m1 $DIR/$tdir/migrate_dir/.. &&
19862                 error "migrating $tdir/migrate_dir/.. should fail"
19863
19864         true
19865 }
19866 run_test 230h "migrate .. and root"
19867
19868 test_230i() {
19869         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19870         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19871         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
19872                 skip "Need MDS version at least 2.11.52"
19873
19874         mkdir -p $DIR/$tdir/migrate_dir
19875
19876         $LFS migrate -m 1 $DIR/$tdir/migrate_dir/ ||
19877                 error "migration fails with a tailing slash"
19878
19879         $LFS migrate -m 0 $DIR/$tdir/migrate_dir// ||
19880                 error "migration fails with two tailing slashes"
19881 }
19882 run_test 230i "lfs migrate -m tolerates trailing slashes"
19883
19884 test_230j() {
19885         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
19886         [ $MDS1_VERSION -lt $(version_code 2.13.52) ] &&
19887                 skip "Need MDS version at least 2.11.52"
19888
19889         $LFS mkdir -m 0 -c 1 $DIR/$tdir || error "mkdir $tdir failed"
19890         $LFS setstripe -E 1M -L mdt $DIR/$tdir/$tfile ||
19891                 error "create $tfile failed"
19892         cat /etc/passwd > $DIR/$tdir/$tfile
19893
19894         $LFS migrate -m 1 $DIR/$tdir || error "migrate failed"
19895
19896         cmp /etc/passwd $DIR/$tdir/$tfile ||
19897                 error "DoM file mismatch after migration"
19898 }
19899 run_test 230j "DoM file data not changed after dir migration"
19900
19901 test_230k() {
19902         [ $MDSCOUNT -lt 4 ] && skip "needs >= 4 MDTs"
19903         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
19904                 skip "Need MDS version at least 2.11.56"
19905
19906         local total=20
19907         local files_on_starting_mdt=0
19908
19909         $LFS mkdir -i -1 -c 2 $DIR/$tdir || error "mkdir failed"
19910         $LFS getdirstripe $DIR/$tdir
19911         for i in $(seq $total); do
19912                 echo $((i*i - i)) > $DIR/$tdir/$tfile.$i || error "write failed"
19913                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 0 ]] &&
19914                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
19915         done
19916
19917         echo "$files_on_starting_mdt files on MDT0"
19918
19919         $LFS migrate -m 1,3 $DIR/$tdir || error "migrate -m 1,3 failed"
19920         $LFS getdirstripe $DIR/$tdir
19921
19922         files_on_starting_mdt=0
19923         for i in $(seq $total); do
19924                 $(echo $((i*i - i)) | cmp $DIR/$tdir/$tfile.$i -) ||
19925                         error "file $tfile.$i mismatch after migration"
19926                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 1 ]] &&
19927                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
19928         done
19929
19930         echo "$files_on_starting_mdt files on MDT1 after migration"
19931         [[ $files_on_starting_mdt -eq $total ]] && error "all files on MDT1"
19932
19933         $LFS migrate -m 0 -c 2 $DIR/$tdir || error "migrate -m 0 -c 2 failed"
19934         $LFS getdirstripe $DIR/$tdir
19935
19936         files_on_starting_mdt=0
19937         for i in $(seq $total); do
19938                 $(echo $((i*i - i)) | cmp $DIR/$tdir/$tfile.$i -) ||
19939                         error "file $tfile.$i mismatch after 2nd migration"
19940                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 0 ]] &&
19941                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
19942         done
19943
19944         echo "$files_on_starting_mdt files on MDT0 after 2nd migration"
19945         [[ $files_on_starting_mdt -eq $total ]] && error "all files on MDT0"
19946
19947         true
19948 }
19949 run_test 230k "file data not changed after dir migration"
19950
19951 test_230l() {
19952         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
19953         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
19954                 skip "Need MDS version at least 2.11.56"
19955
19956         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "mkdir failed"
19957         createmany -o $DIR/$tdir/f___________________________________ 1000 ||
19958                 error "create files under remote dir failed $i"
19959         $LFS migrate -m 1 $DIR/$tdir || error "migrate failed"
19960 }
19961 run_test 230l "readdir between MDTs won't crash"
19962
19963 test_230m() {
19964         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
19965         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
19966                 skip "Need MDS version at least 2.11.56"
19967
19968         local MDTIDX=1
19969         local mig_dir=$DIR/$tdir/migrate_dir
19970         local longstr="aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
19971         local shortstr="b"
19972         local val
19973
19974         echo "Creating files and dirs with xattrs"
19975         test_mkdir $DIR/$tdir
19976         test_mkdir -i0 -c1 $mig_dir
19977         mkdir $mig_dir/dir
19978         setfattr -n user.attr1 -v $longstr $mig_dir/dir ||
19979                 error "cannot set xattr attr1 on dir"
19980         setfattr -n user.attr2 -v $shortstr $mig_dir/dir ||
19981                 error "cannot set xattr attr2 on dir"
19982         touch $mig_dir/dir/f0
19983         setfattr -n user.attr1 -v $longstr $mig_dir/dir/f0 ||
19984                 error "cannot set xattr attr1 on file"
19985         setfattr -n user.attr2 -v $shortstr $mig_dir/dir/f0 ||
19986                 error "cannot set xattr attr2 on file"
19987         sync ; sync ; echo 3 > /proc/sys/vm/drop_caches
19988         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir 2>/dev/null)
19989         [ "$val" = $longstr ] || error "xattr attr1 not set properly on dir"
19990         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir 2>/dev/null)
19991         [ "$val" = $shortstr ] || error "xattr attr2 not set properly on dir"
19992         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir/f0 2>/dev/null)
19993         [ "$val" = $longstr ] || error "xattr attr1 not set properly on file"
19994         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir/f0 2>/dev/null)
19995         [ "$val" = $shortstr ] || error "xattr attr2 not set properly on file"
19996
19997         echo "Migrating to MDT1"
19998         $LFS migrate -m $MDTIDX $mig_dir ||
19999                 error "fails on migrating dir to MDT1"
20000
20001         sync ; sync ; echo 3 > /proc/sys/vm/drop_caches
20002         echo "Checking xattrs"
20003         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir 2>/dev/null)
20004         [ "$val" = $longstr ] ||
20005                 error "expecting xattr1 $longstr on dir, found $val"
20006         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir 2>/dev/null)
20007         [ "$val" = $shortstr ] ||
20008                 error "expecting xattr2 $shortstr on dir, found $val"
20009         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir/f0 2>/dev/null)
20010         [ "$val" = $longstr ] ||
20011                 error "expecting xattr1 $longstr on file, found $val"
20012         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir/f0 2>/dev/null)
20013         [ "$val" = $shortstr ] ||
20014                 error "expecting xattr2 $shortstr on file, found $val"
20015 }
20016 run_test 230m "xattrs not changed after dir migration"
20017
20018 test_230n() {
20019         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
20020         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
20021                 skip "Need MDS version at least 2.13.53"
20022
20023         $LFS mkdir -i 0 $DIR/$tdir || error "mkdir $tdir failed"
20024         cat /etc/hosts > $DIR/$tdir/$tfile
20025         $LFS mirror extend -N1 $DIR/$tdir/$tfile || error "Mirroring failed"
20026         $LFS migrate -m 1 $DIR/$tdir || error "Migration failed"
20027
20028         cmp /etc/hosts $DIR/$tdir/$tfile ||
20029                 error "File data mismatch after migration"
20030 }
20031 run_test 230n "Dir migration with mirrored file"
20032
20033 test_230o() {
20034         [ $MDSCOUNT -ge 2 ] || skip "needs >= 2 MDTs"
20035         [ $MDS1_VERSION -ge $(version_code 2.13.52) ] ||
20036                 skip "Need MDS version at least 2.13.52"
20037
20038         local mdts=$(comma_list $(mdts_nodes))
20039         local timeout=100
20040         local restripe_status
20041         local delta
20042         local i
20043
20044         [[ $mds1_FSTYPE == zfs ]] && timeout=300
20045
20046         # in case "crush" hash type is not set
20047         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
20048
20049         restripe_status=$(do_facet mds1 $LCTL get_param -n \
20050                            mdt.*MDT0000.enable_dir_restripe)
20051         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=1"
20052         stack_trap "do_nodes $mdts $LCTL set_param \
20053                     mdt.*.enable_dir_restripe=$restripe_status"
20054
20055         mkdir $DIR/$tdir
20056         createmany -m $DIR/$tdir/f 100 ||
20057                 error "create files under remote dir failed $i"
20058         createmany -d $DIR/$tdir/d 100 ||
20059                 error "create dirs under remote dir failed $i"
20060
20061         for i in $(seq 2 $MDSCOUNT); do
20062                 do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear >/dev/null"
20063                 $LFS setdirstripe -c $i $DIR/$tdir ||
20064                         error "split -c $i $tdir failed"
20065                 wait_update $HOSTNAME \
20066                         "$LFS getdirstripe -H $DIR/$tdir" "crush" $timeout ||
20067                         error "dir split not finished"
20068                 delta=$(do_nodes $mdts "lctl get_param -n mdt.*MDT*.md_stats" |
20069                         awk '/migrate/ {sum += $2} END { print sum }')
20070                 echo "$delta migrated when dir split $((i - 1)) to $i stripes"
20071                 # delta is around total_files/stripe_count
20072                 (( $delta < 200 / (i - 1) + 4 )) ||
20073                         error "$delta files migrated >= $((200 / (i - 1) + 4))"
20074         done
20075 }
20076 run_test 230o "dir split"
20077
20078 test_230p() {
20079         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
20080         (( MDS1_VERSION >= $(version_code 2.13.52) )) ||
20081                 skip "Need MDS version at least 2.13.52"
20082
20083         local mdts=$(comma_list $(mdts_nodes))
20084         local timeout=100
20085         local restripe_status
20086         local delta
20087         local c
20088
20089         [[ $mds1_FSTYPE == zfs ]] && timeout=300
20090
20091         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
20092
20093         restripe_status=$(do_facet mds1 $LCTL get_param -n \
20094                            mdt.*MDT0000.enable_dir_restripe)
20095         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=1"
20096         stack_trap "do_nodes $mdts $LCTL set_param \
20097                     mdt.*.enable_dir_restripe=$restripe_status"
20098
20099         test_mkdir -c $MDSCOUNT -H crush $DIR/$tdir
20100         createmany -m $DIR/$tdir/f 100 ||
20101                 error "create files under remote dir failed"
20102         createmany -d $DIR/$tdir/d 100 ||
20103                 error "create dirs under remote dir failed"
20104
20105         for c in $(seq $((MDSCOUNT - 1)) -1 1); do
20106                 local mdt_hash="crush"
20107
20108                 do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear >/dev/null"
20109                 $LFS setdirstripe -c $c $DIR/$tdir ||
20110                         error "split -c $c $tdir failed"
20111                 if (( MDS1_VERSION >= $(version_code 2.14.51) )); then
20112                         mdt_hash="$mdt_hash,fixed"
20113                 elif [ $c -eq 1 ]; then
20114                         mdt_hash="none"
20115                 fi
20116                 wait_update $HOSTNAME \
20117                         "$LFS getdirstripe -H $DIR/$tdir" $mdt_hash $timeout ||
20118                         error "dir merge not finished"
20119                 delta=$(do_nodes $mdts "lctl get_param -n mdt.*MDT*.md_stats" |
20120                         awk '/migrate/ {sum += $2} END { print sum }')
20121                 echo "$delta migrated when dir merge $((c + 1)) to $c stripes"
20122                 # delta is around total_files/stripe_count
20123                 (( delta < 200 / c + 4 )) ||
20124                         error "$delta files migrated >= $((200 / c + 4))"
20125         done
20126 }
20127 run_test 230p "dir merge"
20128
20129 test_230q() {
20130         (( MDSCOUNT > 1)) || skip "needs >= 2 MDTs"
20131         (( MDS1_VERSION >= $(version_code 2.13.52) )) ||
20132                 skip "Need MDS version at least 2.13.52"
20133
20134         local mdts=$(comma_list $(mdts_nodes))
20135         local saved_threshold=$(do_facet mds1 \
20136                         $LCTL get_param -n mdt.*-MDT0000.dir_split_count)
20137         local saved_delta=$(do_facet mds1 \
20138                         $LCTL get_param -n mdt.*-MDT0000.dir_split_delta)
20139         local threshold=100
20140         local delta=2
20141         local total=0
20142         local stripe_count=0
20143         local stripe_index
20144         local nr_files
20145         local create
20146
20147         # test with fewer files on ZFS
20148         [ "$mds1_FSTYPE" == "zfs" ] && threshold=40
20149
20150         stack_trap "do_nodes $mdts $LCTL set_param \
20151                     mdt.*.dir_split_count=$saved_threshold"
20152         stack_trap "do_nodes $mdts $LCTL set_param \
20153                     mdt.*.dir_split_delta=$saved_delta"
20154         stack_trap "do_nodes $mdts $LCTL set_param mdt.*.dir_restripe_nsonly=1"
20155         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_auto_split=1"
20156         do_nodes $mdts "$LCTL set_param mdt.*.dir_split_count=$threshold"
20157         do_nodes $mdts "$LCTL set_param mdt.*.dir_split_delta=$delta"
20158         do_nodes $mdts "$LCTL set_param mdt.*.dir_restripe_nsonly=0"
20159         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
20160
20161         $LFS mkdir -i -1 -c 1 $DIR/$tdir || error "mkdir $tdir failed"
20162         stripe_index=$($LFS getdirstripe -i $DIR/$tdir)
20163
20164         create=$((threshold * 3 / 2))
20165         while [ $stripe_count -lt $MDSCOUNT ]; do
20166                 createmany -m $DIR/$tdir/f $total $create ||
20167                         error "create sub files failed"
20168                 stat $DIR/$tdir > /dev/null
20169                 total=$((total + create))
20170                 stripe_count=$((stripe_count + delta))
20171                 [ $stripe_count -gt $MDSCOUNT ] && stripe_count=$MDSCOUNT
20172
20173                 wait_update $HOSTNAME \
20174                         "$LFS getdirstripe -c $DIR/$tdir" "$stripe_count" 40 ||
20175                         error "stripe count $($LFS getdirstripe -c $DIR/$tdir) != $stripe_count"
20176
20177                 wait_update $HOSTNAME \
20178                         "$LFS getdirstripe -H $DIR/$tdir" "crush" 200 ||
20179                         error "stripe hash $($LFS getdirstripe -H $DIR/$tdir) != crush"
20180
20181                 nr_files=$($LFS find -m 1 $DIR/$tdir | grep -c -w $stripe_index)
20182                 echo "$nr_files/$total files on MDT$stripe_index after split"
20183                 # allow 10% margin of imbalance with crush hash
20184                 (( $nr_files <= $total / $stripe_count + $create / 10)) ||
20185                         error "$nr_files files on MDT$stripe_index after split"
20186
20187                 nr_files=$($LFS find -type f $DIR/$tdir | wc -l)
20188                 [ $nr_files -eq $total ] ||
20189                         error "total sub files $nr_files != $total"
20190         done
20191
20192         (( MDS1_VERSION >= $(version_code 2.14.51) )) || return 0
20193
20194         echo "fixed layout directory won't auto split"
20195         $LFS migrate -m 0 $DIR/$tdir || error "migrate $tdir failed"
20196         wait_update $HOSTNAME "$LFS getdirstripe -H $DIR/$tdir" "crush,fixed" \
20197                 10 || error "stripe hash $($LFS getdirstripe -H $DIR/$tdir)"
20198         wait_update $HOSTNAME "$LFS getdirstripe -c $DIR/$tdir" 1 10 ||
20199                 error "stripe count $($LFS getdirstripe -c $DIR/$tdir)"
20200 }
20201 run_test 230q "dir auto split"
20202
20203 test_230r() {
20204         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
20205         [[ $MDSCOUNT -ge 2 ]] || skip_env "needs >= 2 MDTs"
20206         [[ $MDS1_VERSION -ge $(version_code 2.13.54) ]] ||
20207                 skip "Need MDS version at least 2.13.54"
20208
20209         # maximum amount of local locks:
20210         # parent striped dir - 2 locks
20211         # new stripe in parent to migrate to - 1 lock
20212         # source and target - 2 locks
20213         # Total 5 locks for regular file
20214         mkdir -p $DIR/$tdir
20215         $LFS mkdir -i1 -c2 $DIR/$tdir/dir1
20216         touch $DIR/$tdir/dir1/eee
20217
20218         # create 4 hardlink for 4 more locks
20219         # Total: 9 locks > RS_MAX_LOCKS (8)
20220         $LFS mkdir -i1 -c1 $DIR/$tdir/dir2
20221         $LFS mkdir -i1 -c1 $DIR/$tdir/dir3
20222         $LFS mkdir -i1 -c1 $DIR/$tdir/dir4
20223         $LFS mkdir -i1 -c1 $DIR/$tdir/dir5
20224         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir2/eee
20225         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir3/eee
20226         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir4/eee
20227         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir5/eee
20228
20229         cancel_lru_locks mdc
20230
20231         $LFS migrate -m1 -c1 $DIR/$tdir/dir1 ||
20232                 error "migrate dir fails"
20233
20234         rm -rf $DIR/$tdir || error "rm dir failed after migration"
20235 }
20236 run_test 230r "migrate with too many local locks"
20237
20238 test_230s() {
20239         [ $MDS1_VERSION -ge $(version_code 2.13.57) ] ||
20240                 skip "Need MDS version at least 2.13.57"
20241
20242         local mdts=$(comma_list $(mdts_nodes))
20243         local restripe_status=$(do_facet mds1 $LCTL get_param -n \
20244                                 mdt.*MDT0000.enable_dir_restripe)
20245
20246         stack_trap "do_nodes $mdts $LCTL set_param \
20247                     mdt.*.enable_dir_restripe=$restripe_status"
20248
20249         local st
20250         for st in 0 1; do
20251                 do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=$st"
20252                 test_mkdir $DIR/$tdir
20253                 $LFS mkdir $DIR/$tdir |& grep "File exists" ||
20254                         error "$LFS mkdir doesn't return -EEXIST if target exists"
20255                 rmdir $DIR/$tdir
20256         done
20257 }
20258 run_test 230s "lfs mkdir should return -EEXIST if target exists"
20259
20260 test_230t()
20261 {
20262         [[ $MDSCOUNT -ge 2 ]] || skip_env "needs >= 2 MDTs"
20263         [[ $MDS1_VERSION -ge $(version_code 2.14.50) ]] ||
20264                 skip "Need MDS version at least 2.14.50"
20265
20266         test_mkdir $DIR/$tdir || error "mkdir $tdir failed"
20267         test_mkdir $DIR/$tdir/subdir || error "mkdir subdir failed"
20268         $LFS project -p 1 -s $DIR/$tdir ||
20269                 error "set $tdir project id failed"
20270         $LFS project -p 2 -s $DIR/$tdir/subdir ||
20271                 error "set subdir project id failed"
20272         $LFS migrate -m 1 -c $MDSCOUNT $DIR/$tdir || error "migrate failed"
20273 }
20274 run_test 230t "migrate directory with project ID set"
20275
20276 test_230u()
20277 {
20278         (( MDSCOUNT > 3 )) || skip_env "needs >= 4 MDTs"
20279         (( MDS1_VERSION >= $(version_code 2.14.53) )) ||
20280                 skip "Need MDS version at least 2.14.53"
20281
20282         local count
20283
20284         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
20285         mkdir $DIR/$tdir/sub{0..99} || error "mkdir sub failed"
20286         $LFS migrate -m -1 $DIR/$tdir/sub{0..99} || error "migrate sub failed"
20287         for i in $(seq 0 $((MDSCOUNT - 1))); do
20288                 count=$($LFS getstripe -m $DIR/$tdir/sub* | grep -c ^$i)
20289                 echo "$count dirs migrated to MDT$i"
20290         done
20291         count=$($LFS getstripe -m $DIR/$tdir/sub* | sort -u | wc -l)
20292         (( count >= MDSCOUNT - 1 )) || error "dirs migrated to $count MDTs"
20293 }
20294 run_test 230u "migrate directory by QOS"
20295
20296 test_230v()
20297 {
20298         (( MDSCOUNT > 3 )) || skip_env "needs >= 4 MDTs"
20299         (( MDS1_VERSION >= $(version_code 2.14.53) )) ||
20300                 skip "Need MDS version at least 2.14.53"
20301
20302         local count
20303
20304         mkdir $DIR/$tdir || error "mkdir $tdir failed"
20305         mkdir $DIR/$tdir/sub{0..99} || error "mkdir sub failed"
20306         $LFS migrate -m 0,2,1 $DIR/$tdir || error "migrate $tdir failed"
20307         for i in $(seq 0 $((MDSCOUNT - 1))); do
20308                 count=$($LFS getstripe -m $DIR/$tdir/sub* | grep -c ^$i)
20309                 echo "$count subdirs migrated to MDT$i"
20310                 (( i == 3 )) && (( count > 0 )) &&
20311                         error "subdir shouldn't be migrated to MDT3"
20312         done
20313         count=$($LFS getstripe -m $DIR/$tdir/sub* | sort -u | wc -l)
20314         (( count == 3 )) || error "dirs migrated to $count MDTs"
20315 }
20316 run_test 230v "subdir migrated to the MDT where its parent is located"
20317
20318 test_231a()
20319 {
20320         # For simplicity this test assumes that max_pages_per_rpc
20321         # is the same across all OSCs
20322         local max_pages=$($LCTL get_param -n osc.*.max_pages_per_rpc | head -n1)
20323         local bulk_size=$((max_pages * PAGE_SIZE))
20324         local brw_size=$(do_facet ost1 $LCTL get_param -n obdfilter.*.brw_size |
20325                                        head -n 1)
20326
20327         mkdir -p $DIR/$tdir
20328         $LFS setstripe -S ${brw_size}M $DIR/$tdir ||
20329                 error "failed to set stripe with -S ${brw_size}M option"
20330
20331         # clear the OSC stats
20332         $LCTL set_param osc.*.stats=0 &>/dev/null
20333         stop_writeback
20334
20335         # Client writes $bulk_size - there must be 1 rpc for $max_pages.
20336         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=$bulk_size count=1 \
20337                 oflag=direct &>/dev/null || error "dd failed"
20338
20339         sync; sleep 1; sync # just to be safe
20340         local nrpcs=$($LCTL get_param osc.*.stats |awk '/ost_write/ {print $2}')
20341         if [ x$nrpcs != "x1" ]; then
20342                 $LCTL get_param osc.*.stats
20343                 error "found $nrpcs ost_write RPCs, not 1 as expected"
20344         fi
20345
20346         start_writeback
20347         # Drop the OSC cache, otherwise we will read from it
20348         cancel_lru_locks osc
20349
20350         # clear the OSC stats
20351         $LCTL set_param osc.*.stats=0 &>/dev/null
20352
20353         # Client reads $bulk_size.
20354         dd if=$DIR/$tdir/$tfile of=/dev/null bs=$bulk_size count=1 \
20355                 iflag=direct &>/dev/null || error "dd failed"
20356
20357         nrpcs=$($LCTL get_param osc.*.stats | awk '/ost_read/ { print $2 }')
20358         if [ x$nrpcs != "x1" ]; then
20359                 $LCTL get_param osc.*.stats
20360                 error "found $nrpcs ost_read RPCs, not 1 as expected"
20361         fi
20362 }
20363 run_test 231a "checking that reading/writing of BRW RPC size results in one RPC"
20364
20365 test_231b() {
20366         mkdir -p $DIR/$tdir
20367         local i
20368         for i in {0..1023}; do
20369                 dd if=/dev/zero of=$DIR/$tdir/$tfile conv=notrunc \
20370                         seek=$((2 * i)) bs=4096 count=1 &>/dev/null ||
20371                         error "dd of=$DIR/$tdir/$tfile seek=$((2 * i)) failed"
20372         done
20373         sync
20374 }
20375 run_test 231b "must not assert on fully utilized OST request buffer"
20376
20377 test_232a() {
20378         mkdir -p $DIR/$tdir
20379         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
20380
20381         #define OBD_FAIL_LDLM_OST_LVB            0x31c
20382         do_facet ost1 $LCTL set_param fail_loc=0x31c
20383
20384         # ignore dd failure
20385         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=1 || true
20386
20387         do_facet ost1 $LCTL set_param fail_loc=0
20388         umount_client $MOUNT || error "umount failed"
20389         mount_client $MOUNT || error "mount failed"
20390         stop ost1 || error "cannot stop ost1"
20391         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
20392 }
20393 run_test 232a "failed lock should not block umount"
20394
20395 test_232b() {
20396         [ $MDS1_VERSION -ge $(version_code 2.10.58) ] ||
20397                 skip "Need MDS version at least 2.10.58"
20398
20399         mkdir -p $DIR/$tdir
20400         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
20401         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=1
20402         sync
20403         cancel_lru_locks osc
20404
20405         #define OBD_FAIL_LDLM_OST_LVB            0x31c
20406         do_facet ost1 $LCTL set_param fail_loc=0x31c
20407
20408         # ignore failure
20409         $LFS data_version $DIR/$tdir/$tfile || true
20410
20411         do_facet ost1 $LCTL set_param fail_loc=0
20412         umount_client $MOUNT || error "umount failed"
20413         mount_client $MOUNT || error "mount failed"
20414         stop ost1 || error "cannot stop ost1"
20415         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
20416 }
20417 run_test 232b "failed data version lock should not block umount"
20418
20419 test_233a() {
20420         [ $MDS1_VERSION -ge $(version_code 2.3.64) ] ||
20421                 skip "Need MDS version at least 2.3.64"
20422         [ -n "$FILESET" ] && skip_env "SKIP due to FILESET set"
20423
20424         local fid=$($LFS path2fid $MOUNT)
20425
20426         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
20427                 error "cannot access $MOUNT using its FID '$fid'"
20428 }
20429 run_test 233a "checking that OBF of the FS root succeeds"
20430
20431 test_233b() {
20432         [ $MDS1_VERSION -ge $(version_code 2.5.90) ] ||
20433                 skip "Need MDS version at least 2.5.90"
20434         [ -n "$FILESET" ] && skip_env "SKIP due to FILESET set"
20435
20436         local fid=$($LFS path2fid $MOUNT/.lustre)
20437
20438         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
20439                 error "cannot access $MOUNT/.lustre using its FID '$fid'"
20440
20441         fid=$($LFS path2fid $MOUNT/.lustre/fid)
20442         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
20443                 error "cannot access $MOUNT/.lustre/fid using its FID '$fid'"
20444 }
20445 run_test 233b "checking that OBF of the FS .lustre succeeds"
20446
20447 test_234() {
20448         local p="$TMP/sanityN-$TESTNAME.parameters"
20449         save_lustre_params client "llite.*.xattr_cache" > $p
20450         lctl set_param llite.*.xattr_cache 1 ||
20451                 skip_env "xattr cache is not supported"
20452
20453         mkdir -p $DIR/$tdir || error "mkdir failed"
20454         touch $DIR/$tdir/$tfile || error "touch failed"
20455         # OBD_FAIL_LLITE_XATTR_ENOMEM
20456         $LCTL set_param fail_loc=0x1405
20457         getfattr -n user.attr $DIR/$tdir/$tfile &&
20458                 error "getfattr should have failed with ENOMEM"
20459         $LCTL set_param fail_loc=0x0
20460         rm -rf $DIR/$tdir
20461
20462         restore_lustre_params < $p
20463         rm -f $p
20464 }
20465 run_test 234 "xattr cache should not crash on ENOMEM"
20466
20467 test_235() {
20468         [ $MDS1_VERSION -lt $(version_code 2.4.52) ] &&
20469                 skip "Need MDS version at least 2.4.52"
20470
20471         flock_deadlock $DIR/$tfile
20472         local RC=$?
20473         case $RC in
20474                 0)
20475                 ;;
20476                 124) error "process hangs on a deadlock"
20477                 ;;
20478                 *) error "error executing flock_deadlock $DIR/$tfile"
20479                 ;;
20480         esac
20481 }
20482 run_test 235 "LU-1715: flock deadlock detection does not work properly"
20483
20484 #LU-2935
20485 test_236() {
20486         check_swap_layouts_support
20487
20488         local ref1=/etc/passwd
20489         local ref2=/etc/group
20490         local file1=$DIR/$tdir/f1
20491         local file2=$DIR/$tdir/f2
20492
20493         test_mkdir -c1 $DIR/$tdir
20494         $LFS setstripe -c 1 $file1 || error "cannot setstripe on '$file1': rc = $?"
20495         cp $ref1 $file1 || error "cp $ref1 $file1 failed: rc = $?"
20496         $LFS setstripe -c 2 $file2 || error "cannot setstripe on '$file2': rc = $?"
20497         cp $ref2 $file2 || error "cp $ref2 $file2 failed: rc = $?"
20498         local fd=$(free_fd)
20499         local cmd="exec $fd<>$file2"
20500         eval $cmd
20501         rm $file2
20502         $LFS swap_layouts $file1 /proc/self/fd/${fd} ||
20503                 error "cannot swap layouts of '$file1' and /proc/self/fd/${fd}"
20504         cmd="exec $fd>&-"
20505         eval $cmd
20506         cmp $ref2 $file1 || error "content compare failed ($ref2 != $file1)"
20507
20508         #cleanup
20509         rm -rf $DIR/$tdir
20510 }
20511 run_test 236 "Layout swap on open unlinked file"
20512
20513 # LU-4659 linkea consistency
20514 test_238() {
20515         [[ $MDS1_VERSION -gt $(version_code 2.5.57) ]] ||
20516                 [[ $MDS1_VERSION -gt $(version_code 2.5.1) &&
20517                    $MDS1_VERSION -lt $(version_code 2.5.50) ]] ||
20518                 skip "Need MDS version at least 2.5.58 or 2.5.2+"
20519
20520         touch $DIR/$tfile
20521         ln $DIR/$tfile $DIR/$tfile.lnk
20522         touch $DIR/$tfile.new
20523         mv $DIR/$tfile.new $DIR/$tfile
20524         local fid1=$($LFS path2fid $DIR/$tfile)
20525         local fid2=$($LFS path2fid $DIR/$tfile.lnk)
20526         local path1=$($LFS fid2path $FSNAME "$fid1")
20527         [ $tfile == $path1 ] || error "linkea inconsistent: $tfile $fid1 $path1"
20528         local path2=$($LFS fid2path $FSNAME "$fid2")
20529         [ $tfile.lnk == $path2 ] ||
20530                 error "linkea inconsistent: $tfile.lnk $fid2 $path2!"
20531         rm -f $DIR/$tfile*
20532 }
20533 run_test 238 "Verify linkea consistency"
20534
20535 test_239A() { # was test_239
20536         [ $MDS1_VERSION -lt $(version_code 2.5.60) ] &&
20537                 skip "Need MDS version at least 2.5.60"
20538
20539         local list=$(comma_list $(mdts_nodes))
20540
20541         mkdir -p $DIR/$tdir
20542         createmany -o $DIR/$tdir/f- 5000
20543         unlinkmany $DIR/$tdir/f- 5000
20544         [ $MDS1_VERSION -gt $(version_code 2.10.4) ] &&
20545                 do_nodes $list "lctl set_param -n osp.*.force_sync=1"
20546         changes=$(do_nodes $list "lctl get_param -n osp.*MDT*.sync_changes \
20547                         osp.*MDT*.sync_in_flight" | calc_sum)
20548         [ "$changes" -eq 0 ] || error "$changes not synced"
20549 }
20550 run_test 239A "osp_sync test"
20551
20552 test_239a() { #LU-5297
20553         remote_mds_nodsh && skip "remote MDS with nodsh"
20554
20555         touch $DIR/$tfile
20556         #define OBD_FAIL_OSP_CHECK_INVALID_REC     0x2100
20557         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2100
20558         chgrp $RUNAS_GID $DIR/$tfile
20559         wait_delete_completed
20560 }
20561 run_test 239a "process invalid osp sync record correctly"
20562
20563 test_239b() { #LU-5297
20564         remote_mds_nodsh && skip "remote MDS with nodsh"
20565
20566         touch $DIR/$tfile1
20567         #define OBD_FAIL_OSP_CHECK_ENOMEM     0x2101
20568         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2101
20569         chgrp $RUNAS_GID $DIR/$tfile1
20570         wait_delete_completed
20571         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
20572         touch $DIR/$tfile2
20573         chgrp $RUNAS_GID $DIR/$tfile2
20574         wait_delete_completed
20575 }
20576 run_test 239b "process osp sync record with ENOMEM error correctly"
20577
20578 test_240() {
20579         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20580         remote_mds_nodsh && skip "remote MDS with nodsh"
20581
20582         mkdir -p $DIR/$tdir
20583
20584         $LFS mkdir -i 0 $DIR/$tdir/d0 ||
20585                 error "failed to mkdir $DIR/$tdir/d0 on MDT0"
20586         $LFS mkdir -i 1 $DIR/$tdir/d0/d1 ||
20587                 error "failed to mkdir $DIR/$tdir/d0/d1 on MDT1"
20588
20589         umount_client $MOUNT || error "umount failed"
20590         #define OBD_FAIL_TGT_DELAY_CONDITIONAL   0x713
20591         do_facet mds2 lctl set_param fail_loc=0x713 fail_val=1
20592         mount_client $MOUNT || error "failed to mount client"
20593
20594         echo "stat $DIR/$tdir/d0/d1, should not fail/ASSERT"
20595         stat $DIR/$tdir/d0/d1 || error "fail to stat $DIR/$tdir/d0/d1"
20596 }
20597 run_test 240 "race between ldlm enqueue and the connection RPC (no ASSERT)"
20598
20599 test_241_bio() {
20600         local count=$1
20601         local bsize=$2
20602
20603         for LOOP in $(seq $count); do
20604                 dd if=$DIR/$tfile of=/dev/null bs=$bsize count=1 2>/dev/null
20605                 cancel_lru_locks $OSC || true
20606         done
20607 }
20608
20609 test_241_dio() {
20610         local count=$1
20611         local bsize=$2
20612
20613         for LOOP in $(seq $1); do
20614                 dd if=$DIR/$tfile of=/dev/null bs=$bsize count=1 iflag=direct \
20615                         2>/dev/null
20616         done
20617 }
20618
20619 test_241a() { # was test_241
20620         local bsize=$PAGE_SIZE
20621
20622         (( bsize < 40960 )) && bsize=40960
20623         dd if=/dev/zero of=$DIR/$tfile count=1 bs=$bsize
20624         ls -la $DIR/$tfile
20625         cancel_lru_locks $OSC
20626         test_241_bio 1000 $bsize &
20627         PID=$!
20628         test_241_dio 1000 $bsize
20629         wait $PID
20630 }
20631 run_test 241a "bio vs dio"
20632
20633 test_241b() {
20634         local bsize=$PAGE_SIZE
20635
20636         (( bsize < 40960 )) && bsize=40960
20637         dd if=/dev/zero of=$DIR/$tfile count=1 bs=$bsize
20638         ls -la $DIR/$tfile
20639         test_241_dio 1000 $bsize &
20640         PID=$!
20641         test_241_dio 1000 $bsize
20642         wait $PID
20643 }
20644 run_test 241b "dio vs dio"
20645
20646 test_242() {
20647         remote_mds_nodsh && skip "remote MDS with nodsh"
20648
20649         mkdir_on_mdt0 $DIR/$tdir
20650         touch $DIR/$tdir/$tfile
20651
20652         #define OBD_FAIL_MDS_READPAGE_PACK      0x105
20653         do_facet mds1 lctl set_param fail_loc=0x105
20654         /bin/ls $DIR/$tdir && error "ls $DIR/$tdir should fail"
20655
20656         do_facet mds1 lctl set_param fail_loc=0
20657         /bin/ls $DIR/$tdir || error "ls $DIR/$tdir failed"
20658 }
20659 run_test 242 "mdt_readpage failure should not cause directory unreadable"
20660
20661 test_243()
20662 {
20663         test_mkdir $DIR/$tdir
20664         group_lock_test -d $DIR/$tdir || error "A group lock test failed"
20665 }
20666 run_test 243 "various group lock tests"
20667
20668 test_244a()
20669 {
20670         test_mkdir $DIR/$tdir
20671         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=35
20672         sendfile_grouplock $DIR/$tdir/$tfile || \
20673                 error "sendfile+grouplock failed"
20674         rm -rf $DIR/$tdir
20675 }
20676 run_test 244a "sendfile with group lock tests"
20677
20678 test_244b()
20679 {
20680         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
20681
20682         local threads=50
20683         local size=$((1024*1024))
20684
20685         test_mkdir $DIR/$tdir
20686         for i in $(seq 1 $threads); do
20687                 local file=$DIR/$tdir/file_$((i / 10))
20688                 $MULTIOP $file OG1234w$size_$((i % 3))w$size_$((i % 4))g1234c &
20689                 local pids[$i]=$!
20690         done
20691         for i in $(seq 1 $threads); do
20692                 wait ${pids[$i]}
20693         done
20694 }
20695 run_test 244b "multi-threaded write with group lock"
20696
20697 test_245() {
20698         local flagname="multi_mod_rpcs"
20699         local connect_data_name="max_mod_rpcs"
20700         local out
20701
20702         # check if multiple modify RPCs flag is set
20703         out=$($LCTL get_param mdc.$FSNAME-MDT0000-*.import |
20704                 grep "connect_flags:")
20705         echo "$out"
20706
20707         echo "$out" | grep -qw $flagname
20708         if [ $? -ne 0 ]; then
20709                 echo "connect flag $flagname is not set"
20710                 return
20711         fi
20712
20713         # check if multiple modify RPCs data is set
20714         out=$($LCTL get_param mdc.$FSNAME-MDT0000-*.import)
20715         echo "$out"
20716
20717         echo "$out" | grep -qw $connect_data_name ||
20718                 error "import should have connect data $connect_data_name"
20719 }
20720 run_test 245 "check mdc connection flag/data: multiple modify RPCs"
20721
20722 cleanup_247() {
20723         local submount=$1
20724
20725         trap 0
20726         umount_client $submount
20727         rmdir $submount
20728 }
20729
20730 test_247a() {
20731         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
20732                 grep -q subtree ||
20733                 skip_env "Fileset feature is not supported"
20734
20735         local submount=${MOUNT}_$tdir
20736
20737         mkdir $MOUNT/$tdir
20738         mkdir -p $submount || error "mkdir $submount failed"
20739         FILESET="$FILESET/$tdir" mount_client $submount ||
20740                 error "mount $submount failed"
20741         trap "cleanup_247 $submount" EXIT
20742         echo foo > $submount/$tfile || error "write $submount/$tfile failed"
20743         [ $(cat $MOUNT/$tdir/$tfile) = "foo" ] ||
20744                 error "read $MOUNT/$tdir/$tfile failed"
20745         cleanup_247 $submount
20746 }
20747 run_test 247a "mount subdir as fileset"
20748
20749 test_247b() {
20750         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
20751                 skip_env "Fileset feature is not supported"
20752
20753         local submount=${MOUNT}_$tdir
20754
20755         rm -rf $MOUNT/$tdir
20756         mkdir -p $submount || error "mkdir $submount failed"
20757         SKIP_FILESET=1
20758         FILESET="$FILESET/$tdir" mount_client $submount &&
20759                 error "mount $submount should fail"
20760         rmdir $submount
20761 }
20762 run_test 247b "mount subdir that dose not exist"
20763
20764 test_247c() {
20765         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
20766                 skip_env "Fileset feature is not supported"
20767
20768         local submount=${MOUNT}_$tdir
20769
20770         mkdir -p $MOUNT/$tdir/dir1
20771         mkdir -p $submount || error "mkdir $submount failed"
20772         trap "cleanup_247 $submount" EXIT
20773         FILESET="$FILESET/$tdir" mount_client $submount ||
20774                 error "mount $submount failed"
20775         local fid=$($LFS path2fid $MOUNT/)
20776         $LFS fid2path $submount $fid && error "fid2path should fail"
20777         cleanup_247 $submount
20778 }
20779 run_test 247c "running fid2path outside subdirectory root"
20780
20781 test_247d() {
20782         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
20783                 skip "Fileset feature is not supported"
20784
20785         local submount=${MOUNT}_$tdir
20786
20787         mkdir -p $MOUNT/$tdir/dir1
20788         mkdir -p $submount || error "mkdir $submount failed"
20789         FILESET="$FILESET/$tdir" mount_client $submount ||
20790                 error "mount $submount failed"
20791         trap "cleanup_247 $submount" EXIT
20792
20793         local td=$submount/dir1
20794         local fid=$($LFS path2fid $td)
20795         [ -z "$fid" ] && error "path2fid unable to get $td FID"
20796
20797         # check that we get the same pathname back
20798         local rootpath
20799         local found
20800         for rootpath in "$submount" "$submount///" "$submount/dir1"; do
20801                 echo "$rootpath $fid"
20802                 found=$($LFS fid2path $rootpath "$fid")
20803                 [ -n "found" ] || error "fid2path should succeed"
20804                 [ "$found" == "$td" ] || error "fid2path $found != $td"
20805         done
20806         # check wrong root path format
20807         rootpath=$submount"_wrong"
20808         found=$($LFS fid2path $rootpath "$fid")
20809         [ -z "$found" ] || error "fid2path should fail ($rootpath != $submount)"
20810
20811         cleanup_247 $submount
20812 }
20813 run_test 247d "running fid2path inside subdirectory root"
20814
20815 # LU-8037
20816 test_247e() {
20817         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
20818                 grep -q subtree ||
20819                 skip "Fileset feature is not supported"
20820
20821         local submount=${MOUNT}_$tdir
20822
20823         mkdir $MOUNT/$tdir
20824         mkdir -p $submount || error "mkdir $submount failed"
20825         FILESET="$FILESET/.." mount_client $submount &&
20826                 error "mount $submount should fail"
20827         rmdir $submount
20828 }
20829 run_test 247e "mount .. as fileset"
20830
20831 test_247f() {
20832         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20833         [ $MDS1_VERSION -lt $(version_code 2.13.52) ] &&
20834                 skip "Need at least version 2.13.52"
20835         [ $CLIENT_VERSION -lt $(version_code 2.14.50) ] &&
20836                 skip "Need at least version 2.14.50"
20837         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
20838                 grep -q subtree ||
20839                 skip "Fileset feature is not supported"
20840
20841         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
20842         $LFS mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir/remote ||
20843                 error "mkdir remote failed"
20844         $LFS mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir/remote/subdir ||
20845                 error "mkdir remote/subdir failed"
20846         $LFS mkdir -i 0 -c $MDSCOUNT $DIR/$tdir/striped ||
20847                 error "mkdir striped failed"
20848         mkdir $DIR/$tdir/striped/subdir || error "mkdir striped/subdir failed"
20849
20850         local submount=${MOUNT}_$tdir
20851
20852         mkdir -p $submount || error "mkdir $submount failed"
20853         stack_trap "rmdir $submount"
20854
20855         local dir
20856         local stat
20857         local fileset=$FILESET
20858         local mdts=$(comma_list $(mdts_nodes))
20859
20860         stat=$(do_facet mds1 $LCTL get_param -n \
20861                 mdt.*MDT0000.enable_remote_subdir_mount)
20862         stack_trap "do_nodes $mdts $LCTL set_param \
20863                 mdt.*.enable_remote_subdir_mount=$stat"
20864
20865         do_nodes $mdts "$LCTL set_param mdt.*.enable_remote_subdir_mount=0"
20866         stack_trap "umount_client $submount"
20867         FILESET="$fileset/$tdir/remote" mount_client $submount &&
20868                 error "mount remote dir $dir should fail"
20869
20870         for dir in $tdir/remote/subdir $tdir/striped $tdir/striped/subdir \
20871                 $tdir/striped/. ; do
20872                 FILESET="$fileset/$dir" mount_client $submount ||
20873                         error "mount $dir failed"
20874                 umount_client $submount
20875         done
20876
20877         do_nodes $mdts "$LCTL set_param mdt.*.enable_remote_subdir_mount=1"
20878         FILESET="$fileset/$tdir/remote" mount_client $submount ||
20879                 error "mount $tdir/remote failed"
20880 }
20881 run_test 247f "mount striped or remote directory as fileset"
20882
20883 test_247g() {
20884         [ $MDSCOUNT -lt 4 ] && skip_env "needs >= 4 MDTs"
20885         [ $CLIENT_VERSION -lt $(version_code 2.14.50) ] &&
20886                 skip "Need at least version 2.14.50"
20887
20888         $LFS mkdir -i 0 -c 4 -H fnv_1a_64 $DIR/$tdir ||
20889                 error "mkdir $tdir failed"
20890         touch $DIR/$tdir/$tfile || error "touch $tfile failed"
20891
20892         local submount=${MOUNT}_$tdir
20893
20894         mkdir -p $submount || error "mkdir $submount failed"
20895         stack_trap "rmdir $submount"
20896
20897         FILESET="$fileset/$tdir" mount_client $submount ||
20898                 error "mount $dir failed"
20899         stack_trap "umount $submount"
20900
20901         local mdts=$(comma_list $(mdts_nodes))
20902
20903         local nrpcs
20904
20905         stat $submount > /dev/null
20906         cancel_lru_locks $MDC
20907         stat $submount > /dev/null
20908         stat $submount/$tfile > /dev/null
20909         do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear > /dev/null"
20910         stat $submount/$tfile > /dev/null
20911         nrpcs=$(do_nodes $mdts "lctl get_param -n mdt.*.md_stats" |
20912                 awk '/getattr/ {sum += $2} END {print sum}')
20913
20914         [ -z "$nrpcs" ] || error "$nrpcs extra getattr sent"
20915 }
20916 run_test 247g "mount striped directory as fileset caches ROOT lookup lock"
20917
20918 test_248a() {
20919         local fast_read_sav=$($LCTL get_param -n llite.*.fast_read 2>/dev/null)
20920         [ -z "$fast_read_sav" ] && skip "no fast read support"
20921
20922         # create a large file for fast read verification
20923         dd if=/dev/zero of=$DIR/$tfile bs=1M count=128 > /dev/null 2>&1
20924
20925         # make sure the file is created correctly
20926         $CHECKSTAT -s $((128*1024*1024)) $DIR/$tfile ||
20927                 { rm -f $DIR/$tfile; skip "file creation error"; }
20928
20929         echo "Test 1: verify that fast read is 4 times faster on cache read"
20930
20931         # small read with fast read enabled
20932         $LCTL set_param -n llite.*.fast_read=1
20933         local t_fast=$(dd if=$DIR/$tfile of=/dev/null bs=4k 2>&1 |
20934                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
20935                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
20936         # small read with fast read disabled
20937         $LCTL set_param -n llite.*.fast_read=0
20938         local t_slow=$(dd if=$DIR/$tfile of=/dev/null bs=4k 2>&1 |
20939                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
20940                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
20941
20942         # verify that fast read is 4 times faster for cache read
20943         [ $(bc <<< "4 * $t_fast < $t_slow") -eq 1 ] ||
20944                 error_not_in_vm "fast read was not 4 times faster: " \
20945                            "$t_fast vs $t_slow"
20946
20947         echo "Test 2: verify the performance between big and small read"
20948         $LCTL set_param -n llite.*.fast_read=1
20949
20950         # 1k non-cache read
20951         cancel_lru_locks osc
20952         local t_1k=$(dd if=$DIR/$tfile of=/dev/null bs=1k 2>&1 |
20953                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
20954                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
20955
20956         # 1M non-cache read
20957         cancel_lru_locks osc
20958         local t_1m=$(dd if=$DIR/$tfile of=/dev/null bs=1k 2>&1 |
20959                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
20960                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
20961
20962         # verify that big IO is not 4 times faster than small IO
20963         [ $(bc <<< "4 * $t_1k >= $t_1m") -eq 1 ] ||
20964                 error_not_in_vm "bigger IO is way too fast: $t_1k vs $t_1m"
20965
20966         $LCTL set_param -n llite.*.fast_read=$fast_read_sav
20967         rm -f $DIR/$tfile
20968 }
20969 run_test 248a "fast read verification"
20970
20971 test_248b() {
20972         # Default short_io_bytes=16384, try both smaller and larger sizes.
20973         # Lustre O_DIRECT read and write needs to be a multiple of PAGE_SIZE.
20974         # 6017024 = 2^12*13*113 = 47008*128 = 11752*512 = 4096*1469 = 53248*113
20975         echo "bs=53248 count=113 normal buffered write"
20976         dd if=/dev/urandom of=$TMP/$tfile.0 bs=53248 count=113 ||
20977                 error "dd of initial data file failed"
20978         stack_trap "rm -f $DIR/$tfile.[0-3] $TMP/$tfile.[0-3]" EXIT
20979
20980         echo "bs=47008 count=128 oflag=dsync normal write $tfile.0"
20981         dd if=$TMP/$tfile.0 of=$DIR/$tfile.0 bs=47008 count=128 oflag=dsync ||
20982                 error "dd with sync normal writes failed"
20983         cmp $TMP/$tfile.0 $DIR/$tfile.0 || error "compare $DIR/$tfile.0 failed"
20984
20985         echo "bs=11752 count=512 oflag=dsync small write $tfile.1"
20986         dd if=$TMP/$tfile.0 of=$DIR/$tfile.1 bs=11752 count=512 oflag=dsync ||
20987                 error "dd with sync small writes failed"
20988         cmp $TMP/$tfile.0 $DIR/$tfile.1 || error "compare $DIR/$tfile.1 failed"
20989
20990         cancel_lru_locks osc
20991
20992         # calculate the small O_DIRECT size and count for the client PAGE_SIZE
20993         local num=$((13 * 113 / (PAGE_SIZE / 4096)))
20994         echo "bs=$PAGE_SIZE count=$num iflag=direct small read $tfile.1"
20995         dd if=$DIR/$tfile.1 of=$TMP/$tfile.1 bs=$PAGE_SIZE count=$num \
20996                 iflag=direct || error "dd with O_DIRECT small read failed"
20997         # adjust bytes checked to handle larger PAGE_SIZE for ARM/PPC
20998         cmp --bytes=$((PAGE_SIZE * num)) $TMP/$tfile.0 $TMP/$tfile.1 ||
20999                 error "compare $TMP/$tfile.1 failed"
21000
21001         local save=$($LCTL get_param -n osc.*OST000*.short_io_bytes | head -n 1)
21002         stack_trap "$LCTL set_param osc.$FSNAME-*.short_io_bytes=$save" EXIT
21003
21004         # just to see what the maximum tunable value is, and test parsing
21005         echo "test invalid parameter 2MB"
21006         $LCTL set_param osc.$FSNAME-OST0000*.short_io_bytes=2M &&
21007                 error "too-large short_io_bytes allowed"
21008         echo "test maximum parameter 512KB"
21009         # if we can set a larger short_io_bytes, run test regardless of version
21010         if ! $LCTL set_param osc.$FSNAME-OST0000*.short_io_bytes=512K; then
21011                 # older clients may not allow setting it this large, that's OK
21012                 [ $CLIENT_VERSION -ge $(version_code 2.13.50) ] ||
21013                         skip "Need at least client version 2.13.50"
21014                 error "medium short_io_bytes failed"
21015         fi
21016         $LCTL get_param osc.$FSNAME-OST0000*.short_io_bytes
21017         size=$($LCTL get_param -n osc.$FSNAME-OST0000*.short_io_bytes)
21018
21019         echo "test large parameter 64KB"
21020         $LCTL set_param osc.$FSNAME-*.short_io_bytes=65536
21021         $LCTL get_param osc.$FSNAME-OST0000*.short_io_bytes
21022
21023         echo "bs=47008 count=128 oflag=dsync large write $tfile.2"
21024         dd if=$TMP/$tfile.0 of=$DIR/$tfile.2 bs=47008 count=128 oflag=dsync ||
21025                 error "dd with sync large writes failed"
21026         cmp $TMP/$tfile.0 $DIR/$tfile.2 || error "compare $DIR/$tfile.2 failed"
21027
21028         # calculate the large O_DIRECT size and count for the client PAGE_SIZE
21029         local size=$(((4096 * 13 + PAGE_SIZE - 1) / PAGE_SIZE * PAGE_SIZE))
21030         num=$((113 * 4096 / PAGE_SIZE))
21031         echo "bs=$size count=$num oflag=direct large write $tfile.3"
21032         dd if=$TMP/$tfile.0 of=$DIR/$tfile.3 bs=$size count=$num oflag=direct ||
21033                 error "dd with O_DIRECT large writes failed"
21034         cmp --bytes=$((size * num)) $TMP/$tfile.0 $DIR/$tfile.3 ||
21035                 error "compare $DIR/$tfile.3 failed"
21036
21037         cancel_lru_locks osc
21038
21039         echo "bs=$size count=$num iflag=direct large read $tfile.2"
21040         dd if=$DIR/$tfile.2 of=$TMP/$tfile.2 bs=$size count=$num iflag=direct ||
21041                 error "dd with O_DIRECT large read failed"
21042         cmp --bytes=$((size * num)) $TMP/$tfile.0 $TMP/$tfile.2 ||
21043                 error "compare $TMP/$tfile.2 failed"
21044
21045         echo "bs=$size count=$num iflag=direct large read $tfile.3"
21046         dd if=$DIR/$tfile.3 of=$TMP/$tfile.3 bs=$size count=$num iflag=direct ||
21047                 error "dd with O_DIRECT large read failed"
21048         cmp --bytes=$((size * num)) $TMP/$tfile.0 $TMP/$tfile.3 ||
21049                 error "compare $TMP/$tfile.3 failed"
21050 }
21051 run_test 248b "test short_io read and write for both small and large sizes"
21052
21053 test_249() { # LU-7890
21054         [ $MDS1_VERSION -lt $(version_code 2.8.53) ] &&
21055                 skip "Need at least version 2.8.54"
21056
21057         rm -f $DIR/$tfile
21058         $LFS setstripe -c 1 $DIR/$tfile
21059         # Offset 2T == 4k * 512M
21060         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 seek=512M ||
21061                 error "dd to 2T offset failed"
21062 }
21063 run_test 249 "Write above 2T file size"
21064
21065 test_250() {
21066         [ "$(facet_fstype ost$(($($LFS getstripe -i $DIR/$tfile) + 1)))" = "zfs" ] \
21067          && skip "no 16TB file size limit on ZFS"
21068
21069         $LFS setstripe -c 1 $DIR/$tfile
21070         # ldiskfs extent file size limit is (16TB - 4KB - 1) bytes
21071         local size=$((16 * 1024 * 1024 * 1024 * 1024 - 4096 - 1))
21072         $TRUNCATE $DIR/$tfile $size || error "truncate $tfile to $size failed"
21073         dd if=/dev/zero of=$DIR/$tfile bs=10 count=1 oflag=append \
21074                 conv=notrunc,fsync && error "append succeeded"
21075         return 0
21076 }
21077 run_test 250 "Write above 16T limit"
21078
21079 test_251() {
21080         $LFS setstripe -c -1 -S 1048576 $DIR/$tfile
21081
21082         #define OBD_FAIL_LLITE_LOST_LAYOUT 0x1407
21083         #Skip once - writing the first stripe will succeed
21084         $LCTL set_param fail_loc=0xa0001407 fail_val=1
21085         $MULTIOP $DIR/$tfile o:O_RDWR:w2097152c 2>&1 | grep -q "short write" &&
21086                 error "short write happened"
21087
21088         $LCTL set_param fail_loc=0xa0001407 fail_val=1
21089         $MULTIOP $DIR/$tfile or2097152c 2>&1 | grep -q "short read" &&
21090                 error "short read happened"
21091
21092         rm -f $DIR/$tfile
21093 }
21094 run_test 251 "Handling short read and write correctly"
21095
21096 test_252() {
21097         remote_mds_nodsh && skip "remote MDS with nodsh"
21098         remote_ost_nodsh && skip "remote OST with nodsh"
21099         if [ "$ost1_FSTYPE" != ldiskfs ] || [ "$mds1_FSTYPE" != ldiskfs ]; then
21100                 skip_env "ldiskfs only test"
21101         fi
21102
21103         local tgt
21104         local dev
21105         local out
21106         local uuid
21107         local num
21108         local gen
21109
21110         # check lr_reader on OST0000
21111         tgt=ost1
21112         dev=$(facet_device $tgt)
21113         out=$(do_facet $tgt $LR_READER $dev)
21114         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
21115         echo "$out"
21116         uuid=$(echo "$out" | grep -i uuid | awk '{ print $2 }')
21117         [ "$uuid" == "$(ostuuid_from_index 0)" ] ||
21118                 error "Invalid uuid returned by $LR_READER on target $tgt"
21119         echo -e "uuid returned by $LR_READER is '$uuid'\n"
21120
21121         # check lr_reader -c on MDT0000
21122         tgt=mds1
21123         dev=$(facet_device $tgt)
21124         if ! do_facet $tgt $LR_READER -h | grep -q OPTIONS; then
21125                 skip "$LR_READER does not support additional options"
21126         fi
21127         out=$(do_facet $tgt $LR_READER -c $dev)
21128         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
21129         echo "$out"
21130         num=$(echo "$out" | grep -c "mdtlov")
21131         [ "$num" -eq $((MDSCOUNT - 1)) ] ||
21132                 error "Invalid number of mdtlov clients returned by $LR_READER"
21133         echo -e "Number of mdtlov clients returned by $LR_READER is '$num'\n"
21134
21135         # check lr_reader -cr on MDT0000
21136         out=$(do_facet $tgt $LR_READER -cr $dev)
21137         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
21138         echo "$out"
21139         echo "$out" | grep -q "^reply_data:$" ||
21140                 error "$LR_READER should have returned 'reply_data' section"
21141         num=$(echo "$out" | grep -c "client_generation")
21142         echo -e "Number of reply data returned by $LR_READER is '$num'\n"
21143 }
21144 run_test 252 "check lr_reader tool"
21145
21146 test_253() {
21147         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21148         remote_mds_nodsh && skip "remote MDS with nodsh"
21149         remote_mgs_nodsh && skip "remote MGS with nodsh"
21150
21151         local ostidx=0
21152         local rc=0
21153         local ost_name=$(ostname_from_index $ostidx)
21154
21155         # on the mdt's osc
21156         local mdtosc_proc1=$(get_mdtosc_proc_path $SINGLEMDS $ost_name)
21157         do_facet $SINGLEMDS $LCTL get_param -n \
21158                 osp.$mdtosc_proc1.reserved_mb_high ||
21159                 skip  "remote MDS does not support reserved_mb_high"
21160
21161         rm -rf $DIR/$tdir
21162         wait_mds_ost_sync
21163         wait_delete_completed
21164         mkdir $DIR/$tdir
21165
21166         pool_add $TESTNAME || error "Pool creation failed"
21167         pool_add_targets $TESTNAME 0 || error "Pool add targets failed"
21168
21169         $LFS setstripe $DIR/$tdir -i $ostidx -c 1 -p $FSNAME.$TESTNAME ||
21170                 error "Setstripe failed"
21171
21172         dd if=/dev/zero of=$DIR/$tdir/$tfile.0 bs=1M count=10
21173
21174         local wms=$(ost_watermarks_set_enospc $tfile $ostidx |
21175                     grep "watermarks")
21176         stack_trap "ost_watermarks_clear_enospc $tfile $ostidx $wms" EXIT
21177
21178         local oa_status=$(do_facet $SINGLEMDS $LCTL get_param -n \
21179                         osp.$mdtosc_proc1.prealloc_status)
21180         echo "prealloc_status $oa_status"
21181
21182         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=1M count=1 &&
21183                 error "File creation should fail"
21184
21185         #object allocation was stopped, but we still able to append files
21186         dd if=/dev/zero of=$DIR/$tdir/$tfile.0 bs=1M seek=6 count=5 \
21187                 oflag=append || error "Append failed"
21188
21189         rm -f $DIR/$tdir/$tfile.0
21190
21191         # For this test, we want to delete the files we created to go out of
21192         # space but leave the watermark, so we remain nearly out of space
21193         ost_watermarks_enospc_delete_files $tfile $ostidx
21194
21195         wait_delete_completed
21196
21197         sleep_maxage
21198
21199         for i in $(seq 10 12); do
21200                 dd if=/dev/zero of=$DIR/$tdir/$tfile.$i bs=1M count=1 \
21201                         2>/dev/null || error "File creation failed after rm"
21202         done
21203
21204         oa_status=$(do_facet $SINGLEMDS $LCTL get_param -n \
21205                         osp.$mdtosc_proc1.prealloc_status)
21206         echo "prealloc_status $oa_status"
21207
21208         if (( oa_status != 0 )); then
21209                 error "Object allocation still disable after rm"
21210         fi
21211 }
21212 run_test 253 "Check object allocation limit"
21213
21214 test_254() {
21215         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21216         remote_mds_nodsh && skip "remote MDS with nodsh"
21217
21218         local mdt=$(facet_svc $SINGLEMDS)
21219
21220         do_facet $SINGLEMDS $LCTL get_param -n mdd.$mdt.changelog_size ||
21221                 skip "MDS does not support changelog_size"
21222
21223         local cl_user
21224
21225         changelog_register || error "changelog_register failed"
21226
21227         changelog_clear 0 || error "changelog_clear failed"
21228
21229         local size1=$(do_facet $SINGLEMDS \
21230                       $LCTL get_param -n mdd.$mdt.changelog_size)
21231         echo "Changelog size $size1"
21232
21233         rm -rf $DIR/$tdir
21234         $LFS mkdir -i 0 $DIR/$tdir
21235         # change something
21236         mkdir -p $DIR/$tdir/pics/2008/zachy
21237         touch $DIR/$tdir/pics/2008/zachy/timestamp
21238         cp /etc/hosts $DIR/$tdir/pics/2008/zachy/pic1.jpg
21239         mv $DIR/$tdir/pics/2008/zachy $DIR/$tdir/pics/zach
21240         ln $DIR/$tdir/pics/zach/pic1.jpg $DIR/$tdir/pics/2008/portland.jpg
21241         ln -s $DIR/$tdir/pics/2008/portland.jpg $DIR/$tdir/pics/desktop.jpg
21242         rm $DIR/$tdir/pics/desktop.jpg
21243
21244         local size2=$(do_facet $SINGLEMDS \
21245                       $LCTL get_param -n mdd.$mdt.changelog_size)
21246         echo "Changelog size after work $size2"
21247
21248         (( $size2 > $size1 )) ||
21249                 error "new Changelog size=$size2 less than old size=$size1"
21250 }
21251 run_test 254 "Check changelog size"
21252
21253 ladvise_no_type()
21254 {
21255         local type=$1
21256         local file=$2
21257
21258         lfs ladvise -a invalid $file 2>&1 | grep "Valid types" |
21259                 awk -F: '{print $2}' | grep $type > /dev/null
21260         if [ $? -ne 0 ]; then
21261                 return 0
21262         fi
21263         return 1
21264 }
21265
21266 ladvise_no_ioctl()
21267 {
21268         local file=$1
21269
21270         lfs ladvise -a willread $file > /dev/null 2>&1
21271         if [ $? -eq 0 ]; then
21272                 return 1
21273         fi
21274
21275         lfs ladvise -a willread $file 2>&1 |
21276                 grep "Inappropriate ioctl for device" > /dev/null
21277         if [ $? -eq 0 ]; then
21278                 return 0
21279         fi
21280         return 1
21281 }
21282
21283 percent() {
21284         bc <<<"scale=2; ($1 - $2) * 100 / $2"
21285 }
21286
21287 # run a random read IO workload
21288 # usage: random_read_iops <filename> <filesize> <iosize>
21289 random_read_iops() {
21290         local file=$1
21291         local fsize=$2
21292         local iosize=${3:-4096}
21293
21294         $READS -f $file -s $fsize -b $iosize -n $((fsize / iosize)) -t 60 |
21295                 sed -e '/^$/d' -e 's#.*s, ##' -e 's#MB/s##'
21296 }
21297
21298 drop_file_oss_cache() {
21299         local file="$1"
21300         local nodes="$2"
21301
21302         $LFS ladvise -a dontneed $file 2>/dev/null ||
21303                 do_nodes $nodes "echo 3 > /proc/sys/vm/drop_caches"
21304 }
21305
21306 ladvise_willread_performance()
21307 {
21308         local repeat=10
21309         local average_origin=0
21310         local average_cache=0
21311         local average_ladvise=0
21312
21313         for ((i = 1; i <= $repeat; i++)); do
21314                 echo "Iter $i/$repeat: reading without willread hint"
21315                 cancel_lru_locks osc
21316                 drop_file_oss_cache $DIR/$tfile $(comma_list $(osts_nodes))
21317                 local speed_origin=$(random_read_iops $DIR/$tfile $size)
21318                 echo "Iter $i/$repeat: uncached speed: $speed_origin"
21319                 average_origin=$(bc <<<"$average_origin + $speed_origin")
21320
21321                 cancel_lru_locks osc
21322                 local speed_cache=$(random_read_iops $DIR/$tfile $size)
21323                 echo "Iter $i/$repeat: OSS cache speed: $speed_cache"
21324                 average_cache=$(bc <<<"$average_cache + $speed_cache")
21325
21326                 cancel_lru_locks osc
21327                 drop_file_oss_cache $DIR/$tfile $(comma_list $(osts_nodes))
21328                 $LFS ladvise -a willread $DIR/$tfile || error "ladvise failed"
21329                 local speed_ladvise=$(random_read_iops $DIR/$tfile $size)
21330                 echo "Iter $i/$repeat: ladvise speed: $speed_ladvise"
21331                 average_ladvise=$(bc <<<"$average_ladvise + $speed_ladvise")
21332         done
21333         average_origin=$(bc <<<"scale=2; $average_origin / $repeat")
21334         average_cache=$(bc <<<"scale=2; $average_cache / $repeat")
21335         average_ladvise=$(bc <<<"scale=2; $average_ladvise / $repeat")
21336
21337         speedup_cache=$(percent $average_cache $average_origin)
21338         speedup_ladvise=$(percent $average_ladvise $average_origin)
21339
21340         echo "Average uncached read: $average_origin"
21341         echo "Average speedup with OSS cached read: " \
21342                 "$average_cache = +$speedup_cache%"
21343         echo "Average speedup with ladvise willread: " \
21344                 "$average_ladvise = +$speedup_ladvise%"
21345
21346         local lowest_speedup=20
21347         if [ ${average_cache%.*} -lt $lowest_speedup ]; then
21348                 echo "Speedup with OSS cached read less than $lowest_speedup%," \
21349                         "got $average_cache%. Skipping ladvise willread check."
21350                 return 0
21351         fi
21352
21353         # the test won't work on ZFS until it supports 'ladvise dontneed', but
21354         # it is still good to run until then to exercise 'ladvise willread'
21355         ! $LFS ladvise -a dontneed $DIR/$tfile &&
21356                 [ "$ost1_FSTYPE" = "zfs" ] &&
21357                 echo "osd-zfs does not support dontneed or drop_caches" &&
21358                 return 0
21359
21360         lowest_speedup=$(bc <<<"scale=2; $average_cache / 2")
21361         [[ ${average_ladvise%.*} > $lowest_speedup ]] ||
21362                 error_not_in_vm "Speedup with willread is less than " \
21363                         "$lowest_speedup%, got $average_ladvise%"
21364 }
21365
21366 test_255a() {
21367         [ $OST1_VERSION -lt $(version_code 2.8.54) ] &&
21368                 skip "lustre < 2.8.54 does not support ladvise "
21369         remote_ost_nodsh && skip "remote OST with nodsh"
21370
21371         stack_trap "rm -f $DIR/$tfile"
21372         lfs setstripe -c -1 -i 0 $DIR/$tfile || error "$tfile failed"
21373
21374         ladvise_no_type willread $DIR/$tfile &&
21375                 skip "willread ladvise is not supported"
21376
21377         ladvise_no_ioctl $DIR/$tfile &&
21378                 skip "ladvise ioctl is not supported"
21379
21380         local size_mb=100
21381         local size=$((size_mb * 1048576))
21382         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=$size_mb ||
21383                 error "dd to $DIR/$tfile failed"
21384
21385         lfs ladvise -a willread $DIR/$tfile ||
21386                 error "Ladvise failed with no range argument"
21387
21388         lfs ladvise -a willread -s 0 $DIR/$tfile ||
21389                 error "Ladvise failed with no -l or -e argument"
21390
21391         lfs ladvise -a willread -e 1 $DIR/$tfile ||
21392                 error "Ladvise failed with only -e argument"
21393
21394         lfs ladvise -a willread -l 1 $DIR/$tfile ||
21395                 error "Ladvise failed with only -l argument"
21396
21397         lfs ladvise -a willread -s 2 -e 1 $DIR/$tfile &&
21398                 error "End offset should not be smaller than start offset"
21399
21400         lfs ladvise -a willread -s 2 -e 2 $DIR/$tfile &&
21401                 error "End offset should not be equal to start offset"
21402
21403         lfs ladvise -a willread -s $size -l 1 $DIR/$tfile ||
21404                 error "Ladvise failed with overflowing -s argument"
21405
21406         lfs ladvise -a willread -s 1 -e $((size + 1)) $DIR/$tfile ||
21407                 error "Ladvise failed with overflowing -e argument"
21408
21409         lfs ladvise -a willread -s 1 -l $size $DIR/$tfile ||
21410                 error "Ladvise failed with overflowing -l argument"
21411
21412         lfs ladvise -a willread -l 1 -e 2 $DIR/$tfile &&
21413                 error "Ladvise succeeded with conflicting -l and -e arguments"
21414
21415         echo "Synchronous ladvise should wait"
21416         local delay=4
21417 #define OBD_FAIL_OST_LADVISE_PAUSE       0x237
21418         do_nodes $(comma_list $(osts_nodes)) \
21419                 $LCTL set_param fail_val=$delay fail_loc=0x237
21420
21421         local start_ts=$SECONDS
21422         lfs ladvise -a willread $DIR/$tfile ||
21423                 error "Ladvise failed with no range argument"
21424         local end_ts=$SECONDS
21425         local inteval_ts=$((end_ts - start_ts))
21426
21427         if [ $inteval_ts -lt $(($delay - 1)) ]; then
21428                 error "Synchronous advice didn't wait reply"
21429         fi
21430
21431         echo "Asynchronous ladvise shouldn't wait"
21432         local start_ts=$SECONDS
21433         lfs ladvise -a willread -b $DIR/$tfile ||
21434                 error "Ladvise failed with no range argument"
21435         local end_ts=$SECONDS
21436         local inteval_ts=$((end_ts - start_ts))
21437
21438         if [ $inteval_ts -gt $(($delay / 2)) ]; then
21439                 error "Asynchronous advice blocked"
21440         fi
21441
21442         do_nodes $(comma_list $(osts_nodes)) $LCTL set_param fail_loc=0
21443         ladvise_willread_performance
21444 }
21445 run_test 255a "check 'lfs ladvise -a willread'"
21446
21447 facet_meminfo() {
21448         local facet=$1
21449         local info=$2
21450
21451         do_facet $facet "cat /proc/meminfo | grep ^${info}:" | awk '{print $2}'
21452 }
21453
21454 test_255b() {
21455         [ $OST1_VERSION -lt $(version_code 2.8.54) ] &&
21456                 skip "lustre < 2.8.54 does not support ladvise "
21457         remote_ost_nodsh && skip "remote OST with nodsh"
21458
21459         stack_trap "rm -f $DIR/$tfile"
21460         lfs setstripe -c 1 -i 0 $DIR/$tfile
21461
21462         ladvise_no_type dontneed $DIR/$tfile &&
21463                 skip "dontneed ladvise is not supported"
21464
21465         ladvise_no_ioctl $DIR/$tfile &&
21466                 skip "ladvise ioctl is not supported"
21467
21468         ! $LFS ladvise -a dontneed $DIR/$tfile &&
21469                 [ "$ost1_FSTYPE" = "zfs" ] &&
21470                 skip "zfs-osd does not support 'ladvise dontneed'"
21471
21472         local size_mb=100
21473         local size=$((size_mb * 1048576))
21474         # In order to prevent disturbance of other processes, only check 3/4
21475         # of the memory usage
21476         local kibibytes=$((size_mb * 1024 * 3 / 4))
21477
21478         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=$size_mb ||
21479                 error "dd to $DIR/$tfile failed"
21480
21481         #force write to complete before dropping OST cache & checking memory
21482         sync
21483
21484         local total=$(facet_meminfo ost1 MemTotal)
21485         echo "Total memory: $total KiB"
21486
21487         do_facet ost1 "sync && echo 3 > /proc/sys/vm/drop_caches"
21488         local before_read=$(facet_meminfo ost1 Cached)
21489         echo "Cache used before read: $before_read KiB"
21490
21491         lfs ladvise -a willread $DIR/$tfile ||
21492                 error "Ladvise willread failed"
21493         local after_read=$(facet_meminfo ost1 Cached)
21494         echo "Cache used after read: $after_read KiB"
21495
21496         lfs ladvise -a dontneed $DIR/$tfile ||
21497                 error "Ladvise dontneed again failed"
21498         local no_read=$(facet_meminfo ost1 Cached)
21499         echo "Cache used after dontneed ladvise: $no_read KiB"
21500
21501         if [ $total -lt $((before_read + kibibytes)) ]; then
21502                 echo "Memory is too small, abort checking"
21503                 return 0
21504         fi
21505
21506         if [ $((before_read + kibibytes)) -gt $after_read ]; then
21507                 error "Ladvise willread should use more memory" \
21508                         "than $kibibytes KiB"
21509         fi
21510
21511         if [ $((no_read + kibibytes)) -gt $after_read ]; then
21512                 error "Ladvise dontneed should release more memory" \
21513                         "than $kibibytes KiB"
21514         fi
21515 }
21516 run_test 255b "check 'lfs ladvise -a dontneed'"
21517
21518 test_255c() {
21519         [ $OST1_VERSION -lt $(version_code 2.10.50) ] &&
21520                 skip "lustre < 2.10.50 does not support lockahead"
21521
21522         local ost1_imp=$(get_osc_import_name client ost1)
21523         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
21524                          cut -d'.' -f2)
21525         local count
21526         local new_count
21527         local difference
21528         local i
21529         local rc
21530
21531         test_mkdir -p $DIR/$tdir
21532         $LFS setstripe -i 0 -c 1 $DIR/$tdir
21533
21534         #test 10 returns only success/failure
21535         i=10
21536         lockahead_test -d $DIR/$tdir -t $i -f $tfile
21537         rc=$?
21538         if [ $rc -eq 255 ]; then
21539                 error "Ladvise test${i} failed, ${rc}"
21540         fi
21541
21542         #test 11 counts lock enqueue requests, all others count new locks
21543         i=11
21544         count=$(do_facet ost1 \
21545                 $LCTL get_param -n ost.OSS.ost.stats)
21546         count=$(echo "$count" | grep ldlm_extent_enqueue | awk '{ print $2 }')
21547
21548         lockahead_test -d $DIR/$tdir -t $i -f $tfile
21549         rc=$?
21550         if [ $rc -eq 255 ]; then
21551                 error "Ladvise test${i} failed, ${rc}"
21552         fi
21553
21554         new_count=$(do_facet ost1 \
21555                 $LCTL get_param -n ost.OSS.ost.stats)
21556         new_count=$(echo "$new_count" | grep ldlm_extent_enqueue | \
21557                    awk '{ print $2 }')
21558
21559         difference="$((new_count - count))"
21560         if [ $difference -ne $rc ]; then
21561                 error "Ladvise test${i}, bad enqueue count, returned " \
21562                       "${rc}, actual ${difference}"
21563         fi
21564
21565         for i in $(seq 12 21); do
21566                 # If we do not do this, we run the risk of having too many
21567                 # locks and starting lock cancellation while we are checking
21568                 # lock counts.
21569                 cancel_lru_locks osc
21570
21571                 count=$($LCTL get_param -n \
21572                        ldlm.namespaces.$imp_name.lock_unused_count)
21573
21574                 lockahead_test -d $DIR/$tdir -t $i -f $tfile
21575                 rc=$?
21576                 if [ $rc -eq 255 ]; then
21577                         error "Ladvise test ${i} failed, ${rc}"
21578                 fi
21579
21580                 new_count=$($LCTL get_param -n \
21581                        ldlm.namespaces.$imp_name.lock_unused_count)
21582                 difference="$((new_count - count))"
21583
21584                 # Test 15 output is divided by 100 to map down to valid return
21585                 if [ $i -eq 15 ]; then
21586                         rc="$((rc * 100))"
21587                 fi
21588
21589                 if [ $difference -ne $rc ]; then
21590                         error "Ladvise test ${i}, bad lock count, returned " \
21591                               "${rc}, actual ${difference}"
21592                 fi
21593         done
21594
21595         #test 22 returns only success/failure
21596         i=22
21597         lockahead_test -d $DIR/$tdir -t $i -f $tfile
21598         rc=$?
21599         if [ $rc -eq 255 ]; then
21600                 error "Ladvise test${i} failed, ${rc}"
21601         fi
21602 }
21603 run_test 255c "suite of ladvise lockahead tests"
21604
21605 test_256() {
21606         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21607         remote_mds_nodsh && skip "remote MDS with nodsh"
21608         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip "ldiskfs only test"
21609         changelog_users $SINGLEMDS | grep "^cl" &&
21610                 skip "active changelog user"
21611
21612         local cl_user
21613         local cat_sl
21614         local mdt_dev
21615
21616         mdt_dev=$(mdsdevname 1)
21617         echo $mdt_dev
21618
21619         changelog_register || error "changelog_register failed"
21620
21621         rm -rf $DIR/$tdir
21622         mkdir_on_mdt0 $DIR/$tdir
21623
21624         changelog_clear 0 || error "changelog_clear failed"
21625
21626         # change something
21627         touch $DIR/$tdir/{1..10}
21628
21629         # stop the MDT
21630         stop $SINGLEMDS || error "Fail to stop MDT"
21631
21632         # remount the MDT
21633
21634         start $SINGLEMDS $mdt_dev $MDS_MOUNT_OPTS || error "Fail to start MDT"
21635
21636         #after mount new plainllog is used
21637         touch $DIR/$tdir/{11..19}
21638         local tmpfile="$(mktemp --tmpdir -u $tfile.XXXXXX)"
21639         stack_trap "rm -f $tmpfile"
21640         cat_sl=$(do_facet $SINGLEMDS "sync; \
21641                  $DEBUGFS -c -R 'dump changelog_catalog $tmpfile' $mdt_dev; \
21642                  llog_reader $tmpfile | grep -c type=1064553b")
21643         do_facet $SINGLEMDS llog_reader $tmpfile
21644
21645         [ $cat_sl != 2 ] && error "Changelog catalog has $cat_sl != 2 slots"
21646
21647         changelog_clear 0 || error "changelog_clear failed"
21648
21649         cat_sl=$(do_facet $SINGLEMDS "sync; \
21650                  $DEBUGFS -c -R 'dump changelog_catalog $tmpfile' $mdt_dev; \
21651                  llog_reader $tmpfile | grep -c type=1064553b")
21652
21653         if (( cat_sl == 2 )); then
21654                 error "Empty plain llog was not deleted from changelog catalog"
21655         elif (( cat_sl != 1 )); then
21656                 error "Active plain llog shouldn't be deleted from catalog"
21657         fi
21658 }
21659 run_test 256 "Check llog delete for empty and not full state"
21660
21661 test_257() {
21662         remote_mds_nodsh && skip "remote MDS with nodsh"
21663         [[ $MDS1_VERSION -lt $(version_code 2.8.55) ]] &&
21664                 skip "Need MDS version at least 2.8.55"
21665
21666         test_mkdir $DIR/$tdir
21667
21668         setfattr -n trusted.name1 -v value1 $DIR/$tdir ||
21669                 error "setfattr -n trusted.name1=value1 $DIR/$tdir failed"
21670         stat $DIR/$tdir
21671
21672 #define OBD_FAIL_MDS_XATTR_REP                  0x161
21673         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
21674         local facet=mds$((mdtidx + 1))
21675         set_nodes_failloc $(facet_active_host $facet) 0x80000161
21676         getfattr -n trusted.name1 $DIR/$tdir 2> /dev/null
21677
21678         stop $facet || error "stop MDS failed"
21679         start $facet $(mdsdevname $((mdtidx + 1))) $MDS_MOUNT_OPTS ||
21680                 error "start MDS fail"
21681         wait_recovery_complete $facet
21682 }
21683 run_test 257 "xattr locks are not lost"
21684
21685 # Verify we take the i_mutex when security requires it
21686 test_258a() {
21687 #define OBD_FAIL_IMUTEX_SEC 0x141c
21688         $LCTL set_param fail_loc=0x141c
21689         touch $DIR/$tfile
21690         chmod u+s $DIR/$tfile
21691         chmod a+rwx $DIR/$tfile
21692         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 oflag=append
21693         RC=$?
21694         if [ $RC -ne 0 ]; then
21695                 error "error, failed to take i_mutex, rc=$?"
21696         fi
21697         rm -f $DIR/$tfile
21698 }
21699 run_test 258a "verify i_mutex security behavior when suid attributes is set"
21700
21701 # Verify we do NOT take the i_mutex in the normal case
21702 test_258b() {
21703 #define OBD_FAIL_IMUTEX_NOSEC 0x141d
21704         $LCTL set_param fail_loc=0x141d
21705         touch $DIR/$tfile
21706         chmod a+rwx $DIR
21707         chmod a+rw $DIR/$tfile
21708         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 oflag=append
21709         RC=$?
21710         if [ $RC -ne 0 ]; then
21711                 error "error, took i_mutex unnecessarily, rc=$?"
21712         fi
21713         rm -f $DIR/$tfile
21714
21715 }
21716 run_test 258b "verify i_mutex security behavior"
21717
21718 test_259() {
21719         local file=$DIR/$tfile
21720         local before
21721         local after
21722
21723         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip "ldiskfs only test"
21724
21725         stack_trap "rm -f $file" EXIT
21726
21727         wait_delete_completed
21728         before=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
21729         echo "before: $before"
21730
21731         $LFS setstripe -i 0 -c 1 $file
21732         dd if=/dev/zero of=$file bs=1M count=10 || error "couldn't write"
21733         sync_all_data
21734         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
21735         echo "after write: $after"
21736
21737 #define OBD_FAIL_OSD_FAIL_AT_TRUNCATE          0x2301
21738         do_facet ost1 $LCTL set_param fail_loc=0x2301
21739         $TRUNCATE $file 0
21740         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
21741         echo "after truncate: $after"
21742
21743         stop ost1
21744         do_facet ost1 $LCTL set_param fail_loc=0
21745         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
21746         sleep 2
21747         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
21748         echo "after restart: $after"
21749         [ $((after - before)) -ge $(fs_log_size ost1) ] &&
21750                 error "missing truncate?"
21751
21752         return 0
21753 }
21754 run_test 259 "crash at delayed truncate"
21755
21756 test_260() {
21757 #define OBD_FAIL_MDC_CLOSE               0x806
21758         $LCTL set_param fail_loc=0x80000806
21759         touch $DIR/$tfile
21760
21761 }
21762 run_test 260 "Check mdc_close fail"
21763
21764 ### Data-on-MDT sanity tests ###
21765 test_270a() {
21766         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
21767                 skip "Need MDS version at least 2.10.55 for DoM"
21768
21769         # create DoM file
21770         local dom=$DIR/$tdir/dom_file
21771         local tmp=$DIR/$tdir/tmp_file
21772
21773         mkdir_on_mdt0 $DIR/$tdir
21774
21775         # basic checks for DoM component creation
21776         $LFS setstripe -E 1024K -E 2048K -L mdt $dom 2>/dev/null &&
21777                 error "Can set MDT layout to non-first entry"
21778
21779         $LFS setstripe -E 1024K -L mdt -E 2048K -L mdt $dom 2>/dev/null &&
21780                 error "Can define multiple entries as MDT layout"
21781
21782         $LFS setstripe -E 1M -L mdt $dom || error "Can't create DoM layout"
21783
21784         [ $($LFS getstripe -L $dom) == "mdt" ] || error "bad pattern"
21785         [ $($LFS getstripe -c $dom) == 0 ] || error "bad stripe count"
21786         [ $($LFS getstripe -S $dom) == 1048576 ] || error "bad stripe size"
21787
21788         local mdtidx=$($LFS getstripe -m $dom)
21789         local mdtname=MDT$(printf %04x $mdtidx)
21790         local facet=mds$((mdtidx + 1))
21791         local space_check=1
21792
21793         # Skip free space checks with ZFS
21794         [ "$(facet_fstype $facet)" == "zfs" ] && space_check=0
21795
21796         # write
21797         sync
21798         local size_tmp=$((65536 * 3))
21799         local mdtfree1=$(do_facet $facet \
21800                          lctl get_param -n osd*.*$mdtname.kbytesfree)
21801
21802         dd if=/dev/urandom of=$tmp bs=1024 count=$((size_tmp / 1024))
21803         # check also direct IO along write
21804         # IO size must be a multiple of PAGE_SIZE on all platforms (ARM=64KB)
21805         dd if=$tmp of=$dom bs=65536 count=$((size_tmp / 65536)) oflag=direct
21806         sync
21807         cmp $tmp $dom || error "file data is different"
21808         [ $(stat -c%s $dom) == $size_tmp ] ||
21809                 error "bad size after write: $(stat -c%s $dom) != $size_tmp"
21810         if [ $space_check == 1 ]; then
21811                 local mdtfree2=$(do_facet $facet \
21812                                  lctl get_param -n osd*.*$mdtname.kbytesfree)
21813
21814                 # increase in usage from by $size_tmp
21815                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_tmp / 1024)) ] ||
21816                         error "MDT free space wrong after write: " \
21817                               "$mdtfree1 >= $mdtfree2 + $size_tmp/1024"
21818         fi
21819
21820         # truncate
21821         local size_dom=10000
21822
21823         $TRUNCATE $dom $size_dom
21824         [ $(stat -c%s $dom) == $size_dom ] ||
21825                 error "bad size after truncate: $(stat -c%s $dom) != $size_dom"
21826         if [ $space_check == 1 ]; then
21827                 mdtfree1=$(do_facet $facet \
21828                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
21829                 # decrease in usage from $size_tmp to new $size_dom
21830                 [ $(($mdtfree1 - $mdtfree2)) -ge \
21831                   $(((size_tmp - size_dom) / 1024)) ] ||
21832                         error "MDT free space is wrong after truncate: " \
21833                               "$mdtfree1 >= $mdtfree2 + ($size_tmp - $size_dom) / 1024"
21834         fi
21835
21836         # append
21837         cat $tmp >> $dom
21838         sync
21839         size_dom=$((size_dom + size_tmp))
21840         [ $(stat -c%s $dom) == $size_dom ] ||
21841                 error "bad size after append: $(stat -c%s $dom) != $size_dom"
21842         if [ $space_check == 1 ]; then
21843                 mdtfree2=$(do_facet $facet \
21844                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
21845                 # increase in usage by $size_tmp from previous
21846                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_tmp / 1024)) ] ||
21847                         error "MDT free space is wrong after append: " \
21848                               "$mdtfree1 >= $mdtfree2 + $size_tmp/1024"
21849         fi
21850
21851         # delete
21852         rm $dom
21853         if [ $space_check == 1 ]; then
21854                 mdtfree1=$(do_facet $facet \
21855                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
21856                 # decrease in usage by $size_dom from previous
21857                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_dom / 1024)) ] ||
21858                         error "MDT free space is wrong after removal: " \
21859                               "$mdtfree1 >= $mdtfree2 + $size_dom/1024"
21860         fi
21861
21862         # combined striping
21863         $LFS setstripe -E 1024K -L mdt -E EOF $dom ||
21864                 error "Can't create DoM + OST striping"
21865
21866         size_tmp=2031616 # must be a multiple of PAGE_SIZE=65536 on ARM
21867         dd if=/dev/urandom of=$tmp bs=1024 count=$((size_tmp / 1024))
21868         # check also direct IO along write
21869         dd if=$tmp of=$dom bs=65536 count=$((size_tmp / 65536)) oflag=direct
21870         sync
21871         cmp $tmp $dom || error "file data is different"
21872         [ $(stat -c%s $dom) == $size_tmp ] ||
21873                 error "bad size after write: $(stat -c%s $dom) != $size_tmp"
21874         rm $dom $tmp
21875
21876         return 0
21877 }
21878 run_test 270a "DoM: basic functionality tests"
21879
21880 test_270b() {
21881         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
21882                 skip "Need MDS version at least 2.10.55"
21883
21884         local dom=$DIR/$tdir/dom_file
21885         local max_size=1048576
21886
21887         mkdir -p $DIR/$tdir
21888         $LFS setstripe -E $max_size -L mdt $dom
21889
21890         # truncate over the limit
21891         $TRUNCATE $dom $(($max_size + 1)) &&
21892                 error "successful truncate over the maximum size"
21893         # write over the limit
21894         dd if=/dev/zero of=$dom bs=$max_size seek=1 count=1 &&
21895                 error "successful write over the maximum size"
21896         # append over the limit
21897         dd if=/dev/zero of=$dom bs=$(($max_size - 3)) count=1
21898         echo "12345" >> $dom && error "successful append over the maximum size"
21899         rm $dom
21900
21901         return 0
21902 }
21903 run_test 270b "DoM: maximum size overflow checks for DoM-only file"
21904
21905 test_270c() {
21906         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
21907                 skip "Need MDS version at least 2.10.55"
21908
21909         mkdir -p $DIR/$tdir
21910         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
21911
21912         # check files inherit DoM EA
21913         touch $DIR/$tdir/first
21914         [ $($LFS getstripe -L $DIR/$tdir/first) == "mdt" ] ||
21915                 error "bad pattern"
21916         [ $($LFS getstripe -c $DIR/$tdir/first) == 0 ] ||
21917                 error "bad stripe count"
21918         [ $($LFS getstripe -S $DIR/$tdir/first) == 1048576 ] ||
21919                 error "bad stripe size"
21920
21921         # check directory inherits DoM EA and uses it as default
21922         mkdir $DIR/$tdir/subdir
21923         touch $DIR/$tdir/subdir/second
21924         [ $($LFS getstripe -L $DIR/$tdir/subdir/second) == "mdt" ] ||
21925                 error "bad pattern in sub-directory"
21926         [ $($LFS getstripe -c $DIR/$tdir/subdir/second) == 0 ] ||
21927                 error "bad stripe count in sub-directory"
21928         [ $($LFS getstripe -S $DIR/$tdir/subdir/second) == 1048576 ] ||
21929                 error "bad stripe size in sub-directory"
21930         return 0
21931 }
21932 run_test 270c "DoM: DoM EA inheritance tests"
21933
21934 test_270d() {
21935         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
21936                 skip "Need MDS version at least 2.10.55"
21937
21938         mkdir -p $DIR/$tdir
21939         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
21940
21941         # inherit default DoM striping
21942         mkdir $DIR/$tdir/subdir
21943         touch $DIR/$tdir/subdir/f1
21944
21945         # change default directory striping
21946         $LFS setstripe -c 1 $DIR/$tdir/subdir
21947         touch $DIR/$tdir/subdir/f2
21948         [ $($LFS getstripe -c $DIR/$tdir/subdir/f2) == 1 ] ||
21949                 error "wrong default striping in file 2"
21950         [ $($LFS getstripe -L $DIR/$tdir/subdir/f2) == "raid0" ] ||
21951                 error "bad pattern in file 2"
21952         return 0
21953 }
21954 run_test 270d "DoM: change striping from DoM to RAID0"
21955
21956 test_270e() {
21957         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
21958                 skip "Need MDS version at least 2.10.55"
21959
21960         mkdir -p $DIR/$tdir/dom
21961         mkdir -p $DIR/$tdir/norm
21962         DOMFILES=20
21963         NORMFILES=10
21964         $LFS setstripe -E 1M -L mdt $DIR/$tdir/dom
21965         $LFS setstripe -i 0 -S 2M $DIR/$tdir/norm
21966
21967         createmany -o $DIR/$tdir/dom/dom- $DOMFILES
21968         createmany -o $DIR/$tdir/norm/norm- $NORMFILES
21969
21970         # find DoM files by layout
21971         NUM=$($LFS find -L mdt -type f $DIR/$tdir 2>/dev/null | wc -l)
21972         [ $NUM -eq  $DOMFILES ] ||
21973                 error "lfs find -L: found $NUM, expected $DOMFILES"
21974         echo "Test 1: lfs find 20 DOM files by layout: OK"
21975
21976         # there should be 1 dir with default DOM striping
21977         NUM=$($LFS find -L mdt -type d $DIR/$tdir 2>/dev/null | wc -l)
21978         [ $NUM -eq  1 ] ||
21979                 error "lfs find -L: found $NUM, expected 1 dir"
21980         echo "Test 2: lfs find 1 DOM dir by layout: OK"
21981
21982         # find DoM files by stripe size
21983         NUM=$($LFS find -S -1200K -type f $DIR/$tdir 2>/dev/null | wc -l)
21984         [ $NUM -eq  $DOMFILES ] ||
21985                 error "lfs find -S: found $NUM, expected $DOMFILES"
21986         echo "Test 4: lfs find 20 DOM files by stripe size: OK"
21987
21988         # find files by stripe offset except DoM files
21989         NUM=$($LFS find -i 0 -type f $DIR/$tdir 2>/dev/null | wc -l)
21990         [ $NUM -eq  $NORMFILES ] ||
21991                 error "lfs find -i: found $NUM, expected $NORMFILES"
21992         echo "Test 5: lfs find no DOM files by stripe index: OK"
21993         return 0
21994 }
21995 run_test 270e "DoM: lfs find with DoM files test"
21996
21997 test_270f() {
21998         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
21999                 skip "Need MDS version at least 2.10.55"
22000
22001         local mdtname=${FSNAME}-MDT0000-mdtlov
22002         local dom=$DIR/$tdir/dom_file
22003         local dom_limit_saved=$(do_facet mds1 $LCTL get_param -n \
22004                                                 lod.$mdtname.dom_stripesize)
22005         local dom_limit=131072
22006
22007         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=$dom_limit
22008         local dom_current=$(do_facet mds1 $LCTL get_param -n \
22009                                                 lod.$mdtname.dom_stripesize)
22010         [ ${dom_limit} -eq ${dom_current} ] ||
22011                 error "Cannot change per-MDT DoM stripe limit to $dom_limit"
22012
22013         $LFS mkdir -i 0 -c 1 $DIR/$tdir
22014         $LFS setstripe -d $DIR/$tdir
22015         $LFS setstripe -E $dom_limit -L mdt $DIR/$tdir ||
22016                 error "Can't set directory default striping"
22017
22018         # exceed maximum stripe size
22019         $LFS setstripe -E $((dom_limit * 2)) -L mdt $dom ||
22020                 error "Can't create file with $((dom_limit * 2)) DoM stripe"
22021         [ $($LFS getstripe -S $dom) -eq $((dom_limit * 2)) ] &&
22022                 error "Able to create DoM component size more than LOD limit"
22023
22024         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=0
22025         dom_current=$(do_facet mds1 $LCTL get_param -n \
22026                                                 lod.$mdtname.dom_stripesize)
22027         [ 0 -eq ${dom_current} ] ||
22028                 error "Can't set zero DoM stripe limit"
22029         rm $dom
22030
22031         # attempt to create DoM file on server with disabled DoM should
22032         # remove DoM entry from layout and be succeed
22033         $LFS setstripe -E $dom_limit -L mdt -E -1 $dom ||
22034                 error "Can't create DoM file (DoM is disabled)"
22035         [ $($LFS getstripe -L $dom) == "mdt" ] &&
22036                 error "File has DoM component while DoM is disabled"
22037         rm $dom
22038
22039         # attempt to create DoM file with only DoM stripe should return error
22040         $LFS setstripe -E $dom_limit -L mdt $dom &&
22041                 error "Able to create DoM-only file while DoM is disabled"
22042
22043         # too low values to be aligned with smallest stripe size 64K
22044         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=30000
22045         dom_current=$(do_facet mds1 $LCTL get_param -n \
22046                                                 lod.$mdtname.dom_stripesize)
22047         [ 30000 -eq ${dom_current} ] &&
22048                 error "Can set too small DoM stripe limit"
22049
22050         # 64K is a minimal stripe size in Lustre, expect limit of that size
22051         [ 65536 -eq ${dom_current} ] ||
22052                 error "Limit is not set to 64K but ${dom_current}"
22053
22054         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=2147483648
22055         dom_current=$(do_facet mds1 $LCTL get_param -n \
22056                                                 lod.$mdtname.dom_stripesize)
22057         echo $dom_current
22058         [ 2147483648 -eq ${dom_current} ] &&
22059                 error "Can set too large DoM stripe limit"
22060
22061         do_facet mds1 $LCTL set_param -n \
22062                                 lod.$mdtname.dom_stripesize=$((dom_limit * 2))
22063         $LFS setstripe -E $((dom_limit * 2)) -L mdt $dom ||
22064                 error "Can't create DoM component size after limit change"
22065         do_facet mds1 $LCTL set_param -n \
22066                                 lod.$mdtname.dom_stripesize=$((dom_limit / 2))
22067         $LFS setstripe -E $dom_limit -L mdt ${dom}_big ||
22068                 error "Can't create DoM file after limit decrease"
22069         [ $($LFS getstripe -S ${dom}_big) -eq $((dom_limit / 2)) ] ||
22070                 error "Can create big DoM component after limit decrease"
22071         touch ${dom}_def ||
22072                 error "Can't create file with old default layout"
22073
22074         do_facet mds1 $LCTL set_param -n lod.*.dom_stripesize=$dom_limit_saved
22075         return 0
22076 }
22077 run_test 270f "DoM: maximum DoM stripe size checks"
22078
22079 test_270g() {
22080         [ $MDS1_VERSION -ge $(version_code 2.13.52) ] ||
22081                 skip "Need MDS version at least 2.13.52"
22082         local dom=$DIR/$tdir/$tfile
22083
22084         $LFS mkdir -i 0 -c 1 $DIR/$tdir
22085         local lodname=${FSNAME}-MDT0000-mdtlov
22086
22087         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
22088         save_lustre_params mds1 "lod.${lodname}.dom_stripesize_max_kb" > $save
22089         save_lustre_params mds1 "lod.${lodname}.dom_threshold_free_mb" >> $save
22090         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
22091
22092         local dom_limit=1024
22093         local dom_threshold="50%"
22094
22095         $LFS setstripe -d $DIR/$tdir
22096         $LFS setstripe -E ${dom_limit}K -L mdt $DIR/$tdir ||
22097                 error "Can't set directory default striping"
22098
22099         do_facet mds1 $LCTL set_param -n \
22100                                 lod.${lodname}.dom_stripesize_max_kb=$dom_limit
22101         # set 0 threshold and create DOM file to change tunable stripesize
22102         do_facet mds1 $LCTL set_param -n lod.${lodname}.dom_threshold_free_mb=0
22103         $LFS setstripe -E ${dom_limit}K -L mdt -E -1 $dom ||
22104                 error "Failed to create $dom file"
22105         # now tunable dom_cur_stripesize should reach maximum
22106         local dom_current=$(do_facet mds1 $LCTL get_param -n \
22107                                         lod.${lodname}.dom_stripesize_cur_kb)
22108         [[ $dom_current == $dom_limit ]] ||
22109                 error "Current DOM stripesize is not maximum"
22110         rm $dom
22111
22112         # set threshold for further tests
22113         do_facet mds1 $LCTL set_param -n \
22114                         lod.${lodname}.dom_threshold_free_mb=$dom_threshold
22115         echo "DOM threshold is $dom_threshold free space"
22116         local dom_def
22117         local dom_set
22118         # Spoof bfree to exceed threshold
22119         #define OBD_FAIL_MDS_STATFS_SPOOF   0x168
22120         do_facet mds1 $LCTL set_param -n fail_loc=0x0168
22121         for spfree in 40 20 0 15 30 55; do
22122                 do_facet mds1 $LCTL set_param -n fail_val=$spfree
22123                 $LFS setstripe -E ${dom_limit}K -L mdt -E -1 $dom ||
22124                         error "Failed to create $dom file"
22125                 dom_def=$(do_facet mds1 $LCTL get_param -n \
22126                                         lod.${lodname}.dom_stripesize_cur_kb)
22127                 echo "Free space: ${spfree}%, default DOM stripe: ${dom_def}K"
22128                 [[ $dom_def != $dom_current ]] ||
22129                         error "Default stripe size was not changed"
22130                 if [[ $spfree > 0 ]] ; then
22131                         dom_set=$($LFS getstripe -S $dom)
22132                         [[ $dom_set == $((dom_def * 1024)) ]] ||
22133                                 error "DOM component size is still old"
22134                 else
22135                         [[ $($LFS getstripe -L $dom) != "mdt" ]] ||
22136                                 error "DoM component is set with no free space"
22137                 fi
22138                 rm $dom
22139                 dom_current=$dom_def
22140         done
22141 }
22142 run_test 270g "DoM: default DoM stripe size depends on free space"
22143
22144 test_270h() {
22145         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
22146                 skip "Need MDS version at least 2.13.53"
22147
22148         local mdtname=${FSNAME}-MDT0000-mdtlov
22149         local dom=$DIR/$tdir/$tfile
22150         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
22151
22152         save_lustre_params mds1 "lod.*.dom_stripesize" > $save
22153         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
22154
22155         $LFS mkdir -i 0 -c 1 $DIR/$tdir
22156         $LFS setstripe -E 1M -c1  -E -1 -c2 ${dom}_1 ||
22157                 error "can't create OST file"
22158         # mirrored file with DOM entry in the second mirror
22159         $LFS mirror extend -N -E 1M -L mdt -E eof -c2 ${dom}_1 ||
22160                 error "can't create mirror with DoM component"
22161
22162         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=0
22163
22164         # DOM component in the middle and has other enries in the same mirror,
22165         # should succeed but lost DoM component
22166         $LFS setstripe --copy=${dom}_1 $dom ||
22167                 error "Can't create file from OST|DOM mirror layout"
22168         # check new file has no DoM layout after all
22169         [[ $($LFS getstripe -L $dom) != "mdt" ]] ||
22170                 error "File has DoM component while DoM is disabled"
22171 }
22172 run_test 270h "DoM: DoM stripe removal when disabled on server"
22173
22174 test_270i() {
22175         (( $MDS1_VERSION >= $(version_code 2.14.54) )) ||
22176                 skip "Need MDS version at least 2.14.54"
22177
22178         mkdir $DIR/$tdir
22179         $LFS setstripe -L mdt -S 128k -c -1 $DIR/$tdir &&
22180                 error "setstripe should fail" || true
22181 }
22182 run_test 270i "DoM: setting invalid DoM striping should fail"
22183
22184 test_271a() {
22185         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
22186                 skip "Need MDS version at least 2.10.55"
22187
22188         local dom=$DIR/$tdir/dom
22189
22190         mkdir -p $DIR/$tdir
22191
22192         $LFS setstripe -E 1024K -L mdt $dom
22193
22194         lctl set_param -n mdc.*.stats=clear
22195         dd if=/dev/zero of=$dom bs=4096 count=1 || return 1
22196         cat $dom > /dev/null
22197         local reads=$(lctl get_param -n mdc.*.stats | grep -c ost_read)
22198         [ $reads -eq 0 ] || error "Unexpected $reads READ RPCs"
22199         ls $dom
22200         rm -f $dom
22201 }
22202 run_test 271a "DoM: data is cached for read after write"
22203
22204 test_271b() {
22205         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
22206                 skip "Need MDS version at least 2.10.55"
22207
22208         local dom=$DIR/$tdir/dom
22209
22210         mkdir -p $DIR/$tdir
22211
22212         $LFS setstripe -E 1024K -L mdt -E EOF $dom
22213
22214         lctl set_param -n mdc.*.stats=clear
22215         dd if=/dev/zero of=$dom bs=4096 count=1 || return 1
22216         cancel_lru_locks mdc
22217         $CHECKSTAT -t file -s 4096 $dom || error "stat #1 fails"
22218         # second stat to check size is cached on client
22219         $CHECKSTAT -t file -s 4096 $dom || error "stat #2 fails"
22220         local gls=$(lctl get_param -n mdc.*.stats | grep -c ldlm_glimpse)
22221         [ $gls -eq 0 ] || error "Unexpected $gls glimpse RPCs"
22222         rm -f $dom
22223 }
22224 run_test 271b "DoM: no glimpse RPC for stat (DoM only file)"
22225
22226 test_271ba() {
22227         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
22228                 skip "Need MDS version at least 2.10.55"
22229
22230         local dom=$DIR/$tdir/dom
22231
22232         mkdir -p $DIR/$tdir
22233
22234         $LFS setstripe -E 1024K -L mdt -E EOF $dom
22235
22236         lctl set_param -n mdc.*.stats=clear
22237         lctl set_param -n osc.*.stats=clear
22238         dd if=/dev/zero of=$dom bs=2048K count=1 || return 1
22239         cancel_lru_locks mdc
22240         $CHECKSTAT -t file -s 2097152 $dom || error "stat"
22241         # second stat to check size is cached on client
22242         $CHECKSTAT -t file -s 2097152 $dom || error "stat"
22243         local gls=$(lctl get_param -n mdc.*.stats | grep -c ldlm_glimpse)
22244         [ $gls == 0 ] || error "Unexpected $gls glimpse RPCs"
22245         local gls=$(lctl get_param -n osc.*.stats | grep -c ldlm_glimpse)
22246         [ $gls == 0 ] || error "Unexpected $gls OSC glimpse RPCs"
22247         rm -f $dom
22248 }
22249 run_test 271ba "DoM: no glimpse RPC for stat (combined file)"
22250
22251
22252 get_mdc_stats() {
22253         local mdtidx=$1
22254         local param=$2
22255         local mdt=MDT$(printf %04x $mdtidx)
22256
22257         if [ -z $param ]; then
22258                 lctl get_param -n mdc.*$mdt*.stats
22259         else
22260                 lctl get_param -n mdc.*$mdt*.stats | awk "/$param/"'{print $2}'
22261         fi
22262 }
22263
22264 test_271c() {
22265         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
22266                 skip "Need MDS version at least 2.10.55"
22267
22268         local dom=$DIR/$tdir/dom
22269
22270         mkdir -p $DIR/$tdir
22271
22272         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
22273
22274         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
22275         local facet=mds$((mdtidx + 1))
22276
22277         cancel_lru_locks mdc
22278         do_facet $facet lctl set_param -n mdt.*.dom_lock=0
22279         createmany -o $dom 1000
22280         lctl set_param -n mdc.*.stats=clear
22281         smalliomany -w $dom 1000 200
22282         get_mdc_stats $mdtidx
22283         local enq=$(get_mdc_stats $mdtidx ldlm_ibits_enqueue)
22284         # Each file has 1 open, 1 IO enqueues, total 2000
22285         # but now we have also +1 getxattr for security.capability, total 3000
22286         [ $enq -ge 2000 ] || error "Too few enqueues $enq, expected > 2000"
22287         unlinkmany $dom 1000
22288
22289         cancel_lru_locks mdc
22290         do_facet $facet lctl set_param -n mdt.*.dom_lock=1
22291         createmany -o $dom 1000
22292         lctl set_param -n mdc.*.stats=clear
22293         smalliomany -w $dom 1000 200
22294         local enq_2=$(get_mdc_stats $mdtidx ldlm_ibits_enqueue)
22295         # Expect to see reduced amount of RPCs by 1000 due to single enqueue
22296         # for OPEN and IO lock.
22297         [ $((enq - enq_2)) -ge 1000 ] ||
22298                 error "Too many enqueues $enq_2, expected about $((enq - 1000))"
22299         unlinkmany $dom 1000
22300         return 0
22301 }
22302 run_test 271c "DoM: IO lock at open saves enqueue RPCs"
22303
22304 cleanup_271def_tests() {
22305         trap 0
22306         rm -f $1
22307 }
22308
22309 test_271d() {
22310         [ $MDS1_VERSION -lt $(version_code 2.10.57) ] &&
22311                 skip "Need MDS version at least 2.10.57"
22312
22313         local dom=$DIR/$tdir/dom
22314         local tmp=$TMP/$tfile
22315         trap "cleanup_271def_tests $tmp" EXIT
22316
22317         mkdir -p $DIR/$tdir
22318
22319         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
22320
22321         local mdtidx=$($LFS getstripe --mdt-index $DIR/$tdir)
22322
22323         cancel_lru_locks mdc
22324         dd if=/dev/urandom of=$tmp bs=1000 count=1
22325         dd if=$tmp of=$dom bs=1000 count=1
22326         cancel_lru_locks mdc
22327
22328         cat /etc/hosts >> $tmp
22329         lctl set_param -n mdc.*.stats=clear
22330
22331         # append data to the same file it should update local page
22332         echo "Append to the same page"
22333         cat /etc/hosts >> $dom
22334         local num=$(get_mdc_stats $mdtidx ost_read)
22335         local ra=$(get_mdc_stats $mdtidx req_active)
22336         local rw=$(get_mdc_stats $mdtidx req_waittime)
22337
22338         [ -z $num ] || error "$num READ RPC occured"
22339         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
22340         echo "... DONE"
22341
22342         # compare content
22343         cmp $tmp $dom || error "file miscompare"
22344
22345         cancel_lru_locks mdc
22346         lctl set_param -n mdc.*.stats=clear
22347
22348         echo "Open and read file"
22349         cat $dom > /dev/null
22350         local num=$(get_mdc_stats $mdtidx ost_read)
22351         local ra=$(get_mdc_stats $mdtidx req_active)
22352         local rw=$(get_mdc_stats $mdtidx req_waittime)
22353
22354         [ -z $num ] || error "$num READ RPC occured"
22355         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
22356         echo "... DONE"
22357
22358         # compare content
22359         cmp $tmp $dom || error "file miscompare"
22360
22361         return 0
22362 }
22363 run_test 271d "DoM: read on open (1K file in reply buffer)"
22364
22365 test_271f() {
22366         [ $MDS1_VERSION -lt $(version_code 2.10.57) ] &&
22367                 skip "Need MDS version at least 2.10.57"
22368
22369         local dom=$DIR/$tdir/dom
22370         local tmp=$TMP/$tfile
22371         trap "cleanup_271def_tests $tmp" EXIT
22372
22373         mkdir -p $DIR/$tdir
22374
22375         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
22376
22377         local mdtidx=$($LFS getstripe --mdt-index $DIR/$tdir)
22378
22379         cancel_lru_locks mdc
22380         dd if=/dev/urandom of=$tmp bs=265000 count=1
22381         dd if=$tmp of=$dom bs=265000 count=1
22382         cancel_lru_locks mdc
22383         cat /etc/hosts >> $tmp
22384         lctl set_param -n mdc.*.stats=clear
22385
22386         echo "Append to the same page"
22387         cat /etc/hosts >> $dom
22388         local num=$(get_mdc_stats $mdtidx ost_read)
22389         local ra=$(get_mdc_stats $mdtidx req_active)
22390         local rw=$(get_mdc_stats $mdtidx req_waittime)
22391
22392         [ -z $num ] || error "$num READ RPC occured"
22393         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
22394         echo "... DONE"
22395
22396         # compare content
22397         cmp $tmp $dom || error "file miscompare"
22398
22399         cancel_lru_locks mdc
22400         lctl set_param -n mdc.*.stats=clear
22401
22402         echo "Open and read file"
22403         cat $dom > /dev/null
22404         local num=$(get_mdc_stats $mdtidx ost_read)
22405         local ra=$(get_mdc_stats $mdtidx req_active)
22406         local rw=$(get_mdc_stats $mdtidx req_waittime)
22407
22408         [ -z $num ] && num=0
22409         [ $num -eq 1 ] || error "expect 1 READ RPC, $num occured"
22410         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
22411         echo "... DONE"
22412
22413         # compare content
22414         cmp $tmp $dom || error "file miscompare"
22415
22416         return 0
22417 }
22418 run_test 271f "DoM: read on open (200K file and read tail)"
22419
22420 test_271g() {
22421         [[ $($LCTL get_param mdc.*.import) =~ async_discard ]] ||
22422                 skip "Skipping due to old client or server version"
22423
22424         $LFS setstripe -E 1024K -L mdt -E EOF $DIR1/$tfile
22425         # to get layout
22426         $CHECKSTAT -t file $DIR1/$tfile
22427
22428         $MULTIOP $DIR1/$tfile Ow40960_w4096c &
22429         MULTIOP_PID=$!
22430         sleep 1
22431         #define OBD_FAIL_LDLM_CANCEL_BL_CB_RACE
22432         $LCTL set_param fail_loc=0x80000314
22433         rm $DIR1/$tfile || error "Unlink fails"
22434         RC=$?
22435         kill -USR1 $MULTIOP_PID && wait $MULTIOP_PID || error "multiop failure"
22436         [ $RC -eq 0 ] || error "Failed write to stale object"
22437 }
22438 run_test 271g "Discard DoM data vs client flush race"
22439
22440 test_272a() {
22441         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
22442                 skip "Need MDS version at least 2.11.50"
22443
22444         local dom=$DIR/$tdir/dom
22445         mkdir -p $DIR/$tdir
22446
22447         $LFS setstripe -E 256K -L mdt -E -1 -c1 $dom
22448         dd if=/dev/urandom of=$dom bs=512K count=1 ||
22449                 error "failed to write data into $dom"
22450         local old_md5=$(md5sum $dom)
22451
22452         $LFS migrate -E 256K -L mdt -E -1 -c2 $dom ||
22453                 error "failed to migrate to the same DoM component"
22454
22455         local new_md5=$(md5sum $dom)
22456
22457         [ "$old_md5" == "$new_md5" ] ||
22458                 error "md5sum differ: $old_md5, $new_md5"
22459
22460         [ $($LFS getstripe -c $dom) -eq 2 ] ||
22461                 error "bad final stripe count: $($LFS getstripe -c $dom) != 2"
22462 }
22463 run_test 272a "DoM migration: new layout with the same DOM component"
22464
22465 test_272b() {
22466         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
22467                 skip "Need MDS version at least 2.11.50"
22468
22469         local dom=$DIR/$tdir/dom
22470         mkdir -p $DIR/$tdir
22471         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
22472
22473         local mdtidx=$($LFS getstripe -m $dom)
22474         local mdtname=MDT$(printf %04x $mdtidx)
22475         local facet=mds$((mdtidx + 1))
22476
22477         local mdtfree1=$(do_facet $facet \
22478                 lctl get_param -n osd*.*$mdtname.kbytesfree)
22479         dd if=/dev/urandom of=$dom bs=2M count=1 ||
22480                 error "failed to write data into $dom"
22481         local old_md5=$(md5sum $dom)
22482         cancel_lru_locks mdc
22483         local mdtfree1=$(do_facet $facet \
22484                 lctl get_param -n osd*.*$mdtname.kbytesfree)
22485
22486         $LFS migrate -c2 $dom ||
22487                 error "failed to migrate to the new composite layout"
22488         [ $($LFS getstripe -L $dom) != 'mdt' ] ||
22489                 error "MDT stripe was not removed"
22490
22491         cancel_lru_locks mdc
22492         local new_md5=$(md5sum $dom)
22493         [ "$old_md5" == "$new_md5" ] ||
22494                 error "$old_md5 != $new_md5"
22495
22496         # Skip free space checks with ZFS
22497         if [ "$(facet_fstype $facet)" != "zfs" ]; then
22498                 local mdtfree2=$(do_facet $facet \
22499                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
22500                 [ $mdtfree2 -gt $mdtfree1 ] ||
22501                         error "MDT space is not freed after migration"
22502         fi
22503         return 0
22504 }
22505 run_test 272b "DoM migration: DOM file to the OST-striped file (plain)"
22506
22507 test_272c() {
22508         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
22509                 skip "Need MDS version at least 2.11.50"
22510
22511         local dom=$DIR/$tdir/$tfile
22512         mkdir -p $DIR/$tdir
22513         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
22514
22515         local mdtidx=$($LFS getstripe -m $dom)
22516         local mdtname=MDT$(printf %04x $mdtidx)
22517         local facet=mds$((mdtidx + 1))
22518
22519         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
22520                 error "failed to write data into $dom"
22521         local old_md5=$(md5sum $dom)
22522         cancel_lru_locks mdc
22523         local mdtfree1=$(do_facet $facet \
22524                 lctl get_param -n osd*.*$mdtname.kbytesfree)
22525
22526         $LFS migrate -E 2M -c1 -E -1 -c2 $dom ||
22527                 error "failed to migrate to the new composite layout"
22528         [ $($LFS getstripe -L $dom) == 'mdt' ] &&
22529                 error "MDT stripe was not removed"
22530
22531         cancel_lru_locks mdc
22532         local new_md5=$(md5sum $dom)
22533         [ "$old_md5" == "$new_md5" ] ||
22534                 error "$old_md5 != $new_md5"
22535
22536         # Skip free space checks with ZFS
22537         if [ "$(facet_fstype $facet)" != "zfs" ]; then
22538                 local mdtfree2=$(do_facet $facet \
22539                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
22540                 [ $mdtfree2 -gt $mdtfree1 ] ||
22541                         error "MDS space is not freed after migration"
22542         fi
22543         return 0
22544 }
22545 run_test 272c "DoM migration: DOM file to the OST-striped file (composite)"
22546
22547 test_272d() {
22548         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
22549                 skip "Need MDS version at least 2.12.55"
22550
22551         local dom=$DIR/$tdir/$tfile
22552         mkdir -p $DIR/$tdir
22553         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
22554
22555         local mdtidx=$($LFS getstripe -m $dom)
22556         local mdtname=MDT$(printf %04x $mdtidx)
22557         local facet=mds$((mdtidx + 1))
22558
22559         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
22560                 error "failed to write data into $dom"
22561         local old_md5=$(md5sum $dom)
22562         cancel_lru_locks mdc
22563         local mdtfree1=$(do_facet $facet \
22564                 lctl get_param -n osd*.*$mdtname.kbytesfree)
22565
22566         $LFS mirror extend -N -E 2M -c1 -E -1 -c2 $dom ||
22567                 error "failed mirroring to the new composite layout"
22568         $LFS mirror resync $dom ||
22569                 error "failed mirror resync"
22570         $LFS mirror split --mirror-id 1 -d $dom ||
22571                 error "failed mirror split"
22572
22573         [ $($LFS getstripe -L $dom) != 'mdt' ] ||
22574                 error "MDT stripe was not removed"
22575
22576         cancel_lru_locks mdc
22577         local new_md5=$(md5sum $dom)
22578         [ "$old_md5" == "$new_md5" ] ||
22579                 error "$old_md5 != $new_md5"
22580
22581         # Skip free space checks with ZFS
22582         if [ "$(facet_fstype $facet)" != "zfs" ]; then
22583                 local mdtfree2=$(do_facet $facet \
22584                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
22585                 [ $mdtfree2 -gt $mdtfree1 ] ||
22586                         error "MDS space is not freed after DOM mirror deletion"
22587         fi
22588         return 0
22589 }
22590 run_test 272d "DoM mirroring: OST-striped mirror to DOM file"
22591
22592 test_272e() {
22593         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
22594                 skip "Need MDS version at least 2.12.55"
22595
22596         local dom=$DIR/$tdir/$tfile
22597         mkdir -p $DIR/$tdir
22598         $LFS setstripe -c 2 $dom
22599
22600         dd if=/dev/urandom of=$dom bs=512K count=1 oflag=direct ||
22601                 error "failed to write data into $dom"
22602         local old_md5=$(md5sum $dom)
22603         cancel_lru_locks mdc
22604
22605         $LFS mirror extend -N -E 1M -L mdt -E eof -c2 $dom ||
22606                 error "failed mirroring to the DOM layout"
22607         $LFS mirror resync $dom ||
22608                 error "failed mirror resync"
22609         $LFS mirror split --mirror-id 1 -d $dom ||
22610                 error "failed mirror split"
22611
22612         [ $($LFS getstripe -L $dom) != 'mdt' ] ||
22613                 error "MDT stripe was not removed"
22614
22615         cancel_lru_locks mdc
22616         local new_md5=$(md5sum $dom)
22617         [ "$old_md5" == "$new_md5" ] ||
22618                 error "$old_md5 != $new_md5"
22619
22620         return 0
22621 }
22622 run_test 272e "DoM mirroring: DOM mirror to the OST-striped file"
22623
22624 test_272f() {
22625         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
22626                 skip "Need MDS version at least 2.12.55"
22627
22628         local dom=$DIR/$tdir/$tfile
22629         mkdir -p $DIR/$tdir
22630         $LFS setstripe -c 2 $dom
22631
22632         dd if=/dev/urandom of=$dom bs=512K count=1 oflag=direct ||
22633                 error "failed to write data into $dom"
22634         local old_md5=$(md5sum $dom)
22635         cancel_lru_locks mdc
22636
22637         $LFS migrate -E 1M -L mdt -E eof -c2 -v $dom ||
22638                 error "failed migrating to the DOM file"
22639
22640         cancel_lru_locks mdc
22641         local new_md5=$(md5sum $dom)
22642         [ "$old_md5" != "$new_md5" ] &&
22643                 error "$old_md5 != $new_md5"
22644
22645         return 0
22646 }
22647 run_test 272f "DoM migration: OST-striped file to DOM file"
22648
22649 test_273a() {
22650         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
22651                 skip "Need MDS version at least 2.11.50"
22652
22653         # Layout swap cannot be done if either file has DOM component,
22654         # this will never be supported, migration should be used instead
22655
22656         local dom=$DIR/$tdir/$tfile
22657         mkdir -p $DIR/$tdir
22658
22659         $LFS setstripe -c2 ${dom}_plain
22660         $LFS setstripe -E 1M -L mdt -E -1 -c2 ${dom}_dom
22661         $LFS swap_layouts ${dom}_plain ${dom}_dom &&
22662                 error "can swap layout with DoM component"
22663         $LFS swap_layouts ${dom}_dom ${dom}_plain &&
22664                 error "can swap layout with DoM component"
22665
22666         $LFS setstripe -E 1M -c1 -E -1 -c2 ${dom}_comp
22667         $LFS swap_layouts ${dom}_comp ${dom}_dom &&
22668                 error "can swap layout with DoM component"
22669         $LFS swap_layouts ${dom}_dom ${dom}_comp &&
22670                 error "can swap layout with DoM component"
22671         return 0
22672 }
22673 run_test 273a "DoM: layout swapping should fail with DOM"
22674
22675 test_273b() {
22676         mkdir -p $DIR/$tdir
22677         $LFS setstripe -E 1M -L mdt -E -1 -c -1 $DIR/$tdir
22678
22679 #define OBD_FAIL_MDS_COMMITRW_DELAY      0x16b
22680         do_facet mds1 $LCTL set_param fail_loc=0x8000016b fail_val=2
22681
22682         $MULTIOP $DIR/$tdir/$tfile Ouw2097152c
22683 }
22684 run_test 273b "DoM: race writeback and object destroy"
22685
22686 test_275() {
22687         remote_ost_nodsh && skip "remote OST with nodsh"
22688         [ $OST1_VERSION -lt $(version_code 2.10.57) ] &&
22689                 skip "Need OST version >= 2.10.57"
22690
22691         local file=$DIR/$tfile
22692         local oss
22693
22694         oss=$(comma_list $(osts_nodes))
22695
22696         dd if=/dev/urandom of=$file bs=1M count=2 ||
22697                 error "failed to create a file"
22698         cancel_lru_locks osc
22699
22700         #lock 1
22701         dd if=$file of=/dev/null bs=1M count=1 iflag=direct ||
22702                 error "failed to read a file"
22703
22704 #define OBD_FAIL_LDLM_PAUSE_CANCEL2      0x31f
22705         $LCTL set_param fail_loc=0x8000031f
22706
22707         cancel_lru_locks osc &
22708         sleep 1
22709
22710 #define OBD_FAIL_LDLM_PROLONG_PAUSE      0x32b
22711         do_nodes $oss $LCTL set_param fail_loc=0x8000032b
22712         #IO takes another lock, but matches the PENDING one
22713         #and places it to the IO RPC
22714         dd if=$file of=/dev/null bs=1M count=1 iflag=direct ||
22715                 error "failed to read a file with PENDING lock"
22716 }
22717 run_test 275 "Read on a canceled duplicate lock"
22718
22719 test_276() {
22720         remote_ost_nodsh && skip "remote OST with nodsh"
22721         local pid
22722
22723         do_facet ost1 "(while true; do \
22724                 $LCTL get_param obdfilter.*.filesfree > /dev/null 2>&1; \
22725                 done) & pid=\\\$!; echo \\\$pid > $TMP/sanity_276_pid" &
22726         pid=$!
22727
22728         for LOOP in $(seq 20); do
22729                 stop ost1
22730                 start ost1 $(ostdevname 1) $OST_MOUNT_OPTS
22731         done
22732         kill -9 $pid
22733         do_facet ost1 "pid=\\\$(cat $TMP/sanity_276_pid); kill -9 \\\$pid; \
22734                 rm $TMP/sanity_276_pid"
22735 }
22736 run_test 276 "Race between mount and obd_statfs"
22737
22738 test_277() {
22739         $LCTL set_param ldlm.namespaces.*.lru_size=0
22740         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
22741         local cached_mb=$($LCTL get_param llite.*.max_cached_mb |
22742                         grep ^used_mb | awk '{print $2}')
22743         [ $cached_mb -eq 1 ] || error "expected mb 1 got $cached_mb"
22744         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 \
22745                 oflag=direct conv=notrunc
22746         cached_mb=$($LCTL get_param llite.*.max_cached_mb |
22747                         grep ^used_mb | awk '{print $2}')
22748         [ $cached_mb -eq 0 ] || error "expected mb 0 got $cached_mb"
22749 }
22750 run_test 277 "Direct IO shall drop page cache"
22751
22752 test_278() {
22753         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
22754         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
22755         [[ "$(facet_host mds1)" != "$(facet_host mds2)" ]] &&
22756                 skip "needs the same host for mdt1 mdt2" && return
22757
22758         local pid1
22759         local pid2
22760
22761 #define OBD_FAIL_OBD_STOP_MDS_RACE     0x60b
22762         do_facet mds2 $LCTL set_param fail_loc=0x8000060c
22763         stop mds2 &
22764         pid2=$!
22765
22766         stop mds1
22767
22768         echo "Starting MDTs"
22769         start mds1 $(mdsdevname 1) $MDS_MOUNT_OPTS
22770         wait $pid2
22771 #For the error assertion will happen. lu_env_get_key(..., &mdt_thread_key)
22772 #will return NULL
22773         do_facet mds2 $LCTL set_param fail_loc=0
22774
22775         start mds2 $(mdsdevname 2) $MDS_MOUNT_OPTS
22776         wait_recovery_complete mds2
22777 }
22778 run_test 278 "Race starting MDS between MDTs stop/start"
22779
22780 test_280() {
22781         [ $MGS_VERSION -lt $(version_code 2.13.52) ] &&
22782                 skip "Need MGS version at least 2.13.52"
22783         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22784         combined_mgs_mds || skip "needs combined MGS/MDT"
22785
22786         umount_client $MOUNT
22787 #define OBD_FAIL_MDS_LLOG_UMOUNT_RACE   0x15e
22788         do_facet mgs $LCTL set_param fail_loc=0x8000015e fail_val=0
22789
22790         mount_client $MOUNT &
22791         sleep 1
22792         stop mgs || error "stop mgs failed"
22793         #for a race mgs would crash
22794         start mgs $(mgsdevname) $MGS_MOUNT_OPTS || error "start mgs failed"
22795         # make sure we unmount client before remounting
22796         wait
22797         umount_client $MOUNT
22798         mount_client $MOUNT || error "mount client failed"
22799 }
22800 run_test 280 "Race between MGS umount and client llog processing"
22801
22802 cleanup_test_300() {
22803         trap 0
22804         umask $SAVE_UMASK
22805 }
22806 test_striped_dir() {
22807         local mdt_index=$1
22808         local stripe_count
22809         local stripe_index
22810
22811         mkdir -p $DIR/$tdir
22812
22813         SAVE_UMASK=$(umask)
22814         trap cleanup_test_300 RETURN EXIT
22815
22816         $LFS setdirstripe -i $mdt_index -c 2 -H all_char -o 755 \
22817                                                 $DIR/$tdir/striped_dir ||
22818                 error "set striped dir error"
22819
22820         local mode=$(stat -c%a $DIR/$tdir/striped_dir)
22821         [ "$mode" = "755" ] || error "expect 755 got $mode"
22822
22823         $LFS getdirstripe $DIR/$tdir/striped_dir > /dev/null 2>&1 ||
22824                 error "getdirstripe failed"
22825         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir)
22826         if [ "$stripe_count" != "2" ]; then
22827                 error "1:stripe_count is $stripe_count, expect 2"
22828         fi
22829         stripe_count=$($LFS getdirstripe -T $DIR/$tdir/striped_dir)
22830         if [ "$stripe_count" != "2" ]; then
22831                 error "2:stripe_count is $stripe_count, expect 2"
22832         fi
22833
22834         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir)
22835         if [ "$stripe_index" != "$mdt_index" ]; then
22836                 error "stripe_index is $stripe_index, expect $mdt_index"
22837         fi
22838
22839         [ $(stat -c%h $DIR/$tdir/striped_dir) == '2' ] ||
22840                 error "nlink error after create striped dir"
22841
22842         mkdir $DIR/$tdir/striped_dir/a
22843         mkdir $DIR/$tdir/striped_dir/b
22844
22845         stat $DIR/$tdir/striped_dir/a ||
22846                 error "create dir under striped dir failed"
22847         stat $DIR/$tdir/striped_dir/b ||
22848                 error "create dir under striped dir failed"
22849
22850         [ $(stat -c%h $DIR/$tdir/striped_dir) == '4' ] ||
22851                 error "nlink error after mkdir"
22852
22853         rmdir $DIR/$tdir/striped_dir/a
22854         [ $(stat -c%h $DIR/$tdir/striped_dir) == '3' ] ||
22855                 error "nlink error after rmdir"
22856
22857         rmdir $DIR/$tdir/striped_dir/b
22858         [ $(stat -c%h $DIR/$tdir/striped_dir) == '2' ] ||
22859                 error "nlink error after rmdir"
22860
22861         chattr +i $DIR/$tdir/striped_dir
22862         createmany -o $DIR/$tdir/striped_dir/f 10 &&
22863                 error "immutable flags not working under striped dir!"
22864         chattr -i $DIR/$tdir/striped_dir
22865
22866         rmdir $DIR/$tdir/striped_dir ||
22867                 error "rmdir striped dir error"
22868
22869         cleanup_test_300
22870
22871         true
22872 }
22873
22874 test_300a() {
22875         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
22876                 skip "skipped for lustre < 2.7.0"
22877         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22878         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22879
22880         test_striped_dir 0 || error "failed on striped dir on MDT0"
22881         test_striped_dir 1 || error "failed on striped dir on MDT0"
22882 }
22883 run_test 300a "basic striped dir sanity test"
22884
22885 test_300b() {
22886         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
22887                 skip "skipped for lustre < 2.7.0"
22888         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22889         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22890
22891         local i
22892         local mtime1
22893         local mtime2
22894         local mtime3
22895
22896         test_mkdir $DIR/$tdir || error "mkdir fail"
22897         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
22898                 error "set striped dir error"
22899         for i in {0..9}; do
22900                 mtime1=$(stat -c %Y $DIR/$tdir/striped_dir)
22901                 sleep 1
22902                 touch $DIR/$tdir/striped_dir/file_$i || error "touch error $i"
22903                 mtime2=$(stat -c %Y $DIR/$tdir/striped_dir)
22904                 [ $mtime1 -eq $mtime2 ] && error "mtime unchanged after create"
22905                 sleep 1
22906                 rm -f $DIR/$tdir/striped_dir/file_$i || error "unlink error $i"
22907                 mtime3=$(stat -c %Y $DIR/$tdir/striped_dir)
22908                 [ $mtime2 -eq $mtime3 ] && error "mtime unchanged after unlink"
22909         done
22910         true
22911 }
22912 run_test 300b "check ctime/mtime for striped dir"
22913
22914 test_300c() {
22915         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
22916                 skip "skipped for lustre < 2.7.0"
22917         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22918         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22919
22920         local file_count
22921
22922         mkdir_on_mdt0 $DIR/$tdir
22923         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir ||
22924                 error "set striped dir error"
22925
22926         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/striped_dir ||
22927                 error "chown striped dir failed"
22928
22929         $RUNAS createmany -o $DIR/$tdir/striped_dir/f 5000 ||
22930                 error "create 5k files failed"
22931
22932         file_count=$(ls $DIR/$tdir/striped_dir | wc -l)
22933
22934         [ "$file_count" = 5000 ] || error "file count $file_count != 5000"
22935
22936         rm -rf $DIR/$tdir
22937 }
22938 run_test 300c "chown && check ls under striped directory"
22939
22940 test_300d() {
22941         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
22942                 skip "skipped for lustre < 2.7.0"
22943         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22944         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22945
22946         local stripe_count
22947         local file
22948
22949         mkdir -p $DIR/$tdir
22950         $LFS setstripe -c 2 $DIR/$tdir
22951
22952         #local striped directory
22953         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
22954                 error "set striped dir error"
22955         #look at the directories for debug purposes
22956         ls -l $DIR/$tdir
22957         $LFS getdirstripe $DIR/$tdir
22958         ls -l $DIR/$tdir/striped_dir
22959         $LFS getdirstripe $DIR/$tdir/striped_dir
22960         createmany -o $DIR/$tdir/striped_dir/f 10 ||
22961                 error "create 10 files failed"
22962
22963         #remote striped directory
22964         $LFS setdirstripe -i 1 -c 2 $DIR/$tdir/remote_striped_dir ||
22965                 error "set striped dir error"
22966         #look at the directories for debug purposes
22967         ls -l $DIR/$tdir
22968         $LFS getdirstripe $DIR/$tdir
22969         ls -l $DIR/$tdir/remote_striped_dir
22970         $LFS getdirstripe $DIR/$tdir/remote_striped_dir
22971         createmany -o $DIR/$tdir/remote_striped_dir/f 10 ||
22972                 error "create 10 files failed"
22973
22974         for file in $(find $DIR/$tdir); do
22975                 stripe_count=$($LFS getstripe -c $file)
22976                 [ $stripe_count -eq 2 ] ||
22977                         error "wrong stripe $stripe_count for $file"
22978         done
22979
22980         rm -rf $DIR/$tdir
22981 }
22982 run_test 300d "check default stripe under striped directory"
22983
22984 test_300e() {
22985         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
22986                 skip "Need MDS version at least 2.7.55"
22987         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22988         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22989
22990         local stripe_count
22991         local file
22992
22993         mkdir -p $DIR/$tdir
22994
22995         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
22996                 error "set striped dir error"
22997
22998         touch $DIR/$tdir/striped_dir/a
22999         touch $DIR/$tdir/striped_dir/b
23000         touch $DIR/$tdir/striped_dir/c
23001
23002         mkdir $DIR/$tdir/striped_dir/dir_a
23003         mkdir $DIR/$tdir/striped_dir/dir_b
23004         mkdir $DIR/$tdir/striped_dir/dir_c
23005
23006         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_a ||
23007                 error "set striped adir under striped dir error"
23008
23009         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_b ||
23010                 error "set striped bdir under striped dir error"
23011
23012         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_c ||
23013                 error "set striped cdir under striped dir error"
23014
23015         mrename $DIR/$tdir/striped_dir/dir_a $DIR/$tdir/striped_dir/dir_b ||
23016                 error "rename dir under striped dir fails"
23017
23018         mrename $DIR/$tdir/striped_dir/stp_a $DIR/$tdir/striped_dir/stp_b ||
23019                 error "rename dir under different stripes fails"
23020
23021         mrename $DIR/$tdir/striped_dir/a $DIR/$tdir/striped_dir/c ||
23022                 error "rename file under striped dir should succeed"
23023
23024         mrename $DIR/$tdir/striped_dir/dir_b $DIR/$tdir/striped_dir/dir_c ||
23025                 error "rename dir under striped dir should succeed"
23026
23027         rm -rf $DIR/$tdir
23028 }
23029 run_test 300e "check rename under striped directory"
23030
23031 test_300f() {
23032         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23033         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23034         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23035                 skip "Need MDS version at least 2.7.55"
23036
23037         local stripe_count
23038         local file
23039
23040         rm -rf $DIR/$tdir
23041         mkdir -p $DIR/$tdir
23042
23043         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
23044                 error "set striped dir error"
23045
23046         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir1 ||
23047                 error "set striped dir error"
23048
23049         touch $DIR/$tdir/striped_dir/a
23050         mkdir $DIR/$tdir/striped_dir/dir_a
23051         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir/stp_a ||
23052                 error "create striped dir under striped dir fails"
23053
23054         touch $DIR/$tdir/striped_dir1/b
23055         mkdir $DIR/$tdir/striped_dir1/dir_b
23056         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir/stp_b ||
23057                 error "create striped dir under striped dir fails"
23058
23059         mrename $DIR/$tdir/striped_dir/dir_a $DIR/$tdir/striped_dir1/dir_b ||
23060                 error "rename dir under different striped dir should fail"
23061
23062         mrename $DIR/$tdir/striped_dir/stp_a $DIR/$tdir/striped_dir1/stp_b ||
23063                 error "rename striped dir under diff striped dir should fail"
23064
23065         mrename $DIR/$tdir/striped_dir/a $DIR/$tdir/striped_dir1/a ||
23066                 error "rename file under diff striped dirs fails"
23067
23068         rm -rf $DIR/$tdir
23069 }
23070 run_test 300f "check rename cross striped directory"
23071
23072 test_300_check_default_striped_dir()
23073 {
23074         local dirname=$1
23075         local default_count=$2
23076         local default_index=$3
23077         local stripe_count
23078         local stripe_index
23079         local dir_stripe_index
23080         local dir
23081
23082         echo "checking $dirname $default_count $default_index"
23083         $LFS setdirstripe -D -c $default_count -i $default_index \
23084                                 -H all_char $DIR/$tdir/$dirname ||
23085                 error "set default stripe on striped dir error"
23086         stripe_count=$($LFS getdirstripe -D -c $DIR/$tdir/$dirname)
23087         [ $stripe_count -eq $default_count ] ||
23088                 error "expect $default_count get $stripe_count for $dirname"
23089
23090         stripe_index=$($LFS getdirstripe -D -i $DIR/$tdir/$dirname)
23091         [ $stripe_index -eq $default_index ] ||
23092                 error "expect $default_index get $stripe_index for $dirname"
23093
23094         mkdir $DIR/$tdir/$dirname/{test1,test2,test3,test4} ||
23095                                                 error "create dirs failed"
23096
23097         createmany -o $DIR/$tdir/$dirname/f- 10 || error "create files failed"
23098         unlinkmany $DIR/$tdir/$dirname/f- 10    || error "unlink files failed"
23099         for dir in $(find $DIR/$tdir/$dirname/*); do
23100                 stripe_count=$($LFS getdirstripe -c $dir)
23101                 (( $stripe_count == $default_count )) ||
23102                 (( $stripe_count == $MDSCOUNT && $default_count == -1 )) ||
23103                 (( $stripe_count == 0 )) || (( $default_count == 1 )) ||
23104                 error "stripe count $default_count != $stripe_count for $dir"
23105
23106                 stripe_index=$($LFS getdirstripe -i $dir)
23107                 [ $default_index -eq -1 ] ||
23108                         [ $stripe_index -eq $default_index ] ||
23109                         error "$stripe_index != $default_index for $dir"
23110
23111                 #check default stripe
23112                 stripe_count=$($LFS getdirstripe -D -c $dir)
23113                 [ $stripe_count -eq $default_count ] ||
23114                 error "default count $default_count != $stripe_count for $dir"
23115
23116                 stripe_index=$($LFS getdirstripe -D -i $dir)
23117                 [ $stripe_index -eq $default_index ] ||
23118                 error "default index $default_index != $stripe_index for $dir"
23119         done
23120         rmdir $DIR/$tdir/$dirname/* || error "rmdir failed"
23121 }
23122
23123 test_300g() {
23124         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23125         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23126                 skip "Need MDS version at least 2.7.55"
23127
23128         local dir
23129         local stripe_count
23130         local stripe_index
23131
23132         mkdir_on_mdt0 $DIR/$tdir
23133         mkdir $DIR/$tdir/normal_dir
23134
23135         #Checking when client cache stripe index
23136         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
23137         $LFS setdirstripe -D -i1 $DIR/$tdir/striped_dir ||
23138                 error "create striped_dir failed"
23139
23140         $LFS setdirstripe -i0 $DIR/$tdir/striped_dir/dir0 ||
23141                 error "create dir0 fails"
23142         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/dir0)
23143         [ $stripe_index -eq 0 ] ||
23144                 error "dir0 expect index 0 got $stripe_index"
23145
23146         mkdir $DIR/$tdir/striped_dir/dir1 ||
23147                 error "create dir1 fails"
23148         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/dir1)
23149         [ $stripe_index -eq 1 ] ||
23150                 error "dir1 expect index 1 got $stripe_index"
23151
23152         #check default stripe count/stripe index
23153         test_300_check_default_striped_dir normal_dir $MDSCOUNT 1
23154         test_300_check_default_striped_dir normal_dir 1 0
23155         test_300_check_default_striped_dir normal_dir -1 1
23156         test_300_check_default_striped_dir normal_dir 2 -1
23157
23158         #delete default stripe information
23159         echo "delete default stripeEA"
23160         $LFS setdirstripe -d $DIR/$tdir/normal_dir ||
23161                 error "set default stripe on striped dir error"
23162
23163         mkdir -p $DIR/$tdir/normal_dir/{test1,test2,test3,test4}
23164         for dir in $(find $DIR/$tdir/normal_dir/*); do
23165                 stripe_count=$($LFS getdirstripe -c $dir)
23166                 [ $stripe_count -eq 0 ] ||
23167                         error "expect 1 get $stripe_count for $dir"
23168         done
23169 }
23170 run_test 300g "check default striped directory for normal directory"
23171
23172 test_300h() {
23173         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23174         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23175                 skip "Need MDS version at least 2.7.55"
23176
23177         local dir
23178         local stripe_count
23179
23180         mkdir $DIR/$tdir
23181         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
23182                 error "set striped dir error"
23183
23184         test_300_check_default_striped_dir striped_dir $MDSCOUNT 1
23185         test_300_check_default_striped_dir striped_dir 1 0
23186         test_300_check_default_striped_dir striped_dir -1 1
23187         test_300_check_default_striped_dir striped_dir 2 -1
23188
23189         #delete default stripe information
23190         $LFS setdirstripe -d $DIR/$tdir/striped_dir ||
23191                 error "set default stripe on striped dir error"
23192
23193         mkdir -p $DIR/$tdir/striped_dir/{test1,test2,test3,test4}
23194         for dir in $(find $DIR/$tdir/striped_dir/*); do
23195                 stripe_count=$($LFS getdirstripe -c $dir)
23196                 [ $stripe_count -eq 0 ] ||
23197                         error "expect 1 get $stripe_count for $dir"
23198         done
23199 }
23200 run_test 300h "check default striped directory for striped directory"
23201
23202 test_300i() {
23203         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23204         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23205         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23206                 skip "Need MDS version at least 2.7.55"
23207
23208         local stripe_count
23209         local file
23210
23211         mkdir $DIR/$tdir
23212
23213         $LFS setdirstripe -i 0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
23214                 error "set striped dir error"
23215
23216         createmany -o $DIR/$tdir/striped_dir/f- 10 ||
23217                 error "create files under striped dir failed"
23218
23219         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/hashdir ||
23220                 error "set striped hashdir error"
23221
23222         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/hashdir/d0 ||
23223                 error "create dir0 under hash dir failed"
23224         $LFS setdirstripe -i0 -c$MDSCOUNT -H fnv_1a_64 $DIR/$tdir/hashdir/d1 ||
23225                 error "create dir1 under hash dir failed"
23226         $LFS setdirstripe -i0 -c$MDSCOUNT -H crush $DIR/$tdir/hashdir/d2 ||
23227                 error "create dir2 under hash dir failed"
23228
23229         # unfortunately, we need to umount to clear dir layout cache for now
23230         # once we fully implement dir layout, we can drop this
23231         umount_client $MOUNT || error "umount failed"
23232         mount_client $MOUNT || error "mount failed"
23233
23234         $LFS find -H fnv_1a_64,crush $DIR/$tdir/hashdir
23235         local dircnt=$($LFS find -H fnv_1a_64,crush $DIR/$tdir/hashdir | wc -l)
23236         [ $dircnt -eq 2 ] || error "lfs find striped dir got:$dircnt,except:1"
23237
23238         #set the stripe to be unknown hash type
23239         #define OBD_FAIL_UNKNOWN_LMV_STRIPE     0x1901
23240         $LCTL set_param fail_loc=0x1901
23241         for ((i = 0; i < 10; i++)); do
23242                 $CHECKSTAT -t file $DIR/$tdir/striped_dir/f-$i ||
23243                         error "stat f-$i failed"
23244                 rm $DIR/$tdir/striped_dir/f-$i || error "unlink f-$i failed"
23245         done
23246
23247         touch $DIR/$tdir/striped_dir/f0 &&
23248                 error "create under striped dir with unknown hash should fail"
23249
23250         $LCTL set_param fail_loc=0
23251
23252         umount_client $MOUNT || error "umount failed"
23253         mount_client $MOUNT || error "mount failed"
23254
23255         return 0
23256 }
23257 run_test 300i "client handle unknown hash type striped directory"
23258
23259 test_300j() {
23260         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23261         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23262         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23263                 skip "Need MDS version at least 2.7.55"
23264
23265         local stripe_count
23266         local file
23267
23268         mkdir $DIR/$tdir
23269
23270         #define OBD_FAIL_SPLIT_UPDATE_REC       0x1702
23271         $LCTL set_param fail_loc=0x1702
23272         $LFS setdirstripe -i 0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
23273                 error "set striped dir error"
23274
23275         createmany -o $DIR/$tdir/striped_dir/f- 10 ||
23276                 error "create files under striped dir failed"
23277
23278         $LCTL set_param fail_loc=0
23279
23280         rm -rf $DIR/$tdir || error "unlink striped dir fails"
23281
23282         return 0
23283 }
23284 run_test 300j "test large update record"
23285
23286 test_300k() {
23287         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23288         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23289         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23290                 skip "Need MDS version at least 2.7.55"
23291
23292         # this test needs a huge transaction
23293         local kb
23294         kb=$(do_facet $SINGLEMDS "$LCTL get_param -n \
23295              osd*.$FSNAME-MDT0000.kbytestotal")
23296         [ $kb -lt $((1024*1024)) ] && skip "MDT0 too small: $kb"
23297
23298         local stripe_count
23299         local file
23300
23301         mkdir $DIR/$tdir
23302
23303         #define OBD_FAIL_LARGE_STRIPE   0x1703
23304         $LCTL set_param fail_loc=0x1703
23305         $LFS setdirstripe -i 0 -c192 $DIR/$tdir/striped_dir ||
23306                 error "set striped dir error"
23307         $LCTL set_param fail_loc=0
23308
23309         $LFS getdirstripe $DIR/$tdir/striped_dir ||
23310                 error "getstripeddir fails"
23311         rm -rf $DIR/$tdir/striped_dir ||
23312                 error "unlink striped dir fails"
23313
23314         return 0
23315 }
23316 run_test 300k "test large striped directory"
23317
23318 test_300l() {
23319         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23320         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23321         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23322                 skip "Need MDS version at least 2.7.55"
23323
23324         local stripe_index
23325
23326         test_mkdir -p $DIR/$tdir/striped_dir
23327         chown $RUNAS_ID $DIR/$tdir/striped_dir ||
23328                         error "chown $RUNAS_ID failed"
23329         $LFS setdirstripe -i 1 -D $DIR/$tdir/striped_dir ||
23330                 error "set default striped dir failed"
23331
23332         #define OBD_FAIL_MDS_STALE_DIR_LAYOUT    0x158
23333         $LCTL set_param fail_loc=0x80000158
23334         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir || error "create dir fails"
23335
23336         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/test_dir)
23337         [ $stripe_index -eq 1 ] ||
23338                 error "expect 1 get $stripe_index for $dir"
23339 }
23340 run_test 300l "non-root user to create dir under striped dir with stale layout"
23341
23342 test_300m() {
23343         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23344         [ $MDSCOUNT -ge 2 ] && skip_env "Only for single MDT"
23345         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23346                 skip "Need MDS version at least 2.7.55"
23347
23348         mkdir -p $DIR/$tdir/striped_dir
23349         $LFS setdirstripe -D -c 1 $DIR/$tdir/striped_dir ||
23350                 error "set default stripes dir error"
23351
23352         mkdir $DIR/$tdir/striped_dir/a || error "mkdir a fails"
23353
23354         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir/a)
23355         [ $stripe_count -eq 0 ] ||
23356                         error "expect 0 get $stripe_count for a"
23357
23358         $LFS setdirstripe -D -c 2 $DIR/$tdir/striped_dir ||
23359                 error "set default stripes dir error"
23360
23361         mkdir $DIR/$tdir/striped_dir/b || error "mkdir b fails"
23362
23363         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir/b)
23364         [ $stripe_count -eq 0 ] ||
23365                         error "expect 0 get $stripe_count for b"
23366
23367         $LFS setdirstripe -D -c1 -i2 $DIR/$tdir/striped_dir ||
23368                 error "set default stripes dir error"
23369
23370         mkdir $DIR/$tdir/striped_dir/c &&
23371                 error "default stripe_index is invalid, mkdir c should fails"
23372
23373         rm -rf $DIR/$tdir || error "rmdir fails"
23374 }
23375 run_test 300m "setstriped directory on single MDT FS"
23376
23377 cleanup_300n() {
23378         local list=$(comma_list $(mdts_nodes))
23379
23380         trap 0
23381         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
23382 }
23383
23384 test_300n() {
23385         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23386         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23387         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23388                 skip "Need MDS version at least 2.7.55"
23389         remote_mds_nodsh && skip "remote MDS with nodsh"
23390
23391         local stripe_index
23392         local list=$(comma_list $(mdts_nodes))
23393
23394         trap cleanup_300n RETURN EXIT
23395         mkdir -p $DIR/$tdir
23396         chmod 777 $DIR/$tdir
23397         $RUNAS $LFS setdirstripe -i0 -c$MDSCOUNT \
23398                                 $DIR/$tdir/striped_dir > /dev/null 2>&1 &&
23399                 error "create striped dir succeeds with gid=0"
23400
23401         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=-1
23402         $RUNAS $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir ||
23403                 error "create striped dir fails with gid=-1"
23404
23405         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
23406         $RUNAS $LFS setdirstripe -i 1 -c$MDSCOUNT -D \
23407                                 $DIR/$tdir/striped_dir > /dev/null 2>&1 &&
23408                 error "set default striped dir succeeds with gid=0"
23409
23410
23411         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=-1
23412         $RUNAS $LFS setdirstripe -i 1 -c$MDSCOUNT -D $DIR/$tdir/striped_dir ||
23413                 error "set default striped dir fails with gid=-1"
23414
23415
23416         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
23417         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir ||
23418                                         error "create test_dir fails"
23419         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir1 ||
23420                                         error "create test_dir1 fails"
23421         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir2 ||
23422                                         error "create test_dir2 fails"
23423         cleanup_300n
23424 }
23425 run_test 300n "non-root user to create dir under striped dir with default EA"
23426
23427 test_300o() {
23428         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23429         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23430         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23431                 skip "Need MDS version at least 2.7.55"
23432
23433         local numfree1
23434         local numfree2
23435
23436         mkdir -p $DIR/$tdir
23437
23438         numfree1=$(lctl get_param -n mdc.*MDT0000*.filesfree)
23439         numfree2=$(lctl get_param -n mdc.*MDT0001*.filesfree)
23440         if [ $numfree1 -lt 66000 ] || [ $numfree2 -lt 66000 ]; then
23441                 skip "not enough free inodes $numfree1 $numfree2"
23442         fi
23443
23444         numfree1=$(lctl get_param -n mdc.*MDT0000-mdc-*.kbytesfree)
23445         numfree2=$(lctl get_param -n mdc.*MDT0001-mdc-*.kbytesfree)
23446         if [ $numfree1 -lt 300000 ] || [ $numfree2 -lt 300000 ]; then
23447                 skip "not enough free space $numfree1 $numfree2"
23448         fi
23449
23450         $LFS setdirstripe -c2 $DIR/$tdir/striped_dir ||
23451                 error "setdirstripe fails"
23452
23453         createmany -d $DIR/$tdir/striped_dir/d 131000 ||
23454                 error "create dirs fails"
23455
23456         $LCTL set_param ldlm.namespaces.*mdc-*.lru_size=0
23457         ls $DIR/$tdir/striped_dir > /dev/null ||
23458                 error "ls striped dir fails"
23459         unlinkmany -d $DIR/$tdir/striped_dir/d 131000 ||
23460                 error "unlink big striped dir fails"
23461 }
23462 run_test 300o "unlink big sub stripe(> 65000 subdirs)"
23463
23464 test_300p() {
23465         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23466         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23467         remote_mds_nodsh && skip "remote MDS with nodsh"
23468
23469         mkdir_on_mdt0 $DIR/$tdir
23470
23471         #define OBD_FAIL_OUT_ENOSPC     0x1704
23472         do_facet mds2 lctl set_param fail_loc=0x80001704
23473         $LFS setdirstripe -i 0 -c2 $DIR/$tdir/bad_striped_dir > /dev/null 2>&1 \
23474                  && error "create striped directory should fail"
23475
23476         [ -e $DIR/$tdir/bad_striped_dir ] && error "striped dir exists"
23477
23478         $LFS setdirstripe -c2 $DIR/$tdir/bad_striped_dir
23479         true
23480 }
23481 run_test 300p "create striped directory without space"
23482
23483 test_300q() {
23484         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23485         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23486
23487         local fd=$(free_fd)
23488         local cmd="exec $fd<$tdir"
23489         cd $DIR
23490         $LFS mkdir -c $MDSCOUNT $tdir || error "create $tdir fails"
23491         eval $cmd
23492         cmd="exec $fd<&-"
23493         trap "eval $cmd" EXIT
23494         cd $tdir || error "cd $tdir fails"
23495         rmdir  ../$tdir || error "rmdir $tdir fails"
23496         mkdir local_dir && error "create dir succeeds"
23497         $LFS setdirstripe -i1 remote_dir && error "create remote dir succeeds"
23498         eval $cmd
23499         return 0
23500 }
23501 run_test 300q "create remote directory under orphan directory"
23502
23503 test_300r() {
23504         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23505                 skip "Need MDS version at least 2.7.55" && return
23506         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
23507
23508         mkdir $DIR/$tdir
23509
23510         $LFS setdirstripe -i 0 -c -1 $DIR/$tdir/striped_dir ||
23511                 error "set striped dir error"
23512
23513         $LFS getdirstripe $DIR/$tdir/striped_dir ||
23514                 error "getstripeddir fails"
23515
23516         local stripe_count
23517         stripe_count=$($LFS getdirstripe $DIR/$tdir/striped_dir |
23518                       awk '/lmv_stripe_count:/ { print $2 }')
23519
23520         [ $MDSCOUNT -ne $stripe_count ] &&
23521                 error "wrong stripe count $stripe_count expected $MDSCOUNT"
23522
23523         rm -rf $DIR/$tdir/striped_dir ||
23524                 error "unlink striped dir fails"
23525 }
23526 run_test 300r "test -1 striped directory"
23527
23528 test_300s_helper() {
23529         local count=$1
23530
23531         local stripe_dir=$DIR/$tdir/striped_dir.$count
23532
23533         $LFS mkdir -c $count $stripe_dir ||
23534                 error "lfs mkdir -c error"
23535
23536         $LFS getdirstripe $stripe_dir ||
23537                 error "lfs getdirstripe fails"
23538
23539         local stripe_count
23540         stripe_count=$($LFS getdirstripe $stripe_dir |
23541                       awk '/lmv_stripe_count:/ { print $2 }')
23542
23543         [ $count -ne $stripe_count ] &&
23544                 error_noexit "bad stripe count $stripe_count expected $count"
23545
23546         local dupe_stripes
23547         dupe_stripes=$($LFS getdirstripe $stripe_dir |
23548                 awk '/0x/ {count[$1] += 1}; END {
23549                         for (idx in count) {
23550                                 if (count[idx]>1) {
23551                                         print "index " idx " count " count[idx]
23552                                 }
23553                         }
23554                 }')
23555
23556         if [[ -n "$dupe_stripes" ]] ; then
23557                 lfs getdirstripe $stripe_dir
23558                 error_noexit "Dupe MDT above: $dupe_stripes "
23559         fi
23560
23561         rm -rf $stripe_dir ||
23562                 error_noexit "unlink $stripe_dir fails"
23563 }
23564
23565 test_300s() {
23566         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23567                 skip "Need MDS version at least 2.7.55" && return
23568         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
23569
23570         mkdir $DIR/$tdir
23571         for count in $(seq 2 $MDSCOUNT); do
23572                 test_300s_helper $count
23573         done
23574 }
23575 run_test 300s "test lfs mkdir -c without -i"
23576
23577
23578 prepare_remote_file() {
23579         mkdir $DIR/$tdir/src_dir ||
23580                 error "create remote source failed"
23581
23582         cp /etc/hosts $DIR/$tdir/src_dir/a ||
23583                  error "cp to remote source failed"
23584         touch $DIR/$tdir/src_dir/a
23585
23586         $LFS mkdir -i 1 $DIR/$tdir/tgt_dir ||
23587                 error "create remote target dir failed"
23588
23589         touch $DIR/$tdir/tgt_dir/b
23590
23591         mrename $DIR/$tdir/src_dir/a $DIR/$tdir/tgt_dir/b ||
23592                 error "rename dir cross MDT failed!"
23593
23594         $CHECKSTAT -t file $DIR/$tdir/src_dir/a &&
23595                 error "src_child still exists after rename"
23596
23597         $CHECKSTAT -t file $DIR/$tdir/tgt_dir/b ||
23598                 error "missing file(a) after rename"
23599
23600         diff /etc/hosts $DIR/$tdir/tgt_dir/b ||
23601                 error "diff after rename"
23602 }
23603
23604 test_310a() {
23605         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 4 MDTs"
23606         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23607
23608         local remote_file=$DIR/$tdir/tgt_dir/b
23609
23610         mkdir -p $DIR/$tdir
23611
23612         prepare_remote_file || error "prepare remote file failed"
23613
23614         #open-unlink file
23615         $OPENUNLINK $remote_file $remote_file ||
23616                 error "openunlink $remote_file failed"
23617         $CHECKSTAT -a $remote_file || error "$remote_file exists"
23618 }
23619 run_test 310a "open unlink remote file"
23620
23621 test_310b() {
23622         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 4 MDTs"
23623         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23624
23625         local remote_file=$DIR/$tdir/tgt_dir/b
23626
23627         mkdir -p $DIR/$tdir
23628
23629         prepare_remote_file || error "prepare remote file failed"
23630
23631         ln $remote_file $DIR/$tfile || error "link failed for remote file"
23632         $MULTIOP $DIR/$tfile Ouc || error "mulitop failed"
23633         $CHECKSTAT -t file $remote_file || error "check file failed"
23634 }
23635 run_test 310b "unlink remote file with multiple links while open"
23636
23637 test_310c() {
23638         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23639         [[ $MDSCOUNT -lt 4 ]] && skip_env "needs >= 4 MDTs"
23640
23641         local remote_file=$DIR/$tdir/tgt_dir/b
23642
23643         mkdir -p $DIR/$tdir
23644
23645         prepare_remote_file || error "prepare remote file failed"
23646
23647         ln $remote_file $DIR/$tfile || error "link failed for remote file"
23648         multiop_bg_pause $remote_file O_uc ||
23649                         error "mulitop failed for remote file"
23650         MULTIPID=$!
23651         $MULTIOP $DIR/$tfile Ouc
23652         kill -USR1 $MULTIPID
23653         wait $MULTIPID
23654 }
23655 run_test 310c "open-unlink remote file with multiple links"
23656
23657 #LU-4825
23658 test_311() {
23659         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23660         [ $OSTCOUNT -lt 2 ] && skip "needs >= 2 OSTs"
23661         [ $MDS1_VERSION -lt $(version_code 2.8.54) ] &&
23662                 skip "lustre < 2.8.54 does not contain LU-4825 fix"
23663         remote_mds_nodsh && skip "remote MDS with nodsh"
23664
23665         local old_iused=$($LFS df -i | awk '/OST0000/ { print $3; exit; }')
23666         local mdts=$(comma_list $(mdts_nodes))
23667
23668         mkdir -p $DIR/$tdir
23669         $LFS setstripe -i 0 -c 1 $DIR/$tdir
23670         createmany -o $DIR/$tdir/$tfile. 1000
23671
23672         # statfs data is not real time, let's just calculate it
23673         old_iused=$((old_iused + 1000))
23674
23675         local count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
23676                         osp.*OST0000*MDT0000.create_count")
23677         local max_count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
23678                                 osp.*OST0000*MDT0000.max_create_count")
23679         do_nodes $mdts "$LCTL set_param -n osp.*OST0000*.max_create_count=0"
23680
23681         $LFS setstripe -i 0 $DIR/$tdir/$tfile || error "setstripe failed"
23682         local index=$($LFS getstripe -i $DIR/$tdir/$tfile)
23683         [ $index -ne 0 ] || error "$tfile stripe index is 0"
23684
23685         unlinkmany $DIR/$tdir/$tfile. 1000
23686
23687         do_nodes $mdts "$LCTL set_param -n \
23688                         osp.*OST0000*.max_create_count=$max_count"
23689         [ $MDS1_VERSION -lt $(version_code 2.12.51) ] &&
23690                 do_nodes $mdts "$LCTL set_param -n \
23691                                 osp.*OST0000*.create_count=$count"
23692         do_nodes $mdts "$LCTL get_param osp.*OST0000*.create_count" |
23693                         grep "=0" && error "create_count is zero"
23694
23695         local new_iused
23696         for i in $(seq 120); do
23697                 new_iused=$($LFS df -i | awk '/OST0000/ { print $3; exit; }')
23698                 # system may be too busy to destroy all objs in time, use
23699                 # a somewhat small value to not fail autotest
23700                 [ $((old_iused - new_iused)) -gt 400 ] && break
23701                 sleep 1
23702         done
23703
23704         echo "waited $i sec, old Iused $old_iused, new Iused $new_iused"
23705         [ $((old_iused - new_iused)) -gt 400 ] ||
23706                 error "objs not destroyed after unlink"
23707 }
23708 run_test 311 "disable OSP precreate, and unlink should destroy objs"
23709
23710 zfs_oid_to_objid()
23711 {
23712         local ost=$1
23713         local objid=$2
23714
23715         local vdevdir=$(dirname $(facet_vdevice $ost))
23716         local cmd="$ZDB -e -p $vdevdir -ddddd $(facet_device $ost)"
23717         local zfs_zapid=$(do_facet $ost $cmd |
23718                           grep -w "/O/0/d$((objid%32))" -C 5 |
23719                           awk '/Object/{getline; print $1}')
23720         local zfs_objid=$(do_facet $ost $cmd $zfs_zapid |
23721                           awk "/$objid = /"'{printf $3}')
23722
23723         echo $zfs_objid
23724 }
23725
23726 zfs_object_blksz() {
23727         local ost=$1
23728         local objid=$2
23729
23730         local vdevdir=$(dirname $(facet_vdevice $ost))
23731         local cmd="$ZDB -e -p $vdevdir -dddd $(facet_device $ost)"
23732         local blksz=$(do_facet $ost $cmd $objid |
23733                       awk '/dblk/{getline; printf $4}')
23734
23735         case "${blksz: -1}" in
23736                 k|K) blksz=$((${blksz:0:$((${#blksz} - 1))}*1024)) ;;
23737                 m|M) blksz=$((${blksz:0:$((${#blksz} - 1))}*1024*1024)) ;;
23738                 *) ;;
23739         esac
23740
23741         echo $blksz
23742 }
23743
23744 test_312() { # LU-4856
23745         remote_ost_nodsh && skip "remote OST with nodsh"
23746         [ "$ost1_FSTYPE" = "zfs" ] ||
23747                 skip_env "the test only applies to zfs"
23748
23749         local max_blksz=$(do_facet ost1 \
23750                           $ZFS get -p recordsize $(facet_device ost1) |
23751                           awk '!/VALUE/{print $3}')
23752
23753         # to make life a little bit easier
23754         $LFS mkdir -c 1 -i 0 $DIR/$tdir
23755         $LFS setstripe -c 1 -i 0 $DIR/$tdir
23756
23757         local tf=$DIR/$tdir/$tfile
23758         touch $tf
23759         local oid=$($LFS getstripe $tf | awk '/obdidx/{getline; print $2}')
23760
23761         # Get ZFS object id
23762         local zfs_objid=$(zfs_oid_to_objid ost1 $oid)
23763         # block size change by sequential overwrite
23764         local bs
23765
23766         for ((bs=$PAGE_SIZE; bs <= max_blksz; bs *= 4)) ; do
23767                 dd if=/dev/zero of=$tf bs=$bs count=1 oflag=sync conv=notrunc
23768
23769                 local blksz=$(zfs_object_blksz ost1 $zfs_objid)
23770                 [ $blksz -eq $bs ] || error "blksz error: $blksz, expected: $bs"
23771         done
23772         rm -f $tf
23773
23774         # block size change by sequential append write
23775         dd if=/dev/zero of=$tf bs=$PAGE_SIZE count=1 oflag=sync conv=notrunc
23776         oid=$($LFS getstripe $tf | awk '/obdidx/{getline; print $2}')
23777         zfs_objid=$(zfs_oid_to_objid ost1 $oid)
23778         local count
23779
23780         for ((count = 1; count < $((max_blksz / PAGE_SIZE)); count *= 2)); do
23781                 dd if=/dev/zero of=$tf bs=$PAGE_SIZE count=$count seek=$count \
23782                         oflag=sync conv=notrunc
23783
23784                 blksz=$(zfs_object_blksz ost1 $zfs_objid)
23785                 [ $blksz -eq $((2 * count * PAGE_SIZE)) ] ||
23786                         error "blksz error, actual $blksz, " \
23787                                 "expected: 2 * $count * $PAGE_SIZE"
23788         done
23789         rm -f $tf
23790
23791         # random write
23792         touch $tf
23793         oid=$($LFS getstripe $tf | awk '/obdidx/{getline; print $2}')
23794         zfs_objid=$(zfs_oid_to_objid ost1 $oid)
23795
23796         dd if=/dev/zero of=$tf bs=1K count=1 oflag=sync conv=notrunc
23797         blksz=$(zfs_object_blksz ost1 $zfs_objid)
23798         [ $blksz -eq $PAGE_SIZE ] ||
23799                 error "blksz error: $blksz, expected: $PAGE_SIZE"
23800
23801         dd if=/dev/zero of=$tf bs=64K count=1 oflag=sync conv=notrunc seek=128
23802         blksz=$(zfs_object_blksz ost1 $zfs_objid)
23803         [ $blksz -eq 65536 ] || error "blksz error: $blksz, expected: 64k"
23804
23805         dd if=/dev/zero of=$tf bs=1M count=1 oflag=sync conv=notrunc
23806         blksz=$(zfs_object_blksz ost1 $zfs_objid)
23807         [ $blksz -eq 65536 ] || error "rewrite error: $blksz, expected: 64k"
23808 }
23809 run_test 312 "make sure ZFS adjusts its block size by write pattern"
23810
23811 test_313() {
23812         remote_ost_nodsh && skip "remote OST with nodsh"
23813
23814         local file=$DIR/$tfile
23815
23816         rm -f $file
23817         $LFS setstripe -c 1 -i 0 $file || error "setstripe failed"
23818
23819         # define OBD_FAIL_TGT_RCVD_EIO           0x720
23820         do_facet ost1 "$LCTL set_param fail_loc=0x720"
23821         dd if=/dev/zero of=$file bs=$PAGE_SIZE oflag=direct count=1 &&
23822                 error "write should failed"
23823         do_facet ost1 "$LCTL set_param fail_loc=0"
23824         rm -f $file
23825 }
23826 run_test 313 "io should fail after last_rcvd update fail"
23827
23828 test_314() {
23829         [ $OSTCOUNT -lt 2 ] && skip "needs >= 2 OSTs"
23830
23831         $LFS setstripe -c 2 -i 0 $DIR/$tfile || error "setstripe failed"
23832         do_facet ost1 "$LCTL set_param fail_loc=0x720"
23833         rm -f $DIR/$tfile
23834         wait_delete_completed
23835         do_facet ost1 "$LCTL set_param fail_loc=0"
23836 }
23837 run_test 314 "OSP shouldn't fail after last_rcvd update failure"
23838
23839 test_315() { # LU-618
23840         [ -f /proc/$$/io ] || skip_env "no IO accounting in kernel"
23841
23842         local file=$DIR/$tfile
23843         rm -f $file
23844
23845         $MULTIOP $file oO_CREAT:O_DIRECT:O_RDWR:w4063232c ||
23846                 error "multiop file write failed"
23847         $MULTIOP $file oO_RDONLY:r4063232_c &
23848         PID=$!
23849
23850         sleep 2
23851
23852         local rbytes=$(awk '/read_bytes/ { print $2 }' /proc/$PID/io)
23853         kill -USR1 $PID
23854
23855         [ $rbytes -gt 4000000 ] || error "read is not accounted ($rbytes)"
23856         rm -f $file
23857 }
23858 run_test 315 "read should be accounted"
23859
23860 test_316() {
23861         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
23862         large_xattr_enabled || skip_env "ea_inode feature disabled"
23863
23864         rm -rf $DIR/$tdir/d
23865         mkdir -p $DIR/$tdir/d
23866         chown nobody $DIR/$tdir/d
23867         touch $DIR/$tdir/d/file
23868
23869         $LFS mv -m1 $DIR/$tdir/d || error "lfs mv failed"
23870 }
23871 run_test 316 "lfs mv"
23872
23873 test_317() {
23874         [ $MDS1_VERSION -lt $(version_code 2.11.53) ] &&
23875                 skip "Need MDS version at least 2.11.53"
23876         if [ "$ost1_FSTYPE" == "zfs" ]; then
23877                 skip "LU-10370: no implementation for ZFS"
23878         fi
23879
23880         local trunc_sz
23881         local grant_blk_size
23882
23883         grant_blk_size=$($LCTL get_param osc.$FSNAME*.import |
23884                         awk '/grant_block_size:/ { print $2; exit; }')
23885         #
23886         # Create File of size 5M. Truncate it to below size's and verify
23887         # blocks count.
23888         #
23889         dd if=/dev/zero of=$DIR/$tfile bs=5M count=1 conv=fsync ||
23890                 error "Create file $DIR/$tfile failed"
23891         stack_trap "rm -f $DIR/$tfile" EXIT
23892
23893         for trunc_sz in 2097152 4097 4000 509 0; do
23894                 $TRUNCATE $DIR/$tfile $trunc_sz ||
23895                         error "truncate $tfile to $trunc_sz failed"
23896                 local sz=$(stat --format=%s $DIR/$tfile)
23897                 local blk=$(stat --format=%b $DIR/$tfile)
23898                 local trunc_blk=$((((trunc_sz + (grant_blk_size - 1) ) /
23899                                      grant_blk_size) * 8))
23900
23901                 if [[ $blk -ne $trunc_blk ]]; then
23902                         $(which stat) $DIR/$tfile
23903                         error "Expected Block $trunc_blk got $blk for $tfile"
23904                 fi
23905
23906                 $CHECKSTAT -s $trunc_sz $DIR/$tfile ||
23907                         error "Expected Size $trunc_sz got $sz for $tfile"
23908         done
23909
23910         #
23911         # sparse file test
23912         # Create file with a hole and write actual 65536 bytes which aligned
23913         # with 4K and 64K PAGE_SIZE. Block count must be 128.
23914         #
23915         local bs=65536
23916         dd if=/dev/zero of=$DIR/$tfile bs=$bs count=1 seek=5 conv=fsync ||
23917                 error "Create file : $DIR/$tfile"
23918
23919         #
23920         # Truncate to size $trunc_sz bytes. Strip tail blocks and leave only 8
23921         # blocks. The block count must drop to 8.
23922         #
23923         trunc_sz=$(($(stat --format=%s $DIR/$tfile) - \
23924                 ((bs - grant_blk_size) + 1)))
23925         $TRUNCATE $DIR/$tfile $trunc_sz ||
23926                 error "truncate $tfile to $trunc_sz failed"
23927
23928         local trunc_bsz=$((grant_blk_size / $(stat --format=%B $DIR/$tfile)))
23929         sz=$(stat --format=%s $DIR/$tfile)
23930         blk=$(stat --format=%b $DIR/$tfile)
23931
23932         if [[ $blk -ne $trunc_bsz ]]; then
23933                 $(which stat) $DIR/$tfile
23934                 error "Expected Block $trunc_bsz got $blk for $tfile"
23935         fi
23936
23937         $CHECKSTAT -s $trunc_sz $DIR/$tfile ||
23938                 error "Expected Size $trunc_sz got $sz for $tfile"
23939 }
23940 run_test 317 "Verify blocks get correctly update after truncate"
23941
23942 test_318() {
23943         local llite_name="llite.$($LFS getname $MOUNT | awk '{print $1}')"
23944         local old_max_active=$($LCTL get_param -n \
23945                             ${llite_name}.max_read_ahead_async_active \
23946                             2>/dev/null)
23947
23948         $LCTL set_param llite.*.max_read_ahead_async_active=256
23949         local max_active=$($LCTL get_param -n \
23950                            ${llite_name}.max_read_ahead_async_active \
23951                            2>/dev/null)
23952         [ $max_active -ne 256 ] && error "expected 256 but got $max_active"
23953
23954         $LCTL set_param llite.*.max_read_ahead_async_active=0 ||
23955                 error "set max_read_ahead_async_active should succeed"
23956
23957         $LCTL set_param llite.*.max_read_ahead_async_active=512
23958         max_active=$($LCTL get_param -n \
23959                      ${llite_name}.max_read_ahead_async_active 2>/dev/null)
23960         [ $max_active -eq 512 ] || error "expected 512 but got $max_active"
23961
23962         # restore @max_active
23963         [ $old_max_active -ne 0 ] && $LCTL set_param \
23964                 llite.*.max_read_ahead_async_active=$old_max_active
23965
23966         local old_threshold=$($LCTL get_param -n \
23967                 ${llite_name}.read_ahead_async_file_threshold_mb 2>/dev/null)
23968         local max_per_file_mb=$($LCTL get_param -n \
23969                 ${llite_name}.max_read_ahead_per_file_mb 2>/dev/null)
23970
23971         local invalid=$(($max_per_file_mb + 1))
23972         $LCTL set_param \
23973                 llite.*.read_ahead_async_file_threshold_mb=$invalid\
23974                         && error "set $invalid should fail"
23975
23976         local valid=$(($invalid - 1))
23977         $LCTL set_param \
23978                 llite.*.read_ahead_async_file_threshold_mb=$valid ||
23979                         error "set $valid should succeed"
23980         local threshold=$($LCTL get_param -n \
23981                 ${llite_name}.read_ahead_async_file_threshold_mb 2>/dev/null)
23982         [ $threshold -eq $valid ] || error \
23983                 "expect threshold $valid got $threshold"
23984         $LCTL set_param \
23985                 llite.*.read_ahead_async_file_threshold_mb=$old_threshold
23986 }
23987 run_test 318 "Verify async readahead tunables"
23988
23989 test_319() {
23990         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return 0
23991
23992         local before=$(date +%s)
23993         local evict
23994         local mdir=$DIR/$tdir
23995         local file=$mdir/xxx
23996
23997         $LFS mkdir -i0 $mdir || error "mkdir $mdir fails"
23998         touch $file
23999
24000 #define OBD_FAIL_LDLM_LOCAL_CANCEL_PAUSE 0x32c
24001         $LCTL set_param fail_val=5 fail_loc=0x8000032c
24002         $LFS mv -m1 $file &
24003
24004         sleep 1
24005         dd if=$file of=/dev/null
24006         wait
24007         evict=$($LCTL get_param mdc.$FSNAME-MDT*.state |
24008           awk -F"[ [,]" '/EVICTED ]$/ { if (mx<$5) {mx=$5;} } END { print mx }')
24009
24010         [ -z "$evict" ] || [[ $evict -le $before ]] || error "eviction happened"
24011 }
24012 run_test 319 "lost lease lock on migrate error"
24013
24014 test_398a() { # LU-4198
24015         local ost1_imp=$(get_osc_import_name client ost1)
24016         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
24017                          cut -d'.' -f2)
24018
24019         $LFS setstripe -c 1 -i 0 $DIR/$tfile
24020         $LCTL set_param ldlm.namespaces.*.lru_size=clear
24021
24022         # request a new lock on client
24023         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
24024
24025         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=direct conv=notrunc
24026         local lock_count=$($LCTL get_param -n \
24027                            ldlm.namespaces.$imp_name.lru_size)
24028         [[ $lock_count -eq 0 ]] || error "lock should be cancelled by direct IO"
24029
24030         $LCTL set_param ldlm.namespaces.*-OST0000-osc-ffff*.lru_size=clear
24031
24032         # no lock cached, should use lockless IO and not enqueue new lock
24033         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=direct conv=notrunc
24034         lock_count=$($LCTL get_param -n \
24035                      ldlm.namespaces.$imp_name.lru_size)
24036         [[ $lock_count -eq 0 ]] || error "no lock should be held by direct IO"
24037 }
24038 run_test 398a "direct IO should cancel lock otherwise lockless"
24039
24040 test_398b() { # LU-4198
24041         which fio || skip_env "no fio installed"
24042         $LFS setstripe -c -1 $DIR/$tfile
24043
24044         local size=12
24045         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$size
24046
24047         local njobs=4
24048         echo "mix direct rw ${size}M to OST0 by fio with $njobs jobs..."
24049         fio --name=rand-rw --rw=randrw --bs=$PAGE_SIZE --direct=1 \
24050                 --numjobs=$njobs --fallocate=none \
24051                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
24052                 --filename=$DIR/$tfile &
24053         bg_pid=$!
24054
24055         echo "mix buffer rw ${size}M to OST0 by fio with $njobs jobs..."
24056         fio --name=rand-rw --rw=randrw --bs=$PAGE_SIZE \
24057                 --numjobs=$njobs --fallocate=none \
24058                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
24059                 --filename=$DIR/$tfile || true
24060         wait $bg_pid
24061
24062         rm -f $DIR/$tfile
24063 }
24064 run_test 398b "DIO and buffer IO race"
24065
24066 test_398c() { # LU-4198
24067         local ost1_imp=$(get_osc_import_name client ost1)
24068         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
24069                          cut -d'.' -f2)
24070
24071         which fio || skip_env "no fio installed"
24072
24073         saved_debug=$($LCTL get_param -n debug)
24074         $LCTL set_param debug=0
24075
24076         local size=$(lctl get_param -n osc.$FSNAME-OST0000*.kbytesavail | head -1)
24077         ((size /= 1024)) # by megabytes
24078         ((size /= 2)) # write half of the OST at most
24079         [ $size -gt 40 ] && size=40 #reduce test time anyway
24080
24081         $LFS setstripe -c 1 $DIR/$tfile
24082
24083         # it seems like ldiskfs reserves more space than necessary if the
24084         # writing blocks are not mapped, so it extends the file firstly
24085         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$size && sync
24086         cancel_lru_locks osc
24087
24088         # clear and verify rpc_stats later
24089         $LCTL set_param osc.${FSNAME}-OST0000-osc-ffff*.rpc_stats=clear
24090
24091         local njobs=4
24092         echo "writing ${size}M to OST0 by fio with $njobs jobs..."
24093         fio --name=rand-write --rw=randwrite --bs=$PAGE_SIZE --direct=1 \
24094                 --numjobs=$njobs --fallocate=none --ioengine=libaio \
24095                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
24096                 --filename=$DIR/$tfile
24097         [ $? -eq 0 ] || error "fio write error"
24098
24099         [ $($LCTL get_param -n ldlm.namespaces.$imp_name.lock_count) -eq 0 ] ||
24100                 error "Locks were requested while doing AIO"
24101
24102         # get the percentage of 1-page I/O
24103         pct=$($LCTL get_param osc.${imp_name}.rpc_stats |
24104                 grep -A 1 'pages per rpc' | grep -v 'pages per rpc' |
24105                 awk '{print $7}')
24106         [ $pct -le 50 ] || error "$pct% of I/O are 1-page"
24107
24108         echo "mix rw ${size}M to OST0 by fio with $njobs jobs..."
24109         fio --name=rand-rw --rw=randrw --bs=$PAGE_SIZE --direct=1 \
24110                 --numjobs=$njobs --fallocate=none --ioengine=libaio \
24111                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
24112                 --filename=$DIR/$tfile
24113         [ $? -eq 0 ] || error "fio mixed read write error"
24114
24115         echo "AIO with large block size ${size}M"
24116         fio --name=rand-rw --rw=randrw --bs=${size}M --direct=1 \
24117                 --numjobs=1 --fallocate=none --ioengine=libaio \
24118                 --iodepth=16 --allow_file_create=0 --size=${size}M \
24119                 --filename=$DIR/$tfile
24120         [ $? -eq 0 ] || error "fio large block size failed"
24121
24122         rm -f $DIR/$tfile
24123         $LCTL set_param debug="$saved_debug"
24124 }
24125 run_test 398c "run fio to test AIO"
24126
24127 test_398d() { #  LU-13846
24128         which aiocp || skip_env "no aiocp installed"
24129         local aio_file=$DIR/$tfile.aio
24130
24131         $LFS setstripe -c -1 -S 1M $DIR/$tfile $aio_file
24132
24133         dd if=/dev/urandom of=$DIR/$tfile bs=1M count=64
24134         aiocp -a $PAGE_SIZE -b 64M -s 64M -f O_DIRECT $DIR/$tfile $aio_file
24135         stack_trap "rm -f $DIR/$tfile $aio_file"
24136
24137         diff $DIR/$tfile $aio_file || error "file diff after aiocp"
24138
24139         # make sure we don't crash and fail properly
24140         aiocp -a 512 -b 64M -s 64M -f O_DIRECT $DIR/$tfile $aio_file &&
24141                 error "aio not aligned with PAGE SIZE should fail"
24142
24143         rm -f $DIR/$tfile $aio_file
24144 }
24145 run_test 398d "run aiocp to verify block size > stripe size"
24146
24147 test_398e() {
24148         dd if=/dev/zero of=$DIR/$tfile bs=1234 count=1
24149         touch $DIR/$tfile.new
24150         dd if=$DIR/$tfile of=$DIR/$tfile.new bs=1M count=1 oflag=direct
24151 }
24152 run_test 398e "O_Direct open cleared by fcntl doesn't cause hang"
24153
24154 test_398f() { #  LU-14687
24155         which aiocp || skip_env "no aiocp installed"
24156         local aio_file=$DIR/$tfile.aio
24157
24158         $LFS setstripe -c -1 -S 1M $DIR/$tfile $aio_file
24159
24160         dd if=/dev/zero of=$DIR/$tfile bs=1M count=64
24161         stack_trap "rm -f $DIR/$tfile $aio_file"
24162
24163         #define OBD_FAIL_LLITE_PAGE_ALLOC 0x1418
24164         $LCTL set_param fail_loc=0x1418
24165         # make sure we don't crash and fail properly
24166         aiocp -b 64M -s 64M -f O_DIRECT $DIR/$tfile $aio_file &&
24167                 error "aio with page allocation failure succeeded"
24168         $LCTL set_param fail_loc=0
24169         diff $DIR/$tfile $aio_file
24170         [[ $? != 0 ]] || error "no diff after failed aiocp"
24171 }
24172 run_test 398f "verify aio handles ll_direct_rw_pages errors correctly"
24173
24174 # NB: To get the parallel DIO behavior in LU-13798, there must be > 1
24175 # stripe and i/o size must be > stripe size
24176 # Old style synchronous DIO waits after submitting each chunk, resulting in a
24177 # single RPC in flight.  This test shows async DIO submission is working by
24178 # showing multiple RPCs in flight.
24179 test_398g() { #  LU-13798
24180         $LFS setstripe -o 0,0 -S 1M $DIR/$tfile
24181
24182         # We need to do some i/o first to acquire enough grant to put our RPCs
24183         # in flight; otherwise a new connection may not have enough grant
24184         # available
24185         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=1 oflag=direct ||
24186                 error "parallel dio failed"
24187         stack_trap "rm -f $DIR/$tfile"
24188
24189         # Reduce RPC size to 1M to avoid combination in to larger RPCs
24190         local pages_per_rpc=$($LCTL get_param osc.*-OST0000-*.max_pages_per_rpc)
24191         $LCTL set_param osc.*-OST0000-*.max_pages_per_rpc=1M
24192         stack_trap "$LCTL set_param -n $pages_per_rpc"
24193
24194         # Recreate file so it's empty
24195         rm -f $DIR/$tfile
24196         $LFS setstripe -o 0,0 -S 1M $DIR/$tfile
24197         #Pause rpc completion to guarantee we see multiple rpcs in flight
24198         #define OBD_FAIL_OST_BRW_PAUSE_BULK
24199         do_facet ost1 $LCTL set_param fail_loc=0x214 fail_val=2
24200         stack_trap "do_facet ost1 $LCTL set_param fail_loc=0"
24201
24202         # Clear rpc stats
24203         $LCTL set_param osc.*.rpc_stats=c
24204
24205         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=1 oflag=direct ||
24206                 error "parallel dio failed"
24207         stack_trap "rm -f $DIR/$tfile"
24208
24209         $LCTL get_param osc.*-OST0000-*.rpc_stats
24210         pct=$($LCTL get_param osc.*-OST0000-*.rpc_stats |
24211                 grep -A 8 'rpcs in flight' | grep -v 'rpcs in flight' |
24212                 grep "8:" | awk '{print $8}')
24213         # We look at the "8 rpcs in flight" field, and verify A) it is present
24214         # and B) it includes all RPCs.  This proves we had 8 RPCs in flight,
24215         # as expected for an 8M DIO to a file with 1M stripes.
24216         [ $pct -eq 100 ] || error "we should see 8 RPCs in flight"
24217
24218         # Verify turning off parallel dio works as expected
24219         # Clear rpc stats
24220         $LCTL set_param osc.*.rpc_stats=c
24221         $LCTL set_param llite.*.parallel_dio=0
24222         stack_trap '$LCTL set_param llite.*.parallel_dio=1'
24223
24224         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=1 oflag=direct ||
24225                 error "dio with parallel dio disabled failed"
24226
24227         # Ideally, we would see only one RPC in flight here, but there is an
24228         # unavoidable race between i/o completion and RPC in flight counting,
24229         # so while only 1 i/o is in flight at a time, the RPC in flight counter
24230         # will sometimes exceed 1 (3 or 4 is not rare on VM testing).
24231         # So instead we just verify it's always < 8.
24232         $LCTL get_param osc.*-OST0000-*.rpc_stats
24233         ret=$($LCTL get_param osc.*-OST0000-*.rpc_stats |
24234                 grep -A 8 'rpcs in flight' | grep -v 'rpcs in flight' |
24235                 grep '^$' -B1 | grep . | awk '{print $1}')
24236         [ $ret != "8:" ] ||
24237                 error "we should see fewer than 8 RPCs in flight (saw $ret)"
24238 }
24239 run_test 398g "verify parallel dio async RPC submission"
24240
24241 test_398h() { #  LU-13798
24242         local dio_file=$DIR/$tfile.dio
24243
24244         $LFS setstripe -C 2 -S 1M $DIR/$tfile $dio_file
24245
24246         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct
24247         stack_trap "rm -f $DIR/$tfile $dio_file"
24248
24249         dd if=$DIR/$tfile of=$dio_file bs=8M count=8 iflag=direct oflag=direct ||
24250                 error "parallel dio failed"
24251         diff $DIR/$tfile $dio_file
24252         [[ $? == 0 ]] || error "file diff after aiocp"
24253 }
24254 run_test 398h "verify correctness of read & write with i/o size >> stripe size"
24255
24256 test_398i() { #  LU-13798
24257         local dio_file=$DIR/$tfile.dio
24258
24259         $LFS setstripe -C 2 -S 1M $DIR/$tfile $dio_file
24260
24261         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct
24262         stack_trap "rm -f $DIR/$tfile $dio_file"
24263
24264         #define OBD_FAIL_LLITE_PAGE_ALLOC 0x1418
24265         $LCTL set_param fail_loc=0x1418
24266         # make sure we don't crash and fail properly
24267         dd if=$DIR/$tfile of=$dio_file bs=8M count=8 iflag=direct oflag=direct &&
24268                 error "parallel dio page allocation failure succeeded"
24269         diff $DIR/$tfile $dio_file
24270         [[ $? != 0 ]] || error "no diff after failed aiocp"
24271 }
24272 run_test 398i "verify parallel dio handles ll_direct_rw_pages errors correctly"
24273
24274 test_398j() { #  LU-13798
24275         # Stripe size > RPC size but less than i/o size tests split across
24276         # stripes and RPCs for individual i/o op
24277         $LFS setstripe -o 0,0 -S 4M $DIR/$tfile $DIR/$tfile.2
24278
24279         # Reduce RPC size to 1M to guarantee split to multiple RPCs per stripe
24280         local pages_per_rpc=$($LCTL get_param osc.*-OST0000-*.max_pages_per_rpc)
24281         $LCTL set_param osc.*-OST0000-*.max_pages_per_rpc=1M
24282         stack_trap "$LCTL set_param -n $pages_per_rpc"
24283
24284         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct ||
24285                 error "parallel dio write failed"
24286         stack_trap "rm -f $DIR/$tfile $DIR/$tfile.2"
24287
24288         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 iflag=direct ||
24289                 error "parallel dio read failed"
24290         diff $DIR/$tfile $DIR/$tfile.2
24291         [[ $? == 0 ]] || error "file diff after parallel dio read"
24292 }
24293 run_test 398j "test parallel dio where stripe size > rpc_size"
24294
24295 test_398k() { #  LU-13798
24296         wait_delete_completed
24297         wait_mds_ost_sync
24298
24299         # 4 stripe file; we will cause out of space on OST0
24300         $LFS setstripe -o 0,1,0,1 -S 1M $DIR/$tfile
24301
24302         # Fill OST0 (if it's not too large)
24303         ORIGFREE=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
24304                    head -n1)
24305         if [[ $ORIGFREE -gt $MAXFREE ]]; then
24306                 skip "$ORIGFREE > $MAXFREE skipping out-of-space test on OST0"
24307         fi
24308         $LFS setstripe -i 0 -c 1 $DIR/$tfile.1
24309         dd if=/dev/zero of=$DIR/$tfile.1 bs=1024 count=$MAXFREE &&
24310                 error "dd should fill OST0"
24311         stack_trap "rm -f $DIR/$tfile.1"
24312
24313         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct
24314         err=$?
24315
24316         ls -la $DIR/$tfile
24317         $CHECKSTAT -t file -s 0 $DIR/$tfile ||
24318                 error "file is not 0 bytes in size"
24319
24320         # dd above should not succeed, but don't error until here so we can
24321         # get debug info above
24322         [[ $err != 0 ]] ||
24323                 error "parallel dio write with enospc succeeded"
24324         stack_trap "rm -f $DIR/$tfile"
24325 }
24326 run_test 398k "test enospc on first stripe"
24327
24328 test_398l() { #  LU-13798
24329         wait_delete_completed
24330         wait_mds_ost_sync
24331
24332         # 4 stripe file; we will cause out of space on OST0
24333         # Note the 1M stripe size and the > 1M i/o size mean this ENOSPC
24334         # happens on the second i/o chunk we issue
24335         $LFS setstripe -o 1,0,1,0 -S 1M $DIR/$tfile $DIR/$tfile.2
24336
24337         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=2 oflag=direct
24338         stack_trap "rm -f $DIR/$tfile"
24339
24340         # Fill OST0 (if it's not too large)
24341         ORIGFREE=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
24342                    head -n1)
24343         if [[ $ORIGFREE -gt $MAXFREE ]]; then
24344                 skip "$ORIGFREE > $MAXFREE skipping out-of-space test on OST0"
24345         fi
24346         $LFS setstripe -i 0 -c 1 $DIR/$tfile.1
24347         dd if=/dev/zero of=$DIR/$tfile.1 bs=1024 count=$MAXFREE &&
24348                 error "dd should fill OST0"
24349         stack_trap "rm -f $DIR/$tfile.1"
24350
24351         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 oflag=direct
24352         err=$?
24353         stack_trap "rm -f $DIR/$tfile.2"
24354
24355         # Check that short write completed as expected
24356         ls -la $DIR/$tfile.2
24357         $CHECKSTAT -t file -s 1048576 $DIR/$tfile.2 ||
24358                 error "file is not 1M in size"
24359
24360         # dd above should not succeed, but don't error until here so we can
24361         # get debug info above
24362         [[ $err != 0 ]] ||
24363                 error "parallel dio write with enospc succeeded"
24364
24365         # Truncate source file to same length as output file and diff them
24366         $TRUNCATE $DIR/$tfile 1048576
24367         diff $DIR/$tfile $DIR/$tfile.2
24368         [[ $? == 0 ]] || error "data incorrect after short write"
24369 }
24370 run_test 398l "test enospc on intermediate stripe/RPC"
24371
24372 test_398m() { #  LU-13798
24373         $LFS setstripe -o 0,1,0,1 -S 1M $DIR/$tfile
24374
24375         # Set up failure on OST0, the first stripe:
24376         #define OBD_FAIL_OST_BRW_WRITE_BULK     0x20e
24377         #NB: Fail val is ost # + 1, because we cannot use cfs_fail_val = 0
24378         # So this fail_val specifies OST0
24379         do_facet ost1 $LCTL set_param fail_loc=0x20e fail_val=1
24380         stack_trap "do_facet ost1 $LCTL set_param fail_loc=0"
24381
24382         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct &&
24383                 error "parallel dio write with failure on first stripe succeeded"
24384         stack_trap "rm -f $DIR/$tfile"
24385         do_facet ost1 $LCTL set_param fail_loc=0 fail_val=0
24386
24387         # Place data in file for read
24388         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct ||
24389                 error "parallel dio write failed"
24390
24391         # Fail read on OST0, first stripe
24392         #define OBD_FAIL_OST_BRW_READ_BULK       0x20f
24393         do_facet ost1 $LCTL set_param fail_loc=0x20f fail_val=1
24394         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 iflag=direct &&
24395                 error "parallel dio read with error on first stripe succeeded"
24396         rm -f $DIR/$tfile.2
24397         do_facet ost1 $LCTL set_param fail_loc=0 fail_val=0
24398
24399         # Switch to testing on OST1, second stripe
24400         # Clear file contents, maintain striping
24401         echo > $DIR/$tfile
24402         # Set up failure on OST1, second stripe:
24403         do_facet ost1 $LCTL set_param fail_loc=0x20e fail_val=2
24404         stack_trap "do_facet ost1 $LCTL set_param fail_loc=0"
24405
24406         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct &&
24407                 error "parallel dio write with failure on first stripe succeeded"
24408         stack_trap "rm -f $DIR/$tfile"
24409         do_facet ost1 $LCTL set_param fail_loc=0 fail_val=0
24410
24411         # Place data in file for read
24412         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct ||
24413                 error "parallel dio write failed"
24414
24415         # Fail read on OST1, second stripe
24416         #define OBD_FAIL_OST_BRW_READ_BULK       0x20f
24417         do_facet ost2 $LCTL set_param fail_loc=0x20f fail_val=2
24418         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 iflag=direct &&
24419                 error "parallel dio read with error on first stripe succeeded"
24420         rm -f $DIR/$tfile.2
24421         do_facet ost2 $LCTL set_param fail_loc=0 fail_val=0
24422 }
24423 run_test 398m "test RPC failures with parallel dio"
24424
24425 # Parallel submission of DIO should not cause problems for append, but it's
24426 # important to verify.
24427 test_398n() { #  LU-13798
24428         $LFS setstripe -C 2 -S 1M $DIR/$tfile
24429
24430         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 ||
24431                 error "dd to create source file failed"
24432         stack_trap "rm -f $DIR/$tfile"
24433
24434         dd if=$DIR/$tfile of=$DIR/$tfile.1 bs=8M count=8 oflag=direct oflag=append ||
24435                 error "parallel dio write with failure on second stripe succeeded"
24436         stack_trap "rm -f $DIR/$tfile $DIR/$tfile.1"
24437         diff $DIR/$tfile $DIR/$tfile.1
24438         [[ $? == 0 ]] || error "data incorrect after append"
24439
24440 }
24441 run_test 398n "test append with parallel DIO"
24442
24443 test_fake_rw() {
24444         local read_write=$1
24445         if [ "$read_write" = "write" ]; then
24446                 local dd_cmd="dd if=/dev/zero of=$DIR/$tfile"
24447         elif [ "$read_write" = "read" ]; then
24448                 local dd_cmd="dd of=/dev/null if=$DIR/$tfile"
24449         else
24450                 error "argument error"
24451         fi
24452
24453         # turn off debug for performance testing
24454         local saved_debug=$($LCTL get_param -n debug)
24455         $LCTL set_param debug=0
24456
24457         $LFS setstripe -c 1 -i 0 $DIR/$tfile
24458
24459         # get ost1 size - $FSNAME-OST0000
24460         local ost1_avail_size=$($LFS df $DIR | awk /${ost1_svc}/'{ print $4 }')
24461         local blocks=$((ost1_avail_size/2/1024)) # half avail space by megabytes
24462         [ $blocks -gt 1000 ] && blocks=1000 # 1G in maximum
24463
24464         if [ "$read_write" = "read" ]; then
24465                 $TRUNCATE $DIR/$tfile $(expr 1048576 \* $blocks)
24466         fi
24467
24468         local start_time=$(date +%s.%N)
24469         $dd_cmd bs=1M count=$blocks oflag=sync ||
24470                 error "real dd $read_write error"
24471         local duration=$(bc <<< "$(date +%s.%N) - $start_time")
24472
24473         if [ "$read_write" = "write" ]; then
24474                 rm -f $DIR/$tfile
24475         fi
24476
24477         # define OBD_FAIL_OST_FAKE_RW           0x238
24478         do_facet ost1 $LCTL set_param fail_loc=0x238
24479
24480         local start_time=$(date +%s.%N)
24481         $dd_cmd bs=1M count=$blocks oflag=sync ||
24482                 error "fake dd $read_write error"
24483         local duration_fake=$(bc <<< "$(date +%s.%N) - $start_time")
24484
24485         if [ "$read_write" = "write" ]; then
24486                 # verify file size
24487                 cancel_lru_locks osc
24488                 $CHECKSTAT -t file -s $((blocks * 1024 * 1024)) $DIR/$tfile ||
24489                         error "$tfile size not $blocks MB"
24490         fi
24491         do_facet ost1 $LCTL set_param fail_loc=0
24492
24493         echo "fake $read_write $duration_fake vs. normal $read_write" \
24494                 "$duration in seconds"
24495         [ $(bc <<< "$duration_fake < $duration") -eq 1 ] ||
24496                 error_not_in_vm "fake write is slower"
24497
24498         $LCTL set_param -n debug="$saved_debug"
24499         rm -f $DIR/$tfile
24500 }
24501 test_399a() { # LU-7655 for OST fake write
24502         remote_ost_nodsh && skip "remote OST with nodsh"
24503
24504         test_fake_rw write
24505 }
24506 run_test 399a "fake write should not be slower than normal write"
24507
24508 test_399b() { # LU-8726 for OST fake read
24509         remote_ost_nodsh && skip "remote OST with nodsh"
24510         if [ "$ost1_FSTYPE" != "ldiskfs" ]; then
24511                 skip_env "ldiskfs only test"
24512         fi
24513
24514         test_fake_rw read
24515 }
24516 run_test 399b "fake read should not be slower than normal read"
24517
24518 test_400a() { # LU-1606, was conf-sanity test_74
24519         if ! which $CC > /dev/null 2>&1; then
24520                 skip_env "$CC is not installed"
24521         fi
24522
24523         local extra_flags=''
24524         local out=$TMP/$tfile
24525         local prefix=/usr/include/lustre
24526         local prog
24527
24528         # Oleg removes c files in his test rig so test if any c files exist
24529         [ -z "$(ls -A $LUSTRE_TESTS_API_DIR)" ] && \
24530                 skip_env "Needed c test files are missing"
24531
24532         if ! [[ -d $prefix ]]; then
24533                 # Assume we're running in tree and fixup the include path.
24534                 extra_flags+=" -I$LUSTRE/../lnet/include/uapi -I$LUSTRE/include/uapi -I$LUSTRE/include"
24535                 extra_flags+=" -L$LUSTRE/utils/.lib"
24536         fi
24537
24538         for prog in $LUSTRE_TESTS_API_DIR/*.c; do
24539                 $CC -Wall -Werror -std=c99 $extra_flags -o $out $prog -llustreapi ||
24540                         error "client api broken"
24541         done
24542         rm -f $out
24543 }
24544 run_test 400a "Lustre client api program can compile and link"
24545
24546 test_400b() { # LU-1606, LU-5011
24547         local header
24548         local out=$TMP/$tfile
24549         local prefix=/usr/include/linux/lustre
24550
24551         # We use a hard coded prefix so that this test will not fail
24552         # when run in tree. There are headers in lustre/include/lustre/
24553         # that are not packaged (like lustre_idl.h) and have more
24554         # complicated include dependencies (like config.h and lnet/types.h).
24555         # Since this test about correct packaging we just skip them when
24556         # they don't exist (see below) rather than try to fixup cppflags.
24557
24558         if ! which $CC > /dev/null 2>&1; then
24559                 skip_env "$CC is not installed"
24560         fi
24561
24562         for header in $prefix/*.h; do
24563                 if ! [[ -f "$header" ]]; then
24564                         continue
24565                 fi
24566
24567                 if [[ "$(basename $header)" == lustre_ioctl.h ]]; then
24568                         continue # lustre_ioctl.h is internal header
24569                 fi
24570
24571                 $CC -Wall -Werror -std=c99 -include $header -c -x c /dev/null -o $out ||
24572                         error "cannot compile '$header'"
24573         done
24574         rm -f $out
24575 }
24576 run_test 400b "packaged headers can be compiled"
24577
24578 test_401a() { #LU-7437
24579         local printf_arg=$(find -printf 2>&1 | grep "unrecognized:")
24580         [ -n "$printf_arg" ] && skip_env "find does not support -printf"
24581
24582         #count the number of parameters by "list_param -R"
24583         local params=$($LCTL list_param -R '*' 2>/dev/null | wc -l)
24584         #count the number of parameters by listing proc files
24585         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
24586         echo "proc_dirs='$proc_dirs'"
24587         [ -n "$proc_dirs" ] || error "no proc_dirs on $HOSTNAME"
24588         local procs=$(find -L $proc_dirs -mindepth 1 -printf '%P\n' 2>/dev/null|
24589                       sort -u | wc -l)
24590
24591         [ $params -eq $procs ] ||
24592                 error "found $params parameters vs. $procs proc files"
24593
24594         # test the list_param -D option only returns directories
24595         params=$($LCTL list_param -R -D '*' 2>/dev/null | wc -l)
24596         #count the number of parameters by listing proc directories
24597         procs=$(find -L $proc_dirs -mindepth 1 -type d -printf '%P\n' 2>/dev/null |
24598                 sort -u | wc -l)
24599
24600         [ $params -eq $procs ] ||
24601                 error "found $params parameters vs. $procs proc files"
24602 }
24603 run_test 401a "Verify if 'lctl list_param -R' can list parameters recursively"
24604
24605 test_401b() {
24606         # jobid_var may not allow arbitrary values, so use jobid_name
24607         # if available
24608         if $LCTL list_param jobid_name > /dev/null 2>&1; then
24609                 local testname=jobid_name tmp='testing%p'
24610         else
24611                 local testname=jobid_var tmp=testing
24612         fi
24613
24614         local save=$($LCTL get_param -n $testname)
24615
24616         $LCTL set_param foo=bar $testname=$tmp bar=baz &&
24617                 error "no error returned when setting bad parameters"
24618
24619         local jobid_new=$($LCTL get_param -n foe $testname baz)
24620         [[ "$jobid_new" == "$tmp" ]] || error "jobid tmp $jobid_new != $tmp"
24621
24622         $LCTL set_param -n fog=bam $testname=$save bat=fog
24623         local jobid_old=$($LCTL get_param -n foe $testname bag)
24624         [[ "$jobid_old" == "$save" ]] || error "jobid new $jobid_old != $save"
24625 }
24626 run_test 401b "Verify 'lctl {get,set}_param' continue after error"
24627
24628 test_401c() {
24629         # jobid_var may not allow arbitrary values, so use jobid_name
24630         # if available
24631         if $LCTL list_param jobid_name > /dev/null 2>&1; then
24632                 local testname=jobid_name
24633         else
24634                 local testname=jobid_var
24635         fi
24636
24637         local jobid_var_old=$($LCTL get_param -n $testname)
24638         local jobid_var_new
24639
24640         $LCTL set_param $testname= &&
24641                 error "no error returned for 'set_param a='"
24642
24643         jobid_var_new=$($LCTL get_param -n $testname)
24644         [[ "$jobid_var_old" == "$jobid_var_new" ]] ||
24645                 error "$testname was changed by setting without value"
24646
24647         $LCTL set_param $testname &&
24648                 error "no error returned for 'set_param a'"
24649
24650         jobid_var_new=$($LCTL get_param -n $testname)
24651         [[ "$jobid_var_old" == "$jobid_var_new" ]] ||
24652                 error "$testname was changed by setting without value"
24653 }
24654 run_test 401c "Verify 'lctl set_param' without value fails in either format."
24655
24656 test_401d() {
24657         # jobid_var may not allow arbitrary values, so use jobid_name
24658         # if available
24659         if $LCTL list_param jobid_name > /dev/null 2>&1; then
24660                 local testname=jobid_name new_value='foo=bar%p'
24661         else
24662                 local testname=jobid_var new_valuie=foo=bar
24663         fi
24664
24665         local jobid_var_old=$($LCTL get_param -n $testname)
24666         local jobid_var_new
24667
24668         $LCTL set_param $testname=$new_value ||
24669                 error "'set_param a=b' did not accept a value containing '='"
24670
24671         jobid_var_new=$($LCTL get_param -n $testname)
24672         [[ "$jobid_var_new" == "$new_value" ]] ||
24673                 error "'set_param a=b' failed on a value containing '='"
24674
24675         # Reset the $testname to test the other format
24676         $LCTL set_param $testname=$jobid_var_old
24677         jobid_var_new=$($LCTL get_param -n $testname)
24678         [[ "$jobid_var_new" == "$jobid_var_old" ]] ||
24679                 error "failed to reset $testname"
24680
24681         $LCTL set_param $testname $new_value ||
24682                 error "'set_param a b' did not accept a value containing '='"
24683
24684         jobid_var_new=$($LCTL get_param -n $testname)
24685         [[ "$jobid_var_new" == "$new_value" ]] ||
24686                 error "'set_param a b' failed on a value containing '='"
24687
24688         $LCTL set_param $testname $jobid_var_old
24689         jobid_var_new=$($LCTL get_param -n $testname)
24690         [[ "$jobid_var_new" == "$jobid_var_old" ]] ||
24691                 error "failed to reset $testname"
24692 }
24693 run_test 401d "Verify 'lctl set_param' accepts values containing '='"
24694
24695 test_401e() { # LU-14779
24696         $LCTL list_param -R "ldlm.namespaces.MGC*" ||
24697                 error "lctl list_param MGC* failed"
24698         $LCTL get_param "ldlm.namespaces.MGC*" || error "lctl get_param failed"
24699         $LCTL get_param "ldlm.namespaces.MGC*.lru_size" ||
24700                 error "lctl get_param lru_size failed"
24701 }
24702 run_test 401e "verify 'lctl get_param' works with NID in parameter"
24703
24704 test_402() {
24705         [[ $MDS1_VERSION -ge $(version_code 2.7.66) ]] ||
24706         [[ $MDS1_VERSION -ge $(version_code 2.7.18.4) &&
24707                 $MDS1_VERSION -lt $(version_code 2.7.50) ]] ||
24708         [[ $MDS1_VERSION -ge $(version_code 2.7.2) &&
24709                 $MDS1_VERSION -lt $(version_code 2.7.11) ]] ||
24710                 skip "Need MDS version 2.7.2+ or 2.7.18.4+ or 2.7.66+"
24711         remote_mds_nodsh && skip "remote MDS with nodsh"
24712
24713         $LFS setdirstripe -i 0 $DIR/$tdir || error "setdirstripe -i 0 failed"
24714 #define OBD_FAIL_MDS_FLD_LOOKUP 0x15c
24715         do_facet mds1 "lctl set_param fail_loc=0x8000015c"
24716         touch $DIR/$tdir/$tfile && error "touch should fail with ENOENT" ||
24717                 echo "Touch failed - OK"
24718 }
24719 run_test 402 "Return ENOENT to lod_generate_and_set_lovea"
24720
24721 test_403() {
24722         local file1=$DIR/$tfile.1
24723         local file2=$DIR/$tfile.2
24724         local tfile=$TMP/$tfile
24725
24726         rm -f $file1 $file2 $tfile
24727
24728         touch $file1
24729         ln $file1 $file2
24730
24731         # 30 sec OBD_TIMEOUT in ll_getattr()
24732         # right before populating st_nlink
24733         $LCTL set_param fail_loc=0x80001409
24734         stat -c %h $file1 > $tfile &
24735
24736         # create an alias, drop all locks and reclaim the dentry
24737         < $file2
24738         cancel_lru_locks mdc
24739         cancel_lru_locks osc
24740         sysctl -w vm.drop_caches=2
24741
24742         wait
24743
24744         [ $(cat $tfile) -gt 0 ] || error "wrong nlink count: $(cat $tfile)"
24745
24746         rm -f $tfile $file1 $file2
24747 }
24748 run_test 403 "i_nlink should not drop to zero due to aliasing"
24749
24750 test_404() { # LU-6601
24751         [[ $MDS1_VERSION -ge $(version_code 2.8.53) ]] ||
24752                 skip "Need server version newer than 2.8.52"
24753         remote_mds_nodsh && skip "remote MDS with nodsh"
24754
24755         local mosps=$(do_facet $SINGLEMDS $LCTL dl |
24756                 awk '/osp .*-osc-MDT/ { print $4}')
24757
24758         local osp
24759         for osp in $mosps; do
24760                 echo "Deactivate: " $osp
24761                 do_facet $SINGLEMDS $LCTL --device %$osp deactivate
24762                 local stat=$(do_facet $SINGLEMDS $LCTL dl |
24763                         awk -vp=$osp '$4 == p { print $2 }')
24764                 [ $stat = IN ] || {
24765                         do_facet $SINGLEMDS $LCTL dl | grep -w $osp
24766                         error "deactivate error"
24767                 }
24768                 echo "Activate: " $osp
24769                 do_facet $SINGLEMDS $LCTL --device %$osp activate
24770                 local stat=$(do_facet $SINGLEMDS $LCTL dl |
24771                         awk -vp=$osp '$4 == p { print $2 }')
24772                 [ $stat = UP ] || {
24773                         do_facet $SINGLEMDS $LCTL dl | grep -w $osp
24774                         error "activate error"
24775                 }
24776         done
24777 }
24778 run_test 404 "validate manual {de}activated works properly for OSPs"
24779
24780 test_405() {
24781         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
24782         [ $MDS1_VERSION -lt $(version_code 2.6.92) ] ||
24783                 [ $CLIENT_VERSION -lt $(version_code 2.6.99) ] &&
24784                         skip "Layout swap lock is not supported"
24785
24786         check_swap_layouts_support
24787         check_swap_layout_no_dom $DIR
24788
24789         test_mkdir $DIR/$tdir
24790         swap_lock_test -d $DIR/$tdir ||
24791                 error "One layout swap locked test failed"
24792 }
24793 run_test 405 "Various layout swap lock tests"
24794
24795 test_406() {
24796         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
24797         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
24798         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
24799         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24800         [ $MDS1_VERSION -lt $(version_code 2.8.50) ] &&
24801                 skip "Need MDS version at least 2.8.50"
24802
24803         local def_stripe_size=$($LFS getstripe -S $MOUNT)
24804         local test_pool=$TESTNAME
24805
24806         pool_add $test_pool || error "pool_add failed"
24807         pool_add_targets $test_pool 0 $(($OSTCOUNT - 1)) 1 ||
24808                 error "pool_add_targets failed"
24809
24810         save_layout_restore_at_exit $MOUNT
24811
24812         # parent set default stripe count only, child will stripe from both
24813         # parent and fs default
24814         $LFS setstripe -c 1 -i 1 -S $((def_stripe_size * 2)) -p $test_pool $MOUNT ||
24815                 error "setstripe $MOUNT failed"
24816         $LFS mkdir -c $MDSCOUNT $DIR/$tdir || error "mkdir $tdir failed"
24817         $LFS setstripe -c $OSTCOUNT $DIR/$tdir || error "setstripe $tdir failed"
24818         for i in $(seq 10); do
24819                 local f=$DIR/$tdir/$tfile.$i
24820                 touch $f || error "touch failed"
24821                 local count=$($LFS getstripe -c $f)
24822                 [ $count -eq $OSTCOUNT ] ||
24823                         error "$f stripe count $count != $OSTCOUNT"
24824                 local offset=$($LFS getstripe -i $f)
24825                 [ $offset -eq 1 ] || error "$f stripe offset $offset != 1"
24826                 local size=$($LFS getstripe -S $f)
24827                 [ $size -eq $((def_stripe_size * 2)) ] ||
24828                         error "$f stripe size $size != $((def_stripe_size * 2))"
24829                 local pool=$($LFS getstripe -p $f)
24830                 [ $pool == $test_pool ] || error "$f pool $pool != $test_pool"
24831         done
24832
24833         # change fs default striping, delete parent default striping, now child
24834         # will stripe from new fs default striping only
24835         $LFS setstripe -c 1 -S $def_stripe_size -i 0 $MOUNT ||
24836                 error "change $MOUNT default stripe failed"
24837         $LFS setstripe -c 0 $DIR/$tdir ||
24838                 error "delete $tdir default stripe failed"
24839         for i in $(seq 11 20); do
24840                 local f=$DIR/$tdir/$tfile.$i
24841                 touch $f || error "touch $f failed"
24842                 local count=$($LFS getstripe -c $f)
24843                 [ $count -eq 1 ] || error "$f stripe count $count != 1"
24844                 local offset=$($LFS getstripe -i $f)
24845                 [ $offset -eq 0 ] || error "$f stripe offset $offset != 0"
24846                 local size=$($LFS getstripe -S $f)
24847                 [ $size -eq $def_stripe_size ] ||
24848                         error "$f stripe size $size != $def_stripe_size"
24849                 local pool=$($LFS getstripe -p $f)
24850                 [ $pool == $test_pool ] || error "$f pool $pool isn't set"
24851         done
24852
24853         unlinkmany $DIR/$tdir/$tfile. 1 20
24854
24855         local f=$DIR/$tdir/$tfile
24856         pool_remove_all_targets $test_pool $f
24857         pool_remove $test_pool $f
24858 }
24859 run_test 406 "DNE support fs default striping"
24860
24861 test_407() {
24862         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
24863         [[ $MDS1_VERSION -lt $(version_code 2.8.55) ]] &&
24864                 skip "Need MDS version at least 2.8.55"
24865         remote_mds_nodsh && skip "remote MDS with nodsh"
24866
24867         $LFS mkdir -i 0 -c 1 $DIR/$tdir.0 ||
24868                 error "$LFS mkdir -i 0 -c 1 $tdir.0 failed"
24869         $LFS mkdir -i 1 -c 1 $DIR/$tdir.1 ||
24870                 error "$LFS mkdir -i 1 -c 1 $tdir.1 failed"
24871         touch $DIR/$tdir.0/$tfile.0 || error "touch $tdir.0/$tfile.0 failed"
24872
24873         #define OBD_FAIL_DT_TXN_STOP    0x2019
24874         for idx in $(seq $MDSCOUNT); do
24875                 do_facet mds$idx "lctl set_param fail_loc=0x2019"
24876         done
24877         $LFS mkdir -c 2 $DIR/$tdir && error "$LFS mkdir -c 2 $tdir should fail"
24878         mv $DIR/$tdir.0/$tfile.0 $DIR/$tdir.1/$tfile.1 &&
24879                 error "mv $tdir.0/$tfile.0 $tdir.1/$tfile.1 should fail"
24880         true
24881 }
24882 run_test 407 "transaction fail should cause operation fail"
24883
24884 test_408() {
24885         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1 oflag=direct
24886
24887         #define OBD_FAIL_OSC_BRW_PREP_REQ2        0x40a
24888         lctl set_param fail_loc=0x8000040a
24889         # let ll_prepare_partial_page() fail
24890         dd if=/dev/zero of=$DIR/$tfile bs=2048 count=1 conv=notrunc || true
24891
24892         rm -f $DIR/$tfile
24893
24894         # create at least 100 unused inodes so that
24895         # shrink_icache_memory(0) should not return 0
24896         touch $DIR/$tfile-{0..100}
24897         rm -f $DIR/$tfile-{0..100}
24898         sync
24899
24900         echo 2 > /proc/sys/vm/drop_caches
24901 }
24902 run_test 408 "drop_caches should not hang due to page leaks"
24903
24904 test_409()
24905 {
24906         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
24907
24908         mkdir -p $DIR/$tdir || error "(0) Fail to mkdir"
24909         $LFS mkdir -i 1 -c 2 $DIR/$tdir/foo || error "(1) Fail to mkdir"
24910         touch $DIR/$tdir/guard || error "(2) Fail to create"
24911
24912         local PREFIX=$(str_repeat 'A' 128)
24913         echo "Create 1K hard links start at $(date)"
24914         createmany -l $DIR/$tdir/guard $DIR/$tdir/foo/${PREFIX}_ 1000 ||
24915                 error "(3) Fail to hard link"
24916
24917         echo "Links count should be right although linkEA overflow"
24918         stat $DIR/$tdir/guard || error "(4) Fail to stat"
24919         local linkcount=$(stat --format=%h $DIR/$tdir/guard)
24920         [ $linkcount -eq 1001 ] ||
24921                 error "(5) Unexpected hard links count: $linkcount"
24922
24923         echo "List all links start at $(date)"
24924         ls -l $DIR/$tdir/foo > /dev/null ||
24925                 error "(6) Fail to list $DIR/$tdir/foo"
24926
24927         echo "Unlink hard links start at $(date)"
24928         unlinkmany $DIR/$tdir/foo/${PREFIX}_ 1000 ||
24929                 error "(7) Fail to unlink"
24930         echo "Unlink hard links finished at $(date)"
24931 }
24932 run_test 409 "Large amount of cross-MDTs hard links on the same file"
24933
24934 test_410()
24935 {
24936         [[ $CLIENT_VERSION -lt $(version_code 2.9.59) ]] &&
24937                 skip "Need client version at least 2.9.59"
24938         [ -f $LUSTRE/tests/kernel/kinode.ko ] ||
24939                 skip "Need MODULES build"
24940
24941         # Create a file, and stat it from the kernel
24942         local testfile=$DIR/$tfile
24943         touch $testfile
24944
24945         local run_id=$RANDOM
24946         local my_ino=$(stat --format "%i" $testfile)
24947
24948         # Try to insert the module. This will always fail as the
24949         # module is designed to not be inserted.
24950         insmod $LUSTRE/tests/kernel/kinode.ko run_id=$run_id fname=$testfile \
24951             &> /dev/null
24952
24953         # Anything but success is a test failure
24954         dmesg | grep -q \
24955             "lustre_kinode_$run_id: inode numbers are identical: $my_ino" ||
24956             error "no inode match"
24957 }
24958 run_test 410 "Test inode number returned from kernel thread"
24959
24960 cleanup_test411_cgroup() {
24961         trap 0
24962         rmdir "$1"
24963 }
24964
24965 test_411() {
24966         local cg_basedir=/sys/fs/cgroup/memory
24967         # LU-9966
24968         test -f "$cg_basedir/memory.kmem.limit_in_bytes" ||
24969                 skip "no setup for cgroup"
24970
24971         dd if=/dev/zero of=$DIR/$tfile bs=1M count=100 conv=fsync ||
24972                 error "test file creation failed"
24973         cancel_lru_locks osc
24974
24975         # Create a very small memory cgroup to force a slab allocation error
24976         local cgdir=$cg_basedir/osc_slab_alloc
24977         mkdir $cgdir || error "cgroup mkdir '$cgdir' failed"
24978         trap "cleanup_test411_cgroup $cgdir" EXIT
24979         echo 2M > $cgdir/memory.kmem.limit_in_bytes
24980         echo 1M > $cgdir/memory.limit_in_bytes
24981
24982         # Should not LBUG, just be killed by oom-killer
24983         # dd will return 0 even allocation failure in some environment.
24984         # So don't check return value
24985         sh -c "echo \$$ > $cgdir/tasks && dd if=$DIR/$tfile of=/dev/null"
24986         cleanup_test411_cgroup $cgdir
24987
24988         return 0
24989 }
24990 run_test 411 "Slab allocation error with cgroup does not LBUG"
24991
24992 test_412() {
24993         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
24994         if [ $MDS1_VERSION -lt $(version_code 2.10.55) ]; then
24995                 skip "Need server version at least 2.10.55"
24996         fi
24997
24998         $LFS mkdir -i $((MDSCOUNT - 1)),$((MDSCOUNT - 2)) $DIR/$tdir ||
24999                 error "mkdir failed"
25000         $LFS getdirstripe $DIR/$tdir
25001         local stripe_index=$($LFS getdirstripe -i $DIR/$tdir)
25002         [ $stripe_index -eq $((MDSCOUNT - 1)) ] ||
25003                 error "expect $((MDSCOUT - 1)) get $stripe_index"
25004         local stripe_count=$($LFS getdirstripe -T $DIR/$tdir)
25005         [ $stripe_count -eq 2 ] ||
25006                 error "expect 2 get $stripe_count"
25007 }
25008 run_test 412 "mkdir on specific MDTs"
25009
25010 generate_uneven_mdts() {
25011         local threshold=$1
25012         local lmv_qos_maxage
25013         local lod_qos_maxage
25014         local ffree
25015         local bavail
25016         local max
25017         local min
25018         local max_index
25019         local min_index
25020         local tmp
25021         local i
25022
25023         lmv_qos_maxage=$($LCTL get_param -n lmv.*.qos_maxage)
25024         $LCTL set_param lmv.*.qos_maxage=1
25025         stack_trap "$LCTL set_param \
25026                 lmv.*.qos_maxage=$lmv_qos_maxage > /dev/null" RETURN
25027         lod_qos_maxage=$(do_facet mds1 $LCTL get_param -n \
25028                 lod.$FSNAME-MDT0000-mdtlov.qos_maxage | awk '{ print $1 }')
25029         do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param \
25030                 lod.*.mdt_qos_maxage=1
25031         stack_trap "do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param \
25032                 lod.*.mdt_qos_maxage=$lod_qos_maxage > /dev/null" RETURN
25033
25034         echo
25035         echo "Check for uneven MDTs: "
25036
25037         ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.filesfree))
25038         bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.kbytesavail))
25039         bsize=$(lctl get_param -n mdc.*MDT0000*.blocksize)
25040
25041         max=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
25042         min=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
25043         max_index=0
25044         min_index=0
25045         for ((i = 1; i < ${#ffree[@]}; i++)); do
25046                 tmp=$(((${ffree[i]} >> 8) * (${bavail[i]} * bsize >> 16)))
25047                 if [ $tmp -gt $max ]; then
25048                         max=$tmp
25049                         max_index=$i
25050                 fi
25051                 if [ $tmp -lt $min ]; then
25052                         min=$tmp
25053                         min_index=$i
25054                 fi
25055         done
25056
25057         (( ${ffree[min_index]} > 0 )) ||
25058                 skip "no free files in MDT$min_index"
25059         (( ${ffree[min_index]} < 10000000 )) ||
25060                 skip "too many free files in MDT$min_index"
25061
25062         # Check if we need to generate uneven MDTs
25063         local diff=$(((max - min) * 100 / min))
25064         local testdir=$DIR/$tdir-fillmdt
25065         local start
25066
25067         mkdir -p $testdir
25068
25069         i=0
25070         while (( diff < threshold )); do
25071                 # generate uneven MDTs, create till $threshold% diff
25072                 echo -n "weight diff=$diff% must be > $threshold% ..."
25073                 echo "Fill MDT$min_index with 1000 files: loop $i"
25074                 testdir=$DIR/$tdir-fillmdt/$i
25075                 [ -d $testdir ] || $LFS mkdir -i $min_index $testdir ||
25076                         error "mkdir $testdir failed"
25077                 $LFS setstripe -E 1M -L mdt $testdir ||
25078                         error "setstripe $testdir failed"
25079                 start=$SECONDS
25080                 for F in f.{0..999}; do
25081                         dd if=/dev/zero of=$testdir/$F bs=64K count=1 > \
25082                                 /dev/null 2>&1 || error "dd $F failed"
25083                 done
25084
25085                 # wait for QOS to update
25086                 (( SECONDS < start + 1 )) && sleep $((start + 1 - SECONDS))
25087
25088                 ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-*.filesfree))
25089                 bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-*.kbytesavail))
25090                 max=$(((${ffree[max_index]} >> 8) * \
25091                         (${bavail[max_index]} * bsize >> 16)))
25092                 min=$(((${ffree[min_index]} >> 8) * \
25093                         (${bavail[min_index]} * bsize >> 16)))
25094                 diff=$(((max - min) * 100 / min))
25095                 i=$((i + 1))
25096         done
25097
25098         echo "MDT filesfree available: ${ffree[@]}"
25099         echo "MDT blocks available: ${bavail[@]}"
25100         echo "weight diff=$diff%"
25101 }
25102
25103 test_qos_mkdir() {
25104         local mkdir_cmd=$1
25105         local stripe_count=$2
25106         local mdts=$(comma_list $(mdts_nodes))
25107
25108         local testdir
25109         local lmv_qos_prio_free
25110         local lmv_qos_threshold_rr
25111         local lmv_qos_maxage
25112         local lod_qos_prio_free
25113         local lod_qos_threshold_rr
25114         local lod_qos_maxage
25115         local count
25116         local i
25117
25118         lmv_qos_prio_free=$($LCTL get_param -n lmv.*.qos_prio_free | head -n1)
25119         lmv_qos_prio_free=${lmv_qos_prio_free%%%}
25120         lmv_qos_threshold_rr=$($LCTL get_param -n lmv.*.qos_threshold_rr |
25121                 head -n1)
25122         lmv_qos_threshold_rr=${lmv_qos_threshold_rr%%%}
25123         lmv_qos_maxage=$($LCTL get_param -n lmv.*.qos_maxage)
25124         stack_trap "$LCTL set_param \
25125                 lmv.*.qos_prio_free=$lmv_qos_prio_free > /dev/null"
25126         stack_trap "$LCTL set_param \
25127                 lmv.*.qos_threshold_rr=$lmv_qos_threshold_rr > /dev/null"
25128         stack_trap "$LCTL set_param \
25129                 lmv.*.qos_maxage=$lmv_qos_maxage > /dev/null"
25130
25131         lod_qos_prio_free=$(do_facet mds1 $LCTL get_param -n \
25132                 lod.$FSNAME-MDT0000-mdtlov.mdt_qos_prio_free | head -n1)
25133         lod_qos_prio_free=${lod_qos_prio_free%%%}
25134         lod_qos_threshold_rr=$(do_facet mds1 $LCTL get_param -n \
25135                 lod.$FSNAME-MDT0000-mdtlov.mdt_qos_threshold_rr | head -n1)
25136         lod_qos_threshold_rr=${lod_qos_threshold_rr%%%}
25137         lod_qos_maxage=$(do_facet mds1 $LCTL get_param -n \
25138                 lod.$FSNAME-MDT0000-mdtlov.qos_maxage | awk '{ print $1 }')
25139         stack_trap "do_nodes $mdts $LCTL set_param \
25140                 lod.*.mdt_qos_prio_free=$lod_qos_prio_free > /dev/null"
25141         stack_trap "do_nodes $mdts $LCTL set_param \
25142                 lod.*.mdt_qos_threshold_rr=$lod_qos_threshold_rr > /dev/null"
25143         stack_trap "do_nodes $mdts $LCTL set_param \
25144                 lod.*.mdt_qos_maxage=$lod_qos_maxage > /dev/null"
25145
25146         $LCTL set_param lmv.*.qos_threshold_rr=100 > /dev/null
25147         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_threshold_rr=100 > /dev/null
25148
25149         testdir=$DIR/$tdir-s$stripe_count/rr
25150
25151         local stripe_index=$($LFS getstripe -m $testdir)
25152         local test_mkdir_rr=true
25153
25154         getfattr -d -m dmv -e hex $testdir | grep dmv
25155         if (( $? == 0 && $MDS1_VERSION >= $(version_code 2.14.51) )); then
25156                 echo "defstripe: '$($LFS getdirstripe -D $testdir)'"
25157                 (( $($LFS getdirstripe -D --max-inherit-rr $testdir) == 0 )) &&
25158                         test_mkdir_rr=false
25159         fi
25160
25161         echo
25162         $test_mkdir_rr &&
25163                 echo "Mkdir (stripe_count $stripe_count) roundrobin:" ||
25164                 echo "Mkdir (stripe_count $stripe_count) on stripe $stripe_index"
25165
25166         stack_trap "unlinkmany -d $testdir/subdir $((100 * MDSCOUNT))"
25167         for (( i = 0; i < 100 * MDSCOUNT; i++ )); do
25168                 eval $mkdir_cmd $testdir/subdir$i ||
25169                         error "$mkdir_cmd subdir$i failed"
25170         done
25171
25172         for (( i = 0; i < $MDSCOUNT; i++ )); do
25173                 count=$($LFS getdirstripe -i $testdir/* | grep -c "^$i$")
25174                 echo "$count directories created on MDT$i"
25175                 if $test_mkdir_rr; then
25176                         (( $count == 100 )) ||
25177                                 error "subdirs are not evenly distributed"
25178                 elif (( $i == $stripe_index )); then
25179                         (( $count == 100 * MDSCOUNT )) ||
25180                                 error "$count subdirs created on MDT$i"
25181                 else
25182                         (( $count == 0 )) ||
25183                                 error "$count subdirs created on MDT$i"
25184                 fi
25185
25186                 if $test_mkdir_rr && [ $stripe_count -gt 1 ]; then
25187                         count=$($LFS getdirstripe $testdir/* |
25188                                 grep -c -P "^\s+$i\t")
25189                         echo "$count stripes created on MDT$i"
25190                         # deviation should < 5% of average
25191                         (( $count >= 95 * stripe_count &&
25192                            $count <= 105 * stripe_count)) ||
25193                                 error "stripes are not evenly distributed"
25194                 fi
25195         done
25196
25197         echo
25198         echo "Check for uneven MDTs: "
25199
25200         local ffree
25201         local bavail
25202         local max
25203         local min
25204         local max_index
25205         local min_index
25206         local tmp
25207
25208         ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.filesfree))
25209         bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.kbytesavail))
25210         bsize=$(lctl get_param -n mdc.*MDT0000*.blocksize)
25211
25212         max=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
25213         min=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
25214         max_index=0
25215         min_index=0
25216         for ((i = 1; i < ${#ffree[@]}; i++)); do
25217                 tmp=$(((${ffree[i]} >> 8) * (${bavail[i]} * bsize >> 16)))
25218                 if [ $tmp -gt $max ]; then
25219                         max=$tmp
25220                         max_index=$i
25221                 fi
25222                 if [ $tmp -lt $min ]; then
25223                         min=$tmp
25224                         min_index=$i
25225                 fi
25226         done
25227
25228         (( ${ffree[min_index]} > 0 )) ||
25229                 skip "no free files in MDT$min_index"
25230         (( ${ffree[min_index]} < 10000000 )) ||
25231                 skip "too many free files in MDT$min_index"
25232
25233         echo "MDT filesfree available: ${ffree[@]}"
25234         echo "MDT blocks available: ${bavail[@]}"
25235         echo "weight diff=$(((max - min) * 100 / min))%"
25236         echo
25237         echo "Mkdir (stripe_count $stripe_count) with balanced space usage:"
25238
25239         $LCTL set_param lmv.*.qos_threshold_rr=0 > /dev/null
25240         $LCTL set_param lmv.*.qos_prio_free=100 > /dev/null
25241         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_threshold_rr=0 > /dev/null
25242         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_prio_free=100 > /dev/null
25243         # decrease statfs age, so that it can be updated in time
25244         $LCTL set_param lmv.*.qos_maxage=1 > /dev/null
25245         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_maxage=1 > /dev/null
25246
25247         sleep 1
25248
25249         testdir=$DIR/$tdir-s$stripe_count/qos
25250         local num=200
25251
25252         stack_trap "unlinkmany -d $testdir/subdir $((num * MDSCOUNT))"
25253         for (( i = 0; i < num * MDSCOUNT; i++ )); do
25254                 eval $mkdir_cmd $testdir/subdir$i ||
25255                         error "$mkdir_cmd subdir$i failed"
25256         done
25257
25258         max=0
25259         for (( i = 0; i < $MDSCOUNT; i++ )); do
25260                 count=$($LFS getdirstripe -i $testdir/* | grep -c "^$i$")
25261                 (( count > max )) && max=$count
25262                 echo "$count directories created on MDT$i"
25263         done
25264
25265         min=$($LFS getdirstripe -i $testdir/* | grep -c "^$min_index$")
25266
25267         # D-value should > 10% of averge
25268         (( max - min > num / 10 )) ||
25269                 error "subdirs shouldn't be evenly distributed: $max - $min < $((num / 10))"
25270
25271         # ditto for stripes
25272         if (( stripe_count > 1 )); then
25273                 max=0
25274                 for (( i = 0; i < $MDSCOUNT; i++ )); do
25275                         count=$($LFS getdirstripe $testdir/* |
25276                                 grep -c -P "^\s+$i\t")
25277                         (( count > max )) && max=$count
25278                         echo "$count stripes created on MDT$i"
25279                 done
25280
25281                 min=$($LFS getdirstripe $testdir/* |
25282                         grep -c -P "^\s+$min_index\t")
25283                 (( max - min > num * stripe_count / 10 )) ||
25284                         error "stripes shouldn't be evenly distributed: $max - $min < $((num / 10)) * $stripe_count"
25285         fi
25286 }
25287
25288 most_full_mdt() {
25289         local ffree
25290         local bavail
25291         local bsize
25292         local min
25293         local min_index
25294         local tmp
25295
25296         ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.filesfree))
25297         bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.kbytesavail))
25298         bsize=$(lctl get_param -n mdc.*MDT0000*.blocksize)
25299
25300         min=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
25301         min_index=0
25302         for ((i = 1; i < ${#ffree[@]}; i++)); do
25303                 tmp=$(((${ffree[i]} >> 8) * (${bavail[i]} * bsize >> 16)))
25304                 (( tmp < min )) && min=$tmp && min_index=$i
25305         done
25306
25307         echo -n $min_index
25308 }
25309
25310 test_413a() {
25311         [ $MDSCOUNT -lt 2 ] &&
25312                 skip "We need at least 2 MDTs for this test"
25313
25314         [ $MDS1_VERSION -lt $(version_code 2.12.52) ] &&
25315                 skip "Need server version at least 2.12.52"
25316
25317         local stripe_count
25318
25319         generate_uneven_mdts 100
25320         for stripe_count in $(seq 1 $((MDSCOUNT - 1))); do
25321                 mkdir $DIR/$tdir-s$stripe_count || error "mkdir failed"
25322                 mkdir $DIR/$tdir-s$stripe_count/rr || error "mkdir failed"
25323                 $LFS mkdir -i $(most_full_mdt) $DIR/$tdir-s$stripe_count/qos ||
25324                         error "mkdir failed"
25325                 test_qos_mkdir "$LFS mkdir -i -1 -c $stripe_count" $stripe_count
25326         done
25327 }
25328 run_test 413a "QoS mkdir with 'lfs mkdir -i -1'"
25329
25330 test_413b() {
25331         [ $MDSCOUNT -lt 2 ] &&
25332                 skip "We need at least 2 MDTs for this test"
25333
25334         [ $MDS1_VERSION -lt $(version_code 2.12.52) ] &&
25335                 skip "Need server version at least 2.12.52"
25336
25337         local testdir
25338         local stripe_count
25339
25340         generate_uneven_mdts 100
25341         for stripe_count in $(seq 1 $((MDSCOUNT - 1))); do
25342                 testdir=$DIR/$tdir-s$stripe_count
25343                 mkdir $testdir || error "mkdir $testdir failed"
25344                 mkdir $testdir/rr || error "mkdir rr failed"
25345                 $LFS mkdir -i $(most_full_mdt) $testdir/qos ||
25346                         error "mkdir qos failed"
25347                 $LFS setdirstripe -D -c $stripe_count --max-inherit-rr 2 \
25348                         $testdir/rr || error "setdirstripe rr failed"
25349                 $LFS setdirstripe -D -c $stripe_count $testdir/qos ||
25350                         error "setdirstripe failed"
25351                 test_qos_mkdir "mkdir" $stripe_count
25352         done
25353 }
25354 run_test 413b "QoS mkdir under dir whose default LMV starting MDT offset is -1"
25355
25356 test_413c() {
25357         (( $MDSCOUNT >= 2 )) ||
25358                 skip "We need at least 2 MDTs for this test"
25359
25360         (( $MDS1_VERSION >= $(version_code 2.14.51) )) ||
25361                 skip "Need server version at least 2.14.51"
25362
25363         local testdir
25364         local inherit
25365         local inherit_rr
25366
25367         testdir=$DIR/${tdir}-s1
25368         mkdir $testdir || error "mkdir $testdir failed"
25369         mkdir $testdir/rr || error "mkdir rr failed"
25370         $LFS mkdir -i $(most_full_mdt) $testdir/qos || error "mkdir qos failed"
25371         # default max_inherit is -1, default max_inherit_rr is 0
25372         $LFS setdirstripe -D -c 1 $testdir/rr ||
25373                 error "setdirstripe rr failed"
25374         $LFS setdirstripe -D -c 1 -i -1 -X 2 --max-inherit-rr 1 $testdir/qos ||
25375                 error "setdirstripe qos failed"
25376         test_qos_mkdir "mkdir" 1
25377
25378         mkdir $testdir/rr/level1 || error "mkdir rr/level1 failed"
25379         inherit=$($LFS getdirstripe -D -X $testdir/rr/level1)
25380         (( $inherit == -1 )) || error "rr/level1 inherit $inherit != -1"
25381         inherit_rr=$($LFS getdirstripe -D --max-inherit-rr $testdir/rr/level1)
25382         (( $inherit_rr == 0 )) || error "rr/level1 inherit-rr $inherit_rr != 0"
25383
25384         mkdir $testdir/qos/level1 || error "mkdir qos/level1 failed"
25385         inherit=$($LFS getdirstripe -D -X $testdir/qos/level1)
25386         (( $inherit == 1 )) || error "qos/level1 inherit $inherit != 1"
25387         inherit_rr=$($LFS getdirstripe -D --max-inherit-rr $testdir/qos/level1)
25388         (( $inherit_rr == 0 )) || error "qos/level1 inherit-rr $inherit_rr != 0"
25389         mkdir $testdir/qos/level1/level2 || error "mkdir level2 failed"
25390         getfattr -d -m dmv -e hex $testdir/qos/level1/level2 | grep dmv &&
25391                 error "level2 shouldn't have default LMV" || true
25392 }
25393 run_test 413c "mkdir with default LMV max inherit rr"
25394
25395 test_413d() {
25396         (( MDSCOUNT >= 2 )) ||
25397                 skip "We need at least 2 MDTs for this test"
25398
25399         (( MDS1_VERSION >= $(version_code 2.14.51) )) ||
25400                 skip "Need server version at least 2.14.51"
25401
25402         local lmv_qos_threshold_rr
25403
25404         lmv_qos_threshold_rr=$($LCTL get_param -n lmv.*.qos_threshold_rr |
25405                 head -n1)
25406         stack_trap "$LCTL set_param \
25407                 lmv.*.qos_threshold_rr=$lmv_qos_threshold_rr > /dev/null" EXIT
25408
25409         $LCTL set_param lmv.*.qos_threshold_rr=100 > /dev/null
25410         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
25411         getfattr -d -m dmv -e hex $DIR/$tdir | grep dmv &&
25412                 error "$tdir shouldn't have default LMV"
25413         createmany -d $DIR/$tdir/sub $((100 * MDSCOUNT)) ||
25414                 error "mkdir sub failed"
25415
25416         local count=$($LFS getstripe -m $DIR/$tdir/* | grep -c ^0)
25417
25418         (( count == 100 )) || error "$count subdirs on MDT0"
25419 }
25420 run_test 413d "inherit ROOT default LMV"
25421
25422 test_413z() {
25423         local pids=""
25424         local subdir
25425         local pid
25426
25427         for subdir in $(\ls -1 -d $DIR/d413*-fillmdt/*); do
25428                 unlinkmany $subdir/f. 1000 &
25429                 pids="$pids $!"
25430         done
25431
25432         for pid in $pids; do
25433                 wait $pid
25434         done
25435 }
25436 run_test 413z "413 test cleanup"
25437
25438 test_414() {
25439 #define OBD_FAIL_PTLRPC_BULK_ATTACH      0x521
25440         $LCTL set_param fail_loc=0x80000521
25441         dd if=/dev/zero of=$DIR/$tfile bs=2M count=1 oflag=sync
25442         rm -f $DIR/$tfile
25443 }
25444 run_test 414 "simulate ENOMEM in ptlrpc_register_bulk()"
25445
25446 test_415() {
25447         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25448         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
25449                 skip "Need server version at least 2.11.52"
25450
25451         # LU-11102
25452         local total
25453         local setattr_pid
25454         local start_time
25455         local end_time
25456         local duration
25457
25458         total=500
25459         # this test may be slow on ZFS
25460         [ "$mds1_FSTYPE" == "zfs" ] && total=100
25461
25462         # though this test is designed for striped directory, let's test normal
25463         # directory too since lock is always saved as CoS lock.
25464         test_mkdir $DIR/$tdir || error "mkdir $tdir"
25465         createmany -o $DIR/$tdir/$tfile. $total || error "createmany"
25466
25467         (
25468                 while true; do
25469                         touch $DIR/$tdir
25470                 done
25471         ) &
25472         setattr_pid=$!
25473
25474         start_time=$(date +%s)
25475         for i in $(seq $total); do
25476                 mrename $DIR/$tdir/$tfile.$i $DIR/$tdir/$tfile-new.$i \
25477                         > /dev/null
25478         done
25479         end_time=$(date +%s)
25480         duration=$((end_time - start_time))
25481
25482         kill -9 $setattr_pid
25483
25484         echo "rename $total files took $duration sec"
25485         [ $duration -lt 100 ] || error "rename took $duration sec"
25486 }
25487 run_test 415 "lock revoke is not missing"
25488
25489 test_416() {
25490         [ $MDS1_VERSION -lt $(version_code 2.11.55) ] &&
25491                 skip "Need server version at least 2.11.55"
25492
25493         # define OBD_FAIL_OSD_TXN_START    0x19a
25494         do_facet mds1 lctl set_param fail_loc=0x19a
25495
25496         lfs mkdir -c $MDSCOUNT $DIR/$tdir
25497
25498         true
25499 }
25500 run_test 416 "transaction start failure won't cause system hung"
25501
25502 cleanup_417() {
25503         trap 0
25504         do_nodes $(comma_list $(mdts_nodes)) \
25505                 "$LCTL set_param -n mdt.*MDT*.enable_dir_migration=1"
25506         do_nodes $(comma_list $(mdts_nodes)) \
25507                 "$LCTL set_param -n mdt.*MDT*.enable_remote_dir=1"
25508         do_nodes $(comma_list $(mdts_nodes)) \
25509                 "$LCTL set_param -n mdt.*MDT*.enable_striped_dir=1"
25510 }
25511
25512 test_417() {
25513         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
25514         [[ $MDS1_VERSION -lt $(version_code 2.11.56) ]] &&
25515                 skip "Need MDS version at least 2.11.56"
25516
25517         trap cleanup_417 RETURN EXIT
25518
25519         $LFS mkdir -i 1 $DIR/$tdir.1 || error "create remote dir $tdir.1 failed"
25520         do_nodes $(comma_list $(mdts_nodes)) \
25521                 "$LCTL set_param -n mdt.*MDT*.enable_dir_migration=0"
25522         $LFS migrate -m 0 $DIR/$tdir.1 &&
25523                 error "migrate dir $tdir.1 should fail"
25524
25525         do_nodes $(comma_list $(mdts_nodes)) \
25526                 "$LCTL set_param -n mdt.*MDT*.enable_remote_dir=0"
25527         $LFS mkdir -i 1 $DIR/$tdir.2 &&
25528                 error "create remote dir $tdir.2 should fail"
25529
25530         do_nodes $(comma_list $(mdts_nodes)) \
25531                 "$LCTL set_param -n mdt.*MDT*.enable_striped_dir=0"
25532         $LFS mkdir -c 2 $DIR/$tdir.3 &&
25533                 error "create striped dir $tdir.3 should fail"
25534         true
25535 }
25536 run_test 417 "disable remote dir, striped dir and dir migration"
25537
25538 # Checks that the outputs of df [-i] and lfs df [-i] match
25539 #
25540 # usage: check_lfs_df <blocks | inodes> <mountpoint>
25541 check_lfs_df() {
25542         local dir=$2
25543         local inodes
25544         local df_out
25545         local lfs_df_out
25546         local count
25547         local passed=false
25548
25549         # blocks or inodes
25550         [ "$1" == "blocks" ] && inodes= || inodes="-i"
25551
25552         for count in {1..100}; do
25553                 do_nodes "$CLIENTS" \
25554                         $LCTL set_param ldlm.namespaces.*.lru_size=clear
25555                 sync; sleep 0.2
25556
25557                 # read the lines of interest
25558                 df_out=($(df -P $inodes $dir | tail -n +2)) ||
25559                         error "df $inodes $dir | tail -n +2 failed"
25560                 lfs_df_out=($($LFS df $inodes $dir | grep summary:)) ||
25561                         error "lfs df $inodes $dir | grep summary: failed"
25562
25563                 # skip first substrings of each output as they are different
25564                 # "<NID>:/<fsname>" for df, "filesystem_summary:" for lfs df
25565                 # compare the two outputs
25566                 passed=true
25567                 #  skip "available" on MDT until LU-13997 is fixed.
25568                 #for i in {1..5}; do
25569                 for i in 1 2 4 5; do
25570                         [ "${df_out[i]}" != "${lfs_df_out[i]}" ] && passed=false
25571                 done
25572                 $passed && break
25573         done
25574
25575         if ! $passed; then
25576                 df -P $inodes $dir
25577                 echo
25578                 lfs df $inodes $dir
25579                 error "df and lfs df $1 output mismatch: "      \
25580                       "df ${inodes}: ${df_out[*]}, "            \
25581                       "lfs df ${inodes}: ${lfs_df_out[*]}"
25582         fi
25583 }
25584
25585 test_418() {
25586         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25587
25588         local dir=$DIR/$tdir
25589         local numfiles=$((RANDOM % 4096 + 2))
25590         local numblocks=$((RANDOM % 256 + 1))
25591
25592         wait_delete_completed
25593         test_mkdir $dir
25594
25595         # check block output
25596         check_lfs_df blocks $dir
25597         # check inode output
25598         check_lfs_df inodes $dir
25599
25600         # create a single file and retest
25601         echo "Creating a single file and testing"
25602         createmany -o $dir/$tfile- 1 &>/dev/null ||
25603                 error "creating 1 file in $dir failed"
25604         check_lfs_df blocks $dir
25605         check_lfs_df inodes $dir
25606
25607         # create a random number of files
25608         echo "Creating $((numfiles - 1)) files and testing"
25609         createmany -o $dir/$tfile- 1 $((numfiles - 1)) &>/dev/null ||
25610                 error "creating $((numfiles - 1)) files in $dir failed"
25611
25612         # write a random number of blocks to the first test file
25613         echo "Writing $numblocks 4K blocks and testing"
25614         dd if=/dev/urandom of=$dir/${tfile}-0 bs=4K conv=fsync \
25615                 count=$numblocks &>/dev/null ||
25616                 error "dd to $dir/${tfile}-0 failed"
25617
25618         # retest
25619         check_lfs_df blocks $dir
25620         check_lfs_df inodes $dir
25621
25622         unlinkmany $dir/$tfile- $numfiles &>/dev/null ||
25623                 error "unlinking $numfiles files in $dir failed"
25624 }
25625 run_test 418 "df and lfs df outputs match"
25626
25627 test_419()
25628 {
25629         local dir=$DIR/$tdir
25630
25631         mkdir -p $dir
25632         touch $dir/file
25633
25634         cancel_lru_locks mdc
25635
25636         #OBD_FAIL_LLITE_OPEN_BY_NAME    0x1410
25637         $LCTL set_param fail_loc=0x1410
25638         cat $dir/file
25639         $LCTL set_param fail_loc=0
25640         rm -rf $dir
25641 }
25642 run_test 419 "Verify open file by name doesn't crash kernel"
25643
25644 test_420()
25645 {
25646         [[ $MDS1_VERSION -ge $(version_code 2.12.53) ]] ||
25647                 skip "Need MDS version at least 2.12.53"
25648
25649         local SAVE_UMASK=$(umask)
25650         local dir=$DIR/$tdir
25651         local uname=$(getent passwd $RUNAS_ID | cut -d: -f1)
25652
25653         mkdir -p $dir
25654         umask 0000
25655         mkdir -m03777 $dir/testdir
25656         ls -dn $dir/testdir
25657         # Need to remove trailing '.' when SELinux is enabled
25658         local dirperms=$(ls -dn $dir/testdir |
25659                          awk '{ sub(/\.$/, "", $1); print $1}')
25660         [ $dirperms == "drwxrwsrwt" ] ||
25661                 error "incorrect perms on $dir/testdir"
25662
25663         su - $uname -c "PATH=$LUSTRE/tests:\$PATH; \
25664                 openfile -f O_RDONLY:O_CREAT -m 02755 $dir/testdir/testfile"
25665         ls -n $dir/testdir/testfile
25666         local fileperms=$(ls -n $dir/testdir/testfile |
25667                           awk '{ sub(/\.$/, "", $1); print $1}')
25668         [ $fileperms == "-rwxr-xr-x" ] ||
25669                 error "incorrect perms on $dir/testdir/testfile"
25670
25671         umask $SAVE_UMASK
25672 }
25673 run_test 420 "clear SGID bit on non-directories for non-members"
25674
25675 test_421a() {
25676         local cnt
25677         local fid1
25678         local fid2
25679
25680         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
25681                 skip "Need MDS version at least 2.12.54"
25682
25683         test_mkdir $DIR/$tdir
25684         createmany -o $DIR/$tdir/f 3
25685         cnt=$(ls -1 $DIR/$tdir | wc -l)
25686         [ $cnt != 3 ] && error "unexpected #files: $cnt"
25687
25688         fid1=$(lfs path2fid $DIR/$tdir/f1)
25689         fid2=$(lfs path2fid $DIR/$tdir/f2)
25690         $LFS rmfid $DIR $fid1 $fid2 || error "rmfid failed"
25691
25692         stat $DIR/$tdir/f1 && error "f1 still visible on the client"
25693         stat $DIR/$tdir/f2 && error "f2 still visible on the client"
25694
25695         cnt=$(ls -1 $DIR/$tdir | wc -l)
25696         [ $cnt == 1 ] || error "unexpected #files after: $cnt"
25697
25698         rm -f $DIR/$tdir/f3 || error "can't remove f3"
25699         createmany -o $DIR/$tdir/f 3
25700         cnt=$(ls -1 $DIR/$tdir | wc -l)
25701         [ $cnt != 3 ] && error "unexpected #files: $cnt"
25702
25703         fid1=$(lfs path2fid $DIR/$tdir/f1)
25704         fid2=$(lfs path2fid $DIR/$tdir/f2)
25705         echo "remove using fsname $FSNAME"
25706         $LFS rmfid $FSNAME $fid1 $fid2 || error "rmfid with fsname failed"
25707
25708         cnt=$(ls -1 $DIR/$tdir | wc -l)
25709         [ $cnt == 1 ] || error "unexpected #files after: $cnt"
25710 }
25711 run_test 421a "simple rm by fid"
25712
25713 test_421b() {
25714         local cnt
25715         local FID1
25716         local FID2
25717
25718         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
25719                 skip "Need MDS version at least 2.12.54"
25720
25721         test_mkdir $DIR/$tdir
25722         createmany -o $DIR/$tdir/f 3
25723         multiop_bg_pause $DIR/$tdir/f1 o_c || error "multiop failed to start"
25724         MULTIPID=$!
25725
25726         FID1=$(lfs path2fid $DIR/$tdir/f1)
25727         FID2=$(lfs path2fid $DIR/$tdir/f2)
25728         $LFS rmfid $DIR $FID1 $FID2 && error "rmfid didn't fail"
25729
25730         kill -USR1 $MULTIPID
25731         wait
25732
25733         cnt=$(ls $DIR/$tdir | wc -l)
25734         [ $cnt == 2 ] || error "unexpected #files after: $cnt"
25735 }
25736 run_test 421b "rm by fid on open file"
25737
25738 test_421c() {
25739         local cnt
25740         local FIDS
25741
25742         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
25743                 skip "Need MDS version at least 2.12.54"
25744
25745         test_mkdir $DIR/$tdir
25746         createmany -o $DIR/$tdir/f 3
25747         touch $DIR/$tdir/$tfile
25748         createmany -l$DIR/$tdir/$tfile $DIR/$tdir/h 180
25749         cnt=$(ls -1 $DIR/$tdir | wc -l)
25750         [ $cnt != 184 ] && error "unexpected #files: $cnt"
25751
25752         FID1=$(lfs path2fid $DIR/$tdir/$tfile)
25753         $LFS rmfid $DIR $FID1 || error "rmfid failed"
25754
25755         cnt=$(ls $DIR/$tdir | wc -l)
25756         [ $cnt == 3 ] || error "unexpected #files after: $cnt"
25757 }
25758 run_test 421c "rm by fid against hardlinked files"
25759
25760 test_421d() {
25761         local cnt
25762         local FIDS
25763
25764         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
25765                 skip "Need MDS version at least 2.12.54"
25766
25767         test_mkdir $DIR/$tdir
25768         createmany -o $DIR/$tdir/f 4097
25769         cnt=$(ls -1 $DIR/$tdir | wc -l)
25770         [ $cnt != 4097 ] && error "unexpected #files: $cnt"
25771
25772         FIDS=$(lfs path2fid $DIR/$tdir/f* | sed "s/[/][^:]*://g")
25773         $LFS rmfid $DIR $FIDS || error "rmfid failed"
25774
25775         cnt=$(ls $DIR/$tdir | wc -l)
25776         rm -rf $DIR/$tdir
25777         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
25778 }
25779 run_test 421d "rmfid en masse"
25780
25781 test_421e() {
25782         local cnt
25783         local FID
25784
25785         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
25786         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
25787                 skip "Need MDS version at least 2.12.54"
25788
25789         mkdir -p $DIR/$tdir
25790         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
25791         createmany -o $DIR/$tdir/striped_dir/f 512
25792         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
25793         [ $cnt != 512 ] && error "unexpected #files: $cnt"
25794
25795         FIDS=$(lfs path2fid $DIR/$tdir/striped_dir/f* |
25796                 sed "s/[/][^:]*://g")
25797         $LFS rmfid $DIR $FIDS || error "rmfid failed"
25798
25799         cnt=$(ls $DIR/$tdir/striped_dir | wc -l)
25800         rm -rf $DIR/$tdir
25801         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
25802 }
25803 run_test 421e "rmfid in DNE"
25804
25805 test_421f() {
25806         local cnt
25807         local FID
25808
25809         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
25810                 skip "Need MDS version at least 2.12.54"
25811
25812         test_mkdir $DIR/$tdir
25813         touch $DIR/$tdir/f
25814         cnt=$(ls -1 $DIR/$tdir | wc -l)
25815         [ $cnt != 1 ] && error "unexpected #files: $cnt"
25816
25817         FID=$(lfs path2fid $DIR/$tdir/f)
25818         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail (1)"
25819         # rmfid should fail
25820         cnt=$(ls -1 $DIR/$tdir | wc -l)
25821         [ $cnt != 1 ] && error "unexpected #files after (2): $cnt"
25822
25823         chmod a+rw $DIR/$tdir
25824         ls -la $DIR/$tdir
25825         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail (2)"
25826         # rmfid should fail
25827         cnt=$(ls -1 $DIR/$tdir | wc -l)
25828         [ $cnt != 1 ] && error "unexpected #files after (3): $cnt"
25829
25830         rm -f $DIR/$tdir/f
25831         $RUNAS touch $DIR/$tdir/f
25832         FID=$(lfs path2fid $DIR/$tdir/f)
25833         echo "rmfid as root"
25834         $LFS rmfid $DIR $FID || error "rmfid as root failed"
25835         cnt=$(ls -1 $DIR/$tdir | wc -l)
25836         [ $cnt == 0 ] || error "unexpected #files after (4): $cnt"
25837
25838         rm -f $DIR/$tdir/f
25839         $RUNAS touch $DIR/$tdir/f
25840         cnt=$(ls -1 $DIR/$tdir | wc -l)
25841         [ $cnt != 1 ] && error "unexpected #files (4): $cnt"
25842         FID=$(lfs path2fid $DIR/$tdir/f)
25843         # rmfid w/o user_fid2path mount option should fail
25844         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail(3)"
25845         cnt=$(ls -1 $DIR/$tdir | wc -l)
25846         [ $cnt == 1 ] || error "unexpected #files after (5): $cnt"
25847
25848         tmpdir=$(mktemp -d /tmp/lustre-XXXXXX)
25849         stack_trap "rmdir $tmpdir"
25850         mount_client $tmpdir "$MOUNT_OPTS,user_fid2path" ||
25851                 error "failed to mount client'"
25852         stack_trap "umount_client $tmpdir"
25853
25854         $RUNAS $LFS rmfid $tmpdir $FID || error "rmfid failed"
25855         # rmfid should succeed
25856         cnt=$(ls -1 $tmpdir/$tdir | wc -l)
25857         [ $cnt == 0 ] || error "unexpected #files after (6): $cnt"
25858
25859         # rmfid shouldn't allow to remove files due to dir's permission
25860         chmod a+rwx $tmpdir/$tdir
25861         touch $tmpdir/$tdir/f
25862         ls -la $tmpdir/$tdir
25863         FID=$(lfs path2fid $tmpdir/$tdir/f)
25864         $RUNAS $LFS rmfid $tmpdir $FID && error "rmfid didn't fail"
25865         return 0
25866 }
25867 run_test 421f "rmfid checks permissions"
25868
25869 test_421g() {
25870         local cnt
25871         local FIDS
25872
25873         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
25874         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
25875                 skip "Need MDS version at least 2.12.54"
25876
25877         mkdir -p $DIR/$tdir
25878         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
25879         createmany -o $DIR/$tdir/striped_dir/f 512
25880         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
25881         [ $cnt != 512 ] && error "unexpected #files: $cnt"
25882
25883         FIDS=$(lfs path2fid $DIR/$tdir/striped_dir/f* |
25884                 sed "s/[/][^:]*://g")
25885
25886         rm -f $DIR/$tdir/striped_dir/f1*
25887         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
25888         removed=$((512 - cnt))
25889
25890         # few files have been just removed, so we expect
25891         # rmfid to fail on their fids
25892         errors=$($LFS rmfid $DIR $FIDS 2>&1 | wc -l)
25893         [ $removed != $errors ] && error "$errors != $removed"
25894
25895         cnt=$(ls $DIR/$tdir/striped_dir | wc -l)
25896         rm -rf $DIR/$tdir
25897         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
25898 }
25899 run_test 421g "rmfid to return errors properly"
25900
25901 test_422() {
25902         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d1
25903         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d2
25904         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d3
25905         dd if=/dev/zero of=$DIR/$tdir/d1/file1 bs=1k count=1
25906         dd if=/dev/zero of=$DIR/$tdir/d2/file1 bs=1k count=1
25907
25908         local amc=$(at_max_get client)
25909         local amo=$(at_max_get mds1)
25910         local timeout=`lctl get_param -n timeout`
25911
25912         at_max_set 0 client
25913         at_max_set 0 mds1
25914
25915 #define OBD_FAIL_PTLRPC_PAUSE_REQ        0x50a
25916         do_facet mds1 $LCTL set_param fail_loc=0x8000050a \
25917                         fail_val=$(((2*timeout + 10)*1000))
25918         touch $DIR/$tdir/d3/file &
25919         sleep 2
25920 #define OBD_FAIL_TGT_REPLY_DATA_RACE     0x722
25921         do_facet mds1 $LCTL set_param fail_loc=0x80000722 \
25922                         fail_val=$((2*timeout + 5))
25923         mv $DIR/$tdir/d1/file1 $DIR/$tdir/d1/file2 &
25924         local pid=$!
25925         sleep 1
25926         kill -9 $pid
25927         sleep $((2 * timeout))
25928         echo kill $pid
25929         kill -9 $pid
25930         lctl mark touch
25931         touch $DIR/$tdir/d2/file3
25932         touch $DIR/$tdir/d2/file4
25933         touch $DIR/$tdir/d2/file5
25934
25935         wait
25936         at_max_set $amc client
25937         at_max_set $amo mds1
25938
25939         # LU-12838 - verify the ptlrpc thread watchdog is not always throttled
25940         do_facet mds1 "dmesg | grep 'Dumping the stack trace for debugging'" ||
25941                 error "Watchdog is always throttled"
25942 }
25943 run_test 422 "kill a process with RPC in progress"
25944
25945 stat_test() {
25946     df -h $MOUNT &
25947     df -h $MOUNT &
25948     df -h $MOUNT &
25949     df -h $MOUNT &
25950     df -h $MOUNT &
25951     df -h $MOUNT &
25952 }
25953
25954 test_423() {
25955     local _stats
25956     # ensure statfs cache is expired
25957     sleep 2;
25958
25959     _stats=$(stat_test | grep $MOUNT | sort -u | wc -l)
25960     [[ ${_stats} -ne 1 ]] && error "statfs wrong"
25961
25962     return 0
25963 }
25964 run_test 423 "statfs should return a right data"
25965
25966 test_424() {
25967 #define OBD_FAIL_PTLRPC_BULK_REPLY_ATTACH      0x522 | OBD_FAIL_ONCE
25968         $LCTL set_param fail_loc=0x80000522
25969         dd if=/dev/zero of=$DIR/$tfile bs=2M count=1 oflag=sync
25970         rm -f $DIR/$tfile
25971 }
25972 run_test 424 "simulate ENOMEM in ptl_send_rpc bulk reply ME attach"
25973
25974 test_425() {
25975         test_mkdir -c -1 $DIR/$tdir
25976         $LFS setstripe -c -1 $DIR/$tdir
25977
25978         lru_resize_disable "" 100
25979         stack_trap "lru_resize_enable" EXIT
25980
25981         sleep 5
25982
25983         for i in $(seq $((MDSCOUNT * 125))); do
25984                 local t=$DIR/$tdir/$tfile_$i
25985
25986                 dd if=/dev/zero of=$t bs=4K count=1 > /dev/null 2>&1 ||
25987                         error_noexit "Create file $t"
25988         done
25989         stack_trap "rm -rf $DIR/$tdir" EXIT
25990
25991         for oscparam in $($LCTL list_param ldlm.namespaces.*osc-[-0-9a-f]*); do
25992                 local lru_size=$($LCTL get_param -n $oscparam.lru_size)
25993                 local lock_count=$($LCTL get_param -n $oscparam.lock_count)
25994
25995                 [ $lock_count -le $lru_size ] ||
25996                         error "osc lock count $lock_count > lru size $lru_size"
25997         done
25998
25999         for mdcparam in $($LCTL list_param ldlm.namespaces.*mdc-*); do
26000                 local lru_size=$($LCTL get_param -n $mdcparam.lru_size)
26001                 local lock_count=$($LCTL get_param -n $mdcparam.lock_count)
26002
26003                 [ $lock_count -le $lru_size ] ||
26004                         error "mdc lock count $lock_count > lru size $lru_size"
26005         done
26006 }
26007 run_test 425 "lock count should not exceed lru size"
26008
26009 test_426() {
26010         splice-test -r $DIR/$tfile
26011         splice-test -rd $DIR/$tfile
26012         splice-test $DIR/$tfile
26013         splice-test -d $DIR/$tfile
26014 }
26015 run_test 426 "splice test on Lustre"
26016
26017 test_427() {
26018         [ $MDSCOUNT -ge 2 ] || skip "needs >= 2 MDTs"
26019         (( $MDS1_VERSION >= $(version_code 2.12.4) )) ||
26020                 skip "Need MDS version at least 2.12.4"
26021         local log
26022
26023         mkdir $DIR/$tdir
26024         mkdir $DIR/$tdir/1
26025         mkdir $DIR/$tdir/2
26026         test_mkdir -c $MDSCOUNT -i 1 $DIR/$tdir/1/dir
26027         test_mkdir -c $MDSCOUNT -i 1 $DIR/$tdir/2/dir2
26028
26029         $LFS getdirstripe $DIR/$tdir/1/dir
26030
26031         #first setfattr for creating updatelog
26032         setfattr -n user.attr0 -v "some text" $DIR/$tdir/1/dir
26033
26034 #define OBD_FAIL_OUT_OBJECT_MISS        0x1708
26035         do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param fail_loc=0x80001708
26036         setfattr -n user.attr1 -v "some text" $DIR/$tdir/1/dir &
26037         setfattr -n user.attr2 -v "another attr"  $DIR/$tdir/2/dir2 &
26038
26039         sleep 2
26040         fail mds2
26041         wait_recovery_complete mds2 $((2*TIMEOUT))
26042
26043         log=$(do_facet mds1 dmesg | tac | sed "/${TESTNAME//_/ }/,$ d")
26044         echo $log | grep "get update log failed" &&
26045                 error "update log corruption is detected" || true
26046 }
26047 run_test 427 "Failed DNE2 update request shouldn't corrupt updatelog"
26048
26049 test_428() {
26050         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26051         local cache_limit=$CACHE_MAX
26052
26053         stack_trap "$LCTL set_param -n llite.*.max_cached_mb=$cache_limit"
26054         $LCTL set_param -n llite.*.max_cached_mb=64
26055
26056         mkdir $DIR/$tdir
26057         $LFS setstripe -c 1 $DIR/$tdir
26058         eval touch $DIR/$tdir/$tfile.{1..$OSTCOUNT}
26059         stack_trap "rm -f $DIR/$tdir/$tfile.*"
26060         #test write
26061         for f in $(seq 4); do
26062                 dd if=/dev/zero of=$DIR/$tdir/$tfile.$f bs=128M count=1 &
26063         done
26064         wait
26065
26066         cancel_lru_locks osc
26067         # Test read
26068         for f in $(seq 4); do
26069                 dd if=$DIR/$tdir/$tfile.$f of=/dev/null bs=128M count=1 &
26070         done
26071         wait
26072 }
26073 run_test 428 "large block size IO should not hang"
26074
26075 test_429() { # LU-7915 / LU-10948
26076         local ll_opencache_threshold_count="llite.*.opencache_threshold_count"
26077         local testfile=$DIR/$tfile
26078         local mdc_rpcstats="mdc.$FSNAME-MDT0000-*.stats"
26079         local new_flag=1
26080         local first_rpc
26081         local second_rpc
26082         local third_rpc
26083
26084         $LCTL get_param $ll_opencache_threshold_count ||
26085                 skip "client does not have opencache parameter"
26086
26087         set_opencache $new_flag
26088         stack_trap "restore_opencache"
26089         [ $($LCTL get_param -n $ll_opencache_threshold_count) == $new_flag ] ||
26090                 error "enable opencache failed"
26091         touch $testfile
26092         # drop MDC DLM locks
26093         cancel_lru_locks mdc
26094         # clear MDC RPC stats counters
26095         $LCTL set_param $mdc_rpcstats=clear
26096
26097         # According to the current implementation, we need to run 3 times
26098         # open & close file to verify if opencache is enabled correctly.
26099         # 1st, RPCs are sent for lookup/open and open handle is released on
26100         #      close finally.
26101         # 2nd, RPC is sent for open, MDS_OPEN_LOCK is fetched automatically,
26102         #      so open handle won't be released thereafter.
26103         # 3rd, No RPC is sent out.
26104         $MULTIOP $testfile oc || error "multiop failed"
26105         first_rpc=$(calc_stats $mdc_rpcstats ldlm_ibits_enqueue)
26106         echo "1st: $first_rpc RPCs in flight"
26107
26108         $MULTIOP $testfile oc || error "multiop failed"
26109         second_rpc=$(calc_stats $mdc_rpcstats ldlm_ibits_enqueue)
26110         echo "2nd: $second_rpc RPCs in flight"
26111
26112         $MULTIOP $testfile oc || error "multiop failed"
26113         third_rpc=$(calc_stats $mdc_rpcstats ldlm_ibits_enqueue)
26114         echo "3rd: $third_rpc RPCs in flight"
26115
26116         #verify no MDC RPC is sent
26117         [[ $second_rpc == $third_rpc ]] || error "MDC RPC is still sent"
26118 }
26119 run_test 429 "verify if opencache flag on client side does work"
26120
26121 lseek_test_430() {
26122         local offset
26123         local file=$1
26124
26125         # data at [200K, 400K)
26126         dd if=/dev/urandom of=$file bs=256K count=1 seek=1 ||
26127                 error "256K->512K dd fails"
26128         # data at [2M, 3M)
26129         dd if=/dev/urandom of=$file bs=1M count=1 seek=2 ||
26130                 error "2M->3M dd fails"
26131         # data at [4M, 5M)
26132         dd if=/dev/urandom of=$file bs=1M count=1 seek=4 ||
26133                 error "4M->5M dd fails"
26134         echo "Data at 256K...512K, 2M...3M and 4M...5M"
26135         # start at first component hole #1
26136         printf "Seeking hole from 1000 ... "
26137         offset=$(lseek_test -l 1000 $file)
26138         echo $offset
26139         [[ $offset == 1000 ]] || error "offset $offset != 1000"
26140         printf "Seeking data from 1000 ... "
26141         offset=$(lseek_test -d 1000 $file)
26142         echo $offset
26143         [[ $offset == 262144 ]] || error "offset $offset != 262144"
26144
26145         # start at first component data block
26146         printf "Seeking hole from 300000 ... "
26147         offset=$(lseek_test -l 300000 $file)
26148         echo $offset
26149         [[ $offset == 524288 ]] || error "offset $offset != 524288"
26150         printf "Seeking data from 300000 ... "
26151         offset=$(lseek_test -d 300000 $file)
26152         echo $offset
26153         [[ $offset == 300000 ]] || error "offset $offset != 300000"
26154
26155         # start at the first component but beyond end of object size
26156         printf "Seeking hole from 1000000 ... "
26157         offset=$(lseek_test -l 1000000 $file)
26158         echo $offset
26159         [[ $offset == 1000000 ]] || error "offset $offset != 1000000"
26160         printf "Seeking data from 1000000 ... "
26161         offset=$(lseek_test -d 1000000 $file)
26162         echo $offset
26163         [[ $offset == 2097152 ]] || error "offset $offset != 2097152"
26164
26165         # start at second component stripe 2 (empty file)
26166         printf "Seeking hole from 1500000 ... "
26167         offset=$(lseek_test -l 1500000 $file)
26168         echo $offset
26169         [[ $offset == 1500000 ]] || error "offset $offset != 1500000"
26170         printf "Seeking data from 1500000 ... "
26171         offset=$(lseek_test -d 1500000 $file)
26172         echo $offset
26173         [[ $offset == 2097152 ]] || error "offset $offset != 2097152"
26174
26175         # start at second component stripe 1 (all data)
26176         printf "Seeking hole from 3000000 ... "
26177         offset=$(lseek_test -l 3000000 $file)
26178         echo $offset
26179         [[ $offset == 3145728 ]] || error "offset $offset != 3145728"
26180         printf "Seeking data from 3000000 ... "
26181         offset=$(lseek_test -d 3000000 $file)
26182         echo $offset
26183         [[ $offset == 3000000 ]] || error "offset $offset != 3000000"
26184
26185         dd if=/dev/urandom of=$file bs=640K count=1 seek=1 ||
26186                 error "2nd dd fails"
26187         echo "Add data block at 640K...1280K"
26188
26189         # start at before new data block, in hole
26190         printf "Seeking hole from 600000 ... "
26191         offset=$(lseek_test -l 600000 $file)
26192         echo $offset
26193         [[ $offset == 600000 ]] || error "offset $offset != 600000"
26194         printf "Seeking data from 600000 ... "
26195         offset=$(lseek_test -d 600000 $file)
26196         echo $offset
26197         [[ $offset == 655360 ]] || error "offset $offset != 655360"
26198
26199         # start at the first component new data block
26200         printf "Seeking hole from 1000000 ... "
26201         offset=$(lseek_test -l 1000000 $file)
26202         echo $offset
26203         [[ $offset == 1310720 ]] || error "offset $offset != 1310720"
26204         printf "Seeking data from 1000000 ... "
26205         offset=$(lseek_test -d 1000000 $file)
26206         echo $offset
26207         [[ $offset == 1000000 ]] || error "offset $offset != 1000000"
26208
26209         # start at second component stripe 2, new data
26210         printf "Seeking hole from 1200000 ... "
26211         offset=$(lseek_test -l 1200000 $file)
26212         echo $offset
26213         [[ $offset == 1310720 ]] || error "offset $offset != 1310720"
26214         printf "Seeking data from 1200000 ... "
26215         offset=$(lseek_test -d 1200000 $file)
26216         echo $offset
26217         [[ $offset == 1200000 ]] || error "offset $offset != 1200000"
26218
26219         # start beyond file end
26220         printf "Using offset > filesize ... "
26221         lseek_test -l 4000000 $file && error "lseek should fail"
26222         printf "Using offset > filesize ... "
26223         lseek_test -d 4000000 $file && error "lseek should fail"
26224
26225         printf "Done\n\n"
26226 }
26227
26228 test_430a() {
26229         $LCTL get_param mdc.*.import | grep -q 'connect_flags:.*seek' ||
26230                 skip "MDT does not support SEEK_HOLE"
26231
26232         $LCTL get_param osc.*.import | grep -q 'connect_flags:.*seek' ||
26233                 skip "OST does not support SEEK_HOLE"
26234
26235         local file=$DIR/$tdir/$tfile
26236
26237         mkdir -p $DIR/$tdir
26238
26239         $LFS setstripe -E 1M -L mdt -E eof -c2 $file
26240         # OST stripe #1 will have continuous data at [1M, 3M)
26241         # OST stripe #2 is empty
26242         echo "Component #1: 1M DoM, component #2: EOF, 2 stripes 1M"
26243         lseek_test_430 $file
26244         rm $file
26245         $LFS setstripe -E 1M -c2 -S 64K -E 10M -c2 -S 1M $file
26246         echo "Component #1: 1M, 2 stripes 64K, component #2: EOF, 2 stripes 1M"
26247         lseek_test_430 $file
26248         rm $file
26249         $LFS setstripe -c2 -S 512K $file
26250         echo "Two stripes, stripe size 512K"
26251         lseek_test_430 $file
26252         rm $file
26253         # FLR with stale mirror
26254         $LFS setstripe -N -E 512K -c1 -S 64K -E eof -c2 -S 512K \
26255                        -N -c2 -S 1M $file
26256         echo "Mirrored file:"
26257         echo "Component #1: 512K, stripe 64K, component #2: EOF, 2 stripes 512K"
26258         echo "Plain 2 stripes 1M"
26259         lseek_test_430 $file
26260         rm $file
26261 }
26262 run_test 430a "lseek: SEEK_DATA/SEEK_HOLE basic functionality"
26263
26264 test_430b() {
26265         $LCTL get_param osc.*.import | grep -q 'connect_flags:.*seek' ||
26266                 skip "OST does not support SEEK_HOLE"
26267
26268         local offset
26269         local file=$DIR/$tdir/$tfile
26270
26271         mkdir -p $DIR/$tdir
26272         # Empty layout lseek should fail
26273         $MCREATE $file
26274         # seek from 0
26275         printf "Seeking hole from 0 ... "
26276         lseek_test -l 0 $file && error "lseek should fail"
26277         printf "Seeking data from 0 ... "
26278         lseek_test -d 0 $file && error "lseek should fail"
26279         rm $file
26280
26281         # 1M-hole file
26282         $LFS setstripe -E 1M -c2 -E eof $file
26283         $TRUNCATE $file 1048576
26284         printf "Seeking hole from 1000000 ... "
26285         offset=$(lseek_test -l 1000000 $file)
26286         echo $offset
26287         [[ $offset == 1000000 ]] || error "offset $offset != 1000000"
26288         printf "Seeking data from 1000000 ... "
26289         lseek_test -d 1000000 $file && error "lseek should fail"
26290         rm $file
26291
26292         # full component followed by non-inited one
26293         $LFS setstripe -E 1M -c2 -E eof $file
26294         dd if=/dev/urandom of=$file bs=1M count=1
26295         printf "Seeking hole from 1000000 ... "
26296         offset=$(lseek_test -l 1000000 $file)
26297         echo $offset
26298         [[ $offset == 1048576 ]] || error "offset $offset != 1048576"
26299         printf "Seeking hole from 1048576 ... "
26300         lseek_test -l 1048576 $file && error "lseek should fail"
26301         # init second component and truncate back
26302         echo "123" >> $file
26303         $TRUNCATE $file 1048576
26304         printf "Seeking hole from 1000000 ... "
26305         offset=$(lseek_test -l 1000000 $file)
26306         echo $offset
26307         [[ $offset == 1048576 ]] || error "offset $offset != 1048576"
26308         printf "Seeking hole from 1048576 ... "
26309         lseek_test -l 1048576 $file && error "lseek should fail"
26310         # boundary checks for big values
26311         dd if=/dev/urandom of=$file.10g bs=1 count=1 seek=10G
26312         offset=$(lseek_test -d 0 $file.10g)
26313         [[ $offset == 10737418240 ]] || error "offset $offset != 10737418240"
26314         dd if=/dev/urandom of=$file.100g bs=1 count=1 seek=100G
26315         offset=$(lseek_test -d 0 $file.100g)
26316         [[ $offset == 107374182400 ]] || error "offset $offset != 107374182400"
26317         return 0
26318 }
26319 run_test 430b "lseek: SEEK_DATA/SEEK_HOLE special cases"
26320
26321 test_430c() {
26322         $LCTL get_param osc.*.import | grep -q 'connect_flags:.*seek' ||
26323                 skip "OST does not support SEEK_HOLE"
26324
26325         local file=$DIR/$tdir/$tfile
26326         local start
26327
26328         mkdir -p $DIR/$tdir
26329         dd if=/dev/urandom of=$file bs=1k count=1 seek=5M
26330
26331         # cp version 8.33+ prefers lseek over fiemap
26332         if [[ $(cp --version | head -n1 | sed "s/[^0-9]//g") -ge 833 ]]; then
26333                 start=$SECONDS
26334                 time cp $file /dev/null
26335                 (( SECONDS - start < 5 )) ||
26336                         error "cp: too long runtime $((SECONDS - start))"
26337
26338         fi
26339         # tar version 1.29+ supports SEEK_HOLE/DATA
26340         if [[ $(tar --version | head -n1 | sed "s/[^0-9]//g") -ge 129 ]]; then
26341                 start=$SECONDS
26342                 time tar cS $file - | cat > /dev/null
26343                 (( SECONDS - start < 5 )) ||
26344                         error "tar: too long runtime $((SECONDS - start))"
26345         fi
26346 }
26347 run_test 430c "lseek: external tools check"
26348
26349 test_431() { # LU-14187
26350         local file=$DIR/$tdir/$tfile
26351
26352         mkdir -p $DIR/$tdir
26353         $LFS setstripe -c 1 -i 0 $file || error "lfs setstripe failed"
26354         dd if=/dev/urandom of=$file bs=4k count=1
26355         dd if=/dev/urandom of=$file bs=4k count=1 seek=10 conv=notrunc
26356         dd if=/dev/urandom of=$file bs=4k count=1 seek=12 conv=notrunc
26357         #define OBD_FAIL_OST_RESTART_IO 0x251
26358         do_facet ost1 "$LCTL set_param fail_loc=0x251"
26359         $LFS setstripe -c 1 -i 0 $file.0 || error "lfs setstripe failed"
26360         cp $file $file.0
26361         cancel_lru_locks
26362         sync_all_data
26363         echo 3 > /proc/sys/vm/drop_caches
26364         diff  $file $file.0 || error "data diff"
26365 }
26366 run_test 431 "Restart transaction for IO"
26367
26368 cleanup_test_432() {
26369         do_facet mgs $LCTL nodemap_activate 0
26370         wait_nm_sync active
26371 }
26372
26373 test_432() {
26374         local tmpdir=$TMP/dir432
26375
26376         (( $MDS1_VERSION >= $(version_code 2.14.52) )) ||
26377                 skip "Need MDS version at least 2.14.52"
26378
26379         stack_trap cleanup_test_432 EXIT
26380         mkdir $DIR/$tdir
26381         mkdir $tmpdir
26382
26383         do_facet mgs $LCTL nodemap_activate 1
26384         wait_nm_sync active
26385         do_facet mgs $LCTL nodemap_modify --name default \
26386                 --property admin --value 1
26387         do_facet mgs $LCTL nodemap_modify --name default \
26388                 --property trusted --value 1
26389         cancel_lru_locks mdc
26390         wait_nm_sync default admin_nodemap
26391         wait_nm_sync default trusted_nodemap
26392
26393         if [ $(mv $tmpdir $DIR/$tdir/ 2>&1 |
26394                grep -ci "Operation not permitted") -ne 0 ]; then
26395                 error "mv $tmpdir $DIR/$tdir/ hits 'Operation not permitted'"
26396         fi
26397 }
26398 run_test 432 "mv dir from outside Lustre"
26399
26400 prep_801() {
26401         [[ $MDS1_VERSION -lt $(version_code 2.9.55) ]] ||
26402         [[ $OST1_VERSION -lt $(version_code 2.9.55) ]] &&
26403                 skip "Need server version at least 2.9.55"
26404
26405         start_full_debug_logging
26406 }
26407
26408 post_801() {
26409         stop_full_debug_logging
26410 }
26411
26412 barrier_stat() {
26413         if [ $MGS_VERSION -le $(version_code 2.10.0) ]; then
26414                 local st=$(do_facet mgs $LCTL barrier_stat $FSNAME |
26415                            awk '/The barrier for/ { print $7 }')
26416                 echo $st
26417         else
26418                 local st=$(do_facet mgs $LCTL barrier_stat -s $FSNAME)
26419                 echo \'$st\'
26420         fi
26421 }
26422
26423 barrier_expired() {
26424         local expired
26425
26426         if [ $MGS_VERSION -le $(version_code 2.10.0) ]; then
26427                 expired=$(do_facet mgs $LCTL barrier_stat $FSNAME |
26428                           awk '/will be expired/ { print $7 }')
26429         else
26430                 expired=$(do_facet mgs $LCTL barrier_stat -t $FSNAME)
26431         fi
26432
26433         echo $expired
26434 }
26435
26436 test_801a() {
26437         prep_801
26438
26439         echo "Start barrier_freeze at: $(date)"
26440         #define OBD_FAIL_BARRIER_DELAY          0x2202
26441         do_facet mgs $LCTL set_param fail_val=5 fail_loc=0x2202
26442         # Do not reduce barrier time - See LU-11873
26443         do_facet mgs $LCTL barrier_freeze $FSNAME 20 &
26444
26445         sleep 2
26446         local b_status=$(barrier_stat)
26447         echo "Got barrier status at: $(date)"
26448         [ "$b_status" = "'freezing_p1'" ] ||
26449                 error "(1) unexpected barrier status $b_status"
26450
26451         do_facet mgs $LCTL set_param fail_val=0 fail_loc=0
26452         wait
26453         b_status=$(barrier_stat)
26454         [ "$b_status" = "'frozen'" ] ||
26455                 error "(2) unexpected barrier status $b_status"
26456
26457         local expired=$(barrier_expired)
26458         echo "sleep $((expired + 3)) seconds, then the barrier will be expired"
26459         sleep $((expired + 3))
26460
26461         b_status=$(barrier_stat)
26462         [ "$b_status" = "'expired'" ] ||
26463                 error "(3) unexpected barrier status $b_status"
26464
26465         # Do not reduce barrier time - See LU-11873
26466         do_facet mgs $LCTL barrier_freeze $FSNAME 20 ||
26467                 error "(4) fail to freeze barrier"
26468
26469         b_status=$(barrier_stat)
26470         [ "$b_status" = "'frozen'" ] ||
26471                 error "(5) unexpected barrier status $b_status"
26472
26473         echo "Start barrier_thaw at: $(date)"
26474         #define OBD_FAIL_BARRIER_DELAY          0x2202
26475         do_facet mgs $LCTL set_param fail_val=5 fail_loc=0x2202
26476         do_facet mgs $LCTL barrier_thaw $FSNAME &
26477
26478         sleep 2
26479         b_status=$(barrier_stat)
26480         echo "Got barrier status at: $(date)"
26481         [ "$b_status" = "'thawing'" ] ||
26482                 error "(6) unexpected barrier status $b_status"
26483
26484         do_facet mgs $LCTL set_param fail_val=0 fail_loc=0
26485         wait
26486         b_status=$(barrier_stat)
26487         [ "$b_status" = "'thawed'" ] ||
26488                 error "(7) unexpected barrier status $b_status"
26489
26490         #define OBD_FAIL_BARRIER_FAILURE        0x2203
26491         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2203
26492         do_facet mgs $LCTL barrier_freeze $FSNAME
26493
26494         b_status=$(barrier_stat)
26495         [ "$b_status" = "'failed'" ] ||
26496                 error "(8) unexpected barrier status $b_status"
26497
26498         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
26499         do_facet mgs $LCTL barrier_thaw $FSNAME
26500
26501         post_801
26502 }
26503 run_test 801a "write barrier user interfaces and stat machine"
26504
26505 test_801b() {
26506         prep_801
26507
26508         mkdir $DIR/$tdir || error "(1) fail to mkdir"
26509         createmany -d $DIR/$tdir/d 6 || "(2) fail to mkdir"
26510         touch $DIR/$tdir/d2/f10 || error "(3) fail to touch"
26511         touch $DIR/$tdir/d3/f11 || error "(4) fail to touch"
26512         touch $DIR/$tdir/d4/f12 || error "(5) fail to touch"
26513
26514         cancel_lru_locks mdc
26515
26516         # 180 seconds should be long enough
26517         do_facet mgs $LCTL barrier_freeze $FSNAME 180
26518
26519         local b_status=$(barrier_stat)
26520         [ "$b_status" = "'frozen'" ] ||
26521                 error "(6) unexpected barrier status $b_status"
26522
26523         mkdir $DIR/$tdir/d0/d10 &
26524         mkdir_pid=$!
26525
26526         touch $DIR/$tdir/d1/f13 &
26527         touch_pid=$!
26528
26529         ln $DIR/$tdir/d2/f10 $DIR/$tdir/d2/f14 &
26530         ln_pid=$!
26531
26532         mv $DIR/$tdir/d3/f11 $DIR/$tdir/d3/f15 &
26533         mv_pid=$!
26534
26535         rm -f $DIR/$tdir/d4/f12 &
26536         rm_pid=$!
26537
26538         stat $DIR/$tdir/d5 || error "(7) stat should succeed"
26539
26540         # To guarantee taht the 'stat' is not blocked
26541         b_status=$(barrier_stat)
26542         [ "$b_status" = "'frozen'" ] ||
26543                 error "(8) unexpected barrier status $b_status"
26544
26545         # let above commands to run at background
26546         sleep 5
26547
26548         ps -p $mkdir_pid || error "(9) mkdir should be blocked"
26549         ps -p $touch_pid || error "(10) touch should be blocked"
26550         ps -p $ln_pid || error "(11) link should be blocked"
26551         ps -p $mv_pid || error "(12) rename should be blocked"
26552         ps -p $rm_pid || error "(13) unlink should be blocked"
26553
26554         b_status=$(barrier_stat)
26555         [ "$b_status" = "'frozen'" ] ||
26556                 error "(14) unexpected barrier status $b_status"
26557
26558         do_facet mgs $LCTL barrier_thaw $FSNAME
26559         b_status=$(barrier_stat)
26560         [ "$b_status" = "'thawed'" ] ||
26561                 error "(15) unexpected barrier status $b_status"
26562
26563         wait $mkdir_pid || error "(16) mkdir should succeed"
26564         wait $touch_pid || error "(17) touch should succeed"
26565         wait $ln_pid || error "(18) link should succeed"
26566         wait $mv_pid || error "(19) rename should succeed"
26567         wait $rm_pid || error "(20) unlink should succeed"
26568
26569         post_801
26570 }
26571 run_test 801b "modification will be blocked by write barrier"
26572
26573 test_801c() {
26574         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
26575
26576         prep_801
26577
26578         stop mds2 || error "(1) Fail to stop mds2"
26579
26580         do_facet mgs $LCTL barrier_freeze $FSNAME 30
26581
26582         local b_status=$(barrier_stat)
26583         [ "$b_status" = "'expired'" ] || [ "$b_status" = "'failed'" ] || {
26584                 do_facet mgs $LCTL barrier_thaw $FSNAME
26585                 error "(2) unexpected barrier status $b_status"
26586         }
26587
26588         do_facet mgs $LCTL barrier_rescan $FSNAME ||
26589                 error "(3) Fail to rescan barrier bitmap"
26590
26591         # Do not reduce barrier time - See LU-11873
26592         do_facet mgs $LCTL barrier_freeze $FSNAME 20
26593
26594         b_status=$(barrier_stat)
26595         [ "$b_status" = "'frozen'" ] ||
26596                 error "(4) unexpected barrier status $b_status"
26597
26598         do_facet mgs $LCTL barrier_thaw $FSNAME
26599         b_status=$(barrier_stat)
26600         [ "$b_status" = "'thawed'" ] ||
26601                 error "(5) unexpected barrier status $b_status"
26602
26603         local devname=$(mdsdevname 2)
26604
26605         start mds2 $devname $MDS_MOUNT_OPTS || error "(6) Fail to start mds2"
26606
26607         do_facet mgs $LCTL barrier_rescan $FSNAME ||
26608                 error "(7) Fail to rescan barrier bitmap"
26609
26610         post_801
26611 }
26612 run_test 801c "rescan barrier bitmap"
26613
26614 saved_MGS_MOUNT_OPTS=$MGS_MOUNT_OPTS
26615 saved_MDS_MOUNT_OPTS=$MDS_MOUNT_OPTS
26616 saved_OST_MOUNT_OPTS=$OST_MOUNT_OPTS
26617 saved_MOUNT_OPTS=$MOUNT_OPTS
26618
26619 cleanup_802a() {
26620         trap 0
26621
26622         stopall
26623         MGS_MOUNT_OPTS=$saved_MGS_MOUNT_OPTS
26624         MDS_MOUNT_OPTS=$saved_MDS_MOUNT_OPTS
26625         OST_MOUNT_OPTS=$saved_OST_MOUNT_OPTS
26626         MOUNT_OPTS=$saved_MOUNT_OPTS
26627         setupall
26628 }
26629
26630 test_802a() {
26631         [[ $mds1_FSTYPE = zfs ]] || skip "ZFS specific test"
26632         [[ $MDS1_VERSION -lt $(version_code 2.9.55) ]] ||
26633         [[ $OST1_VERSION -lt $(version_code 2.9.55) ]] &&
26634                 skip "Need server version at least 2.9.55"
26635
26636         [[ $ENABLE_QUOTA ]] && skip "Quota enabled for read-only test"
26637
26638         mkdir $DIR/$tdir || error "(1) fail to mkdir"
26639
26640         cp $LUSTRE/tests/test-framework.sh $DIR/$tdir/ ||
26641                 error "(2) Fail to copy"
26642
26643         trap cleanup_802a EXIT
26644
26645         # sync by force before remount as readonly
26646         sync; sync_all_data; sleep 3; sync_all_data
26647
26648         stopall
26649
26650         MGS_MOUNT_OPTS=$(csa_add "$MGS_MOUNT_OPTS" -o rdonly_dev)
26651         MDS_MOUNT_OPTS=$(csa_add "$MDS_MOUNT_OPTS" -o rdonly_dev)
26652         OST_MOUNT_OPTS=$(csa_add "$OST_MOUNT_OPTS" -o rdonly_dev)
26653
26654         echo "Mount the server as read only"
26655         setupall server_only || error "(3) Fail to start servers"
26656
26657         echo "Mount client without ro should fail"
26658         mount_client $MOUNT &&
26659                 error "(4) Mount client without 'ro' should fail"
26660
26661         echo "Mount client with ro should succeed"
26662         MOUNT_OPTS=$(csa_add "$MOUNT_OPTS" -o ro)
26663         mount_client $MOUNT ||
26664                 error "(5) Mount client with 'ro' should succeed"
26665
26666         echo "Modify should be refused"
26667         touch $DIR/$tdir/guard && error "(6) Touch should fail under ro mode"
26668
26669         echo "Read should be allowed"
26670         diff $LUSTRE/tests/test-framework.sh $DIR/$tdir/test-framework.sh ||
26671                 error "(7) Read should succeed under ro mode"
26672
26673         cleanup_802a
26674 }
26675 run_test 802a "simulate readonly device"
26676
26677 test_802b() {
26678         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26679         remote_mds_nodsh && skip "remote MDS with nodsh"
26680
26681         do_facet $SINGLEMDS $LCTL get_param mdt.*.readonly ||
26682                 skip "readonly option not available"
26683
26684         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "(1) fail to mkdir"
26685
26686         cp $LUSTRE/tests/test-framework.sh $DIR/$tdir/ ||
26687                 error "(2) Fail to copy"
26688
26689         # write back all cached data before setting MDT to readonly
26690         cancel_lru_locks
26691         sync_all_data
26692
26693         do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=1
26694         stack_trap "do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=0" EXIT
26695
26696         echo "Modify should be refused"
26697         touch $DIR/$tdir/guard && error "(6) Touch should fail under ro mode"
26698
26699         echo "Read should be allowed"
26700         diff $LUSTRE/tests/test-framework.sh $DIR/$tdir/test-framework.sh ||
26701                 error "(7) Read should succeed under ro mode"
26702
26703         # disable readonly
26704         do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=0
26705 }
26706 run_test 802b "be able to set MDTs to readonly"
26707
26708 test_803a() {
26709         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
26710         [ $MDS1_VERSION -lt $(version_code 2.10.54) ] &&
26711                 skip "MDS needs to be newer than 2.10.54"
26712
26713         mkdir_on_mdt0 $DIR/$tdir
26714         # Create some objects on all MDTs to trigger related logs objects
26715         for idx in $(seq $MDSCOUNT); do
26716                 $LFS mkdir -c $MDSCOUNT -i $((idx % $MDSCOUNT)) \
26717                         $DIR/$tdir/dir${idx} ||
26718                         error "Fail to create $DIR/$tdir/dir${idx}"
26719         done
26720
26721         sync; sleep 3
26722         wait_delete_completed # ensure old test cleanups are finished
26723         echo "before create:"
26724         $LFS df -i $MOUNT
26725         local before_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
26726
26727         for i in {1..10}; do
26728                 $LFS mkdir -c 1 -i 1 $DIR/$tdir/foo$i ||
26729                         error "Fail to create $DIR/$tdir/foo$i"
26730         done
26731
26732         sync; sleep 3
26733         echo "after create:"
26734         $LFS df -i $MOUNT
26735         local after_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
26736
26737         # allow for an llog to be cleaned up during the test
26738         [ $after_used -ge $((before_used + 10 - 1)) ] ||
26739                 error "before ($before_used) + 10 > after ($after_used)"
26740
26741         for i in {1..10}; do
26742                 rm -rf $DIR/$tdir/foo$i ||
26743                         error "Fail to remove $DIR/$tdir/foo$i"
26744         done
26745
26746         sleep 3 # avoid MDT return cached statfs
26747         wait_delete_completed
26748         echo "after unlink:"
26749         $LFS df -i $MOUNT
26750         after_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
26751
26752         # allow for an llog to be created during the test
26753         [ $after_used -le $((before_used + 1)) ] ||
26754                 error "after ($after_used) > before ($before_used) + 1"
26755 }
26756 run_test 803a "verify agent object for remote object"
26757
26758 test_803b() {
26759         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
26760         [ $MDS1_VERSION -lt $(version_code 2.13.56) ] &&
26761                 skip "MDS needs to be newer than 2.13.56"
26762         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26763
26764         for i in $(seq 0 $((MDSCOUNT - 1))); do
26765                 $LFS mkdir -i $i $DIR/$tdir.$i || error "mkdir $tdir.$i"
26766         done
26767
26768         local before=0
26769         local after=0
26770
26771         local tmp
26772
26773         stat $DIR/$tdir.* >/dev/null || error "stat $tdir.*"
26774         for i in $(seq 0 $((MDSCOUNT - 1))); do
26775                 tmp=$(do_facet mds$i $LCTL get_param mdt.*-MDT000$i.md_stats |
26776                         awk '/getattr/ { print $2 }')
26777                 before=$((before + tmp))
26778         done
26779         stat $DIR/$tdir.* >/dev/null || error "stat $tdir.*"
26780         for i in $(seq 0 $((MDSCOUNT - 1))); do
26781                 tmp=$(do_facet mds$i $LCTL get_param mdt.*-MDT000$i.md_stats |
26782                         awk '/getattr/ { print $2 }')
26783                 after=$((after + tmp))
26784         done
26785
26786         [ $before -eq $after ] || error "getattr count $before != $after"
26787 }
26788 run_test 803b "remote object can getattr from cache"
26789
26790 test_804() {
26791         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
26792         [ $MDS1_VERSION -lt $(version_code 2.10.54) ] &&
26793                 skip "MDS needs to be newer than 2.10.54"
26794         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
26795
26796         mkdir -p $DIR/$tdir
26797         $LFS mkdir -c 1 -i 1 $DIR/$tdir/dir0 ||
26798                 error "Fail to create $DIR/$tdir/dir0"
26799
26800         local fid=$($LFS path2fid $DIR/$tdir/dir0)
26801         local dev=$(mdsdevname 2)
26802
26803         do_facet mds2 "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
26804                 grep ${fid} || error "NOT found agent entry for dir0"
26805
26806         $LFS mkdir -c $MDSCOUNT -i 0 $DIR/$tdir/dir1 ||
26807                 error "Fail to create $DIR/$tdir/dir1"
26808
26809         touch $DIR/$tdir/dir1/foo0 ||
26810                 error "Fail to create $DIR/$tdir/dir1/foo0"
26811         fid=$($LFS path2fid $DIR/$tdir/dir1/foo0)
26812         local rc=0
26813
26814         for idx in $(seq $MDSCOUNT); do
26815                 dev=$(mdsdevname $idx)
26816                 do_facet mds${idx} \
26817                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
26818                         grep ${fid} && rc=$idx
26819         done
26820
26821         mv $DIR/$tdir/dir1/foo0 $DIR/$tdir/dir1/foo1 ||
26822                 error "Fail to rename foo0 to foo1"
26823         if [ $rc -eq 0 ]; then
26824                 for idx in $(seq $MDSCOUNT); do
26825                         dev=$(mdsdevname $idx)
26826                         do_facet mds${idx} \
26827                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
26828                         grep ${fid} && rc=$idx
26829                 done
26830         fi
26831
26832         mv $DIR/$tdir/dir1/foo1 $DIR/$tdir/dir1/foo2 ||
26833                 error "Fail to rename foo1 to foo2"
26834         if [ $rc -eq 0 ]; then
26835                 for idx in $(seq $MDSCOUNT); do
26836                         dev=$(mdsdevname $idx)
26837                         do_facet mds${idx} \
26838                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
26839                         grep ${fid} && rc=$idx
26840                 done
26841         fi
26842
26843         [ $rc -ne 0 ] || error "NOT found agent entry for foo"
26844
26845         ln $DIR/$tdir/dir1/foo2 $DIR/$tdir/dir0/guard ||
26846                 error "Fail to link to $DIR/$tdir/dir1/foo2"
26847         mv $DIR/$tdir/dir1/foo2 $DIR/$tdir/dir1/foo0 ||
26848                 error "Fail to rename foo2 to foo0"
26849         unlink $DIR/$tdir/dir1/foo0 ||
26850                 error "Fail to unlink $DIR/$tdir/dir1/foo0"
26851         rm -rf $DIR/$tdir/dir0 ||
26852                 error "Fail to rm $DIR/$tdir/dir0"
26853
26854         for idx in $(seq $MDSCOUNT); do
26855                 dev=$(mdsdevname $idx)
26856                 rc=0
26857
26858                 stop mds${idx}
26859                 run_e2fsck $(facet_active_host mds$idx) $dev -n ||
26860                         rc=$?
26861                 start mds${idx} $dev $MDS_MOUNT_OPTS ||
26862                         error "mount mds$idx failed"
26863                 df $MOUNT > /dev/null 2>&1
26864
26865                 # e2fsck should not return error
26866                 [ $rc -eq 0 ] ||
26867                         error "e2fsck detected error on MDT${idx}: rc=$rc"
26868         done
26869 }
26870 run_test 804 "verify agent entry for remote entry"
26871
26872 cleanup_805() {
26873         do_facet $SINGLEMDS zfs set quota=$old $fsset
26874         unlinkmany $DIR/$tdir/f- 1000000
26875         trap 0
26876 }
26877
26878 test_805() {
26879         local zfs_version=$(do_facet mds1 cat /sys/module/zfs/version)
26880         [ "$mds1_FSTYPE" != "zfs" ] && skip "ZFS specific test"
26881         [ $(version_code $zfs_version) -lt $(version_code 0.7.2) ] &&
26882                 skip "netfree not implemented before 0.7"
26883         [[ $MDS1_VERSION -ge $(version_code 2.10.57) ]] ||
26884                 skip "Need MDS version at least 2.10.57"
26885
26886         local fsset
26887         local freekb
26888         local usedkb
26889         local old
26890         local quota
26891         local pref="osd-zfs.$FSNAME-MDT0000."
26892
26893         # limit available space on MDS dataset to meet nospace issue
26894         # quickly. then ZFS 0.7.2 can use reserved space if asked
26895         # properly (using netfree flag in osd_declare_destroy()
26896         fsset=$(do_facet $SINGLEMDS lctl get_param -n $pref.mntdev)
26897         old=$(do_facet $SINGLEMDS zfs get -H quota $fsset | \
26898                 gawk '{print $3}')
26899         freekb=$(do_facet $SINGLEMDS lctl get_param -n $pref.kbytesfree)
26900         usedkb=$(do_facet $SINGLEMDS lctl get_param -n $pref.kbytestotal)
26901         let "usedkb=usedkb-freekb"
26902         let "freekb=freekb/2"
26903         if let "freekb > 5000"; then
26904                 let "freekb=5000"
26905         fi
26906         do_facet $SINGLEMDS zfs set quota=$(((usedkb+freekb)*1024)) $fsset
26907         trap cleanup_805 EXIT
26908         mkdir_on_mdt0 $DIR/$tdir
26909         $LFS setstripe -E 1M -c2 -E 4M -c2 -E -1 -c2 $DIR/$tdir ||
26910                 error "Can't set PFL layout"
26911         createmany -m $DIR/$tdir/f- 1000000 && error "ENOSPC wasn't met"
26912         rm -rf $DIR/$tdir || error "not able to remove"
26913         do_facet $SINGLEMDS zfs set quota=$old $fsset
26914         trap 0
26915 }
26916 run_test 805 "ZFS can remove from full fs"
26917
26918 # Size-on-MDS test
26919 check_lsom_data()
26920 {
26921         local file=$1
26922         local expect=$(stat -c %s $file)
26923
26924         check_lsom_size $1 $expect
26925
26926         local blocks=$($LFS getsom -b $file)
26927         expect=$(stat -c %b $file)
26928         [[ $blocks == $expect ]] ||
26929                 error "$file expected blocks: $expect, got: $blocks"
26930 }
26931
26932 check_lsom_size()
26933 {
26934         local size
26935         local expect=$2
26936
26937         cancel_lru_locks mdc
26938
26939         size=$($LFS getsom -s $1)
26940         [[ $size == $expect ]] ||
26941                 error "$file expected size: $expect, got: $size"
26942 }
26943
26944 test_806() {
26945         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
26946                 skip "Need MDS version at least 2.11.52"
26947
26948         local bs=1048576
26949
26950         touch $DIR/$tfile || error "touch $tfile failed"
26951
26952         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
26953         save_lustre_params client "llite.*.xattr_cache" > $save
26954         lctl set_param llite.*.xattr_cache=0
26955         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
26956
26957         # single-threaded write
26958         echo "Test SOM for single-threaded write"
26959         dd if=/dev/zero of=$DIR/$tfile bs=$bs count=1 ||
26960                 error "write $tfile failed"
26961         check_lsom_size $DIR/$tfile $bs
26962
26963         local num=32
26964         local size=$(($num * $bs))
26965         local offset=0
26966         local i
26967
26968         echo "Test SOM for single client multi-threaded($num) write"
26969         $TRUNCATE $DIR/$tfile 0
26970         for ((i = 0; i < $num; i++)); do
26971                 $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
26972                 local pids[$i]=$!
26973                 offset=$((offset + $bs))
26974         done
26975         for (( i=0; i < $num; i++ )); do
26976                 wait ${pids[$i]}
26977         done
26978         check_lsom_size $DIR/$tfile $size
26979
26980         $TRUNCATE $DIR/$tfile 0
26981         for ((i = 0; i < $num; i++)); do
26982                 offset=$((offset - $bs))
26983                 $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
26984                 local pids[$i]=$!
26985         done
26986         for (( i=0; i < $num; i++ )); do
26987                 wait ${pids[$i]}
26988         done
26989         check_lsom_size $DIR/$tfile $size
26990
26991         # multi-client writes
26992         num=$(get_node_count ${CLIENTS//,/ })
26993         size=$(($num * $bs))
26994         offset=0
26995         i=0
26996
26997         echo "Test SOM for multi-client ($num) writes"
26998         $TRUNCATE $DIR/$tfile 0
26999         for client in ${CLIENTS//,/ }; do
27000                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
27001                 local pids[$i]=$!
27002                 i=$((i + 1))
27003                 offset=$((offset + $bs))
27004         done
27005         for (( i=0; i < $num; i++ )); do
27006                 wait ${pids[$i]}
27007         done
27008         check_lsom_size $DIR/$tfile $offset
27009
27010         i=0
27011         $TRUNCATE $DIR/$tfile 0
27012         for client in ${CLIENTS//,/ }; do
27013                 offset=$((offset - $bs))
27014                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
27015                 local pids[$i]=$!
27016                 i=$((i + 1))
27017         done
27018         for (( i=0; i < $num; i++ )); do
27019                 wait ${pids[$i]}
27020         done
27021         check_lsom_size $DIR/$tfile $size
27022
27023         # verify truncate
27024         echo "Test SOM for truncate"
27025         $TRUNCATE $DIR/$tfile 1048576
27026         check_lsom_size $DIR/$tfile 1048576
27027         $TRUNCATE $DIR/$tfile 1234
27028         check_lsom_size $DIR/$tfile 1234
27029
27030         # verify SOM blocks count
27031         echo "Verify SOM block count"
27032         $TRUNCATE $DIR/$tfile 0
27033         $MULTIOP $DIR/$tfile oO_TRUNC:O_RDWR:w1048576YSc ||
27034                 error "failed to write file $tfile"
27035         check_lsom_data $DIR/$tfile
27036 }
27037 run_test 806 "Verify Lazy Size on MDS"
27038
27039 test_807() {
27040         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
27041         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
27042                 skip "Need MDS version at least 2.11.52"
27043
27044         # Registration step
27045         changelog_register || error "changelog_register failed"
27046         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
27047         changelog_users $SINGLEMDS | grep -q $cl_user ||
27048                 error "User $cl_user not found in changelog_users"
27049
27050         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
27051         save_lustre_params client "llite.*.xattr_cache" > $save
27052         lctl set_param llite.*.xattr_cache=0
27053         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
27054
27055         rm -rf $DIR/$tdir || error "rm $tdir failed"
27056         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
27057         touch $DIR/$tdir/trunc || error "touch $tdir/trunc failed"
27058         $TRUNCATE $DIR/$tdir/trunc 1024 || error "truncate $tdir/trunc failed"
27059         $TRUNCATE $DIR/$tdir/trunc 1048576 ||
27060                 error "truncate $tdir/trunc failed"
27061
27062         local bs=1048576
27063         dd if=/dev/zero of=$DIR/$tdir/single_dd bs=$bs count=1 conv=fsync ||
27064                 error "write $tfile failed"
27065
27066         # multi-client wirtes
27067         local num=$(get_node_count ${CLIENTS//,/ })
27068         local offset=0
27069         local i=0
27070
27071         echo "Test SOM for multi-client ($num) writes"
27072         touch $DIR/$tfile || error "touch $tfile failed"
27073         $TRUNCATE $DIR/$tfile 0
27074         for client in ${CLIENTS//,/ }; do
27075                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
27076                 local pids[$i]=$!
27077                 i=$((i + 1))
27078                 offset=$((offset + $bs))
27079         done
27080         for (( i=0; i < $num; i++ )); do
27081                 wait ${pids[$i]}
27082         done
27083
27084         do_rpc_nodes "$CLIENTS" cancel_lru_locks osc
27085         do_nodes "$CLIENTS" "sync ; sleep 5 ; sync"
27086         $LSOM_SYNC -u $cl_user -m $FSNAME-MDT0000 $MOUNT
27087         check_lsom_data $DIR/$tdir/trunc
27088         check_lsom_data $DIR/$tdir/single_dd
27089         check_lsom_data $DIR/$tfile
27090
27091         rm -rf $DIR/$tdir
27092         # Deregistration step
27093         changelog_deregister || error "changelog_deregister failed"
27094 }
27095 run_test 807 "verify LSOM syncing tool"
27096
27097 check_som_nologged()
27098 {
27099         local lines=$($LFS changelog $FSNAME-MDT0000 |
27100                 grep 'x=trusted.som' | wc -l)
27101         [ $lines -ne 0 ] && error "trusted.som xattr is logged in Changelogs"
27102 }
27103
27104 test_808() {
27105         [ $MDS1_VERSION -lt $(version_code 2.11.55) ] &&
27106                 skip "Need MDS version at least 2.11.55"
27107
27108         # Registration step
27109         changelog_register || error "changelog_register failed"
27110
27111         touch $DIR/$tfile || error "touch $tfile failed"
27112         check_som_nologged
27113
27114         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=1 ||
27115                 error "write $tfile failed"
27116         check_som_nologged
27117
27118         $TRUNCATE $DIR/$tfile 1234
27119         check_som_nologged
27120
27121         $TRUNCATE $DIR/$tfile 1048576
27122         check_som_nologged
27123
27124         # Deregistration step
27125         changelog_deregister || error "changelog_deregister failed"
27126 }
27127 run_test 808 "Check trusted.som xattr not logged in Changelogs"
27128
27129 check_som_nodata()
27130 {
27131         $LFS getsom $1
27132         [[ $? -eq 61 ]] || error "DoM-only file $1 has SOM xattr"
27133 }
27134
27135 test_809() {
27136         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
27137                 skip "Need MDS version at least 2.11.56"
27138
27139         $LFS setstripe -E 1M -L mdt $DIR/$tfile ||
27140                 error "failed to create DoM-only file $DIR/$tfile"
27141         touch $DIR/$tfile || error "touch $tfile failed"
27142         check_som_nodata $DIR/$tfile
27143
27144         dd if=/dev/zero of=$DIR/$tfile bs=2048 count=1 ||
27145                 error "write $tfile failed"
27146         check_som_nodata $DIR/$tfile
27147
27148         $TRUNCATE $DIR/$tfile 1234
27149         check_som_nodata $DIR/$tfile
27150
27151         $TRUNCATE $DIR/$tfile 4097
27152         check_som_nodata $DIR/$file
27153 }
27154 run_test 809 "Verify no SOM xattr store for DoM-only files"
27155
27156 test_810() {
27157         [ $PARALLEL == "yes" ] && skip "skip parallel run"
27158         $GSS && skip_env "could not run with gss"
27159         [[ $OST1_VERSION -gt $(version_code 2.12.58) ]] ||
27160                 skip "OST < 2.12.58 doesn't align checksum"
27161
27162         set_checksums 1
27163         stack_trap "set_checksums $ORIG_CSUM" EXIT
27164         stack_trap "set_checksum_type $ORIG_CSUM_TYPE" EXIT
27165
27166         local csum
27167         local before
27168         local after
27169         for csum in $CKSUM_TYPES; do
27170                 #define OBD_FAIL_OSC_NO_GRANT   0x411
27171                 $LCTL set_param osc.*.checksum_type=$csum fail_loc=0x411
27172                 for i in "10240 0" "10000 0" "4000 1" "500 1"; do
27173                         eval set -- $i
27174                         dd if=/dev/urandom of=$DIR/$tfile bs=$1 count=2 seek=$2
27175                         before=$(md5sum $DIR/$tfile)
27176                         $LCTL set_param ldlm.namespaces.*osc*.lru_size=clear
27177                         after=$(md5sum $DIR/$tfile)
27178                         [ "$before" == "$after" ] ||
27179                                 error "$csum: $before != $after bs=$1 seek=$2"
27180                 done
27181         done
27182 }
27183 run_test 810 "partial page writes on ZFS (LU-11663)"
27184
27185 test_812a() {
27186         [ $OST1_VERSION -lt $(version_code 2.12.51) ] &&
27187                 skip "OST < 2.12.51 doesn't support this fail_loc"
27188
27189         $LFS setstripe -c 1 -i 0 $DIR/$tfile
27190         # ensure ost1 is connected
27191         stat $DIR/$tfile >/dev/null || error "can't stat"
27192         wait_osc_import_state client ost1 FULL
27193         # no locks, no reqs to let the connection idle
27194         cancel_lru_locks osc
27195
27196         # delay OST_DISCONNECT on OST1 to put OSC into intermediate state
27197 #define OBD_FAIL_OST_DISCONNECT_DELAY    0x245
27198         do_facet ost1 "$LCTL set_param fail_loc=0x245 fail_val=8"
27199         wait_osc_import_state client ost1 CONNECTING
27200         do_facet ost1 "$LCTL set_param fail_loc=0 fail_val=0"
27201
27202         stat $DIR/$tfile >/dev/null || error "can't stat file"
27203 }
27204 run_test 812a "do not drop reqs generated when imp is going to idle (LU-11951)"
27205
27206 test_812b() { # LU-12378
27207         [ $OST1_VERSION -lt $(version_code 2.12.51) ] &&
27208                 skip "OST < 2.12.51 doesn't support this fail_loc"
27209
27210         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "setstripe failed"
27211         # ensure ost1 is connected
27212         stat $DIR/$tfile >/dev/null || error "can't stat"
27213         wait_osc_import_state client ost1 FULL
27214         # no locks, no reqs to let the connection idle
27215         cancel_lru_locks osc
27216
27217         # delay OST_DISCONNECT on OST1 to put OSC into intermediate state
27218 #define OBD_FAIL_OST_DISCONNECT_DELAY    0x245
27219         do_facet ost1 "$LCTL set_param fail_loc=0x245 fail_val=8"
27220         wait_osc_import_state client ost1 CONNECTING
27221         do_facet ost1 "$LCTL set_param fail_loc=0 fail_val=0"
27222
27223         $LFS quota -u 0 $DIR/ || error "lfs quota should succeed"
27224         wait_osc_import_state client ost1 IDLE
27225 }
27226 run_test 812b "do not drop no resend request for idle connect"
27227
27228 test_812c() {
27229         local old
27230
27231         old=$($LCTL get_param -n osc.*.idle_timeout | head -n 1)
27232
27233         $LFS setstripe -c 1 -o 0 $DIR/$tfile
27234         $LFS getstripe $DIR/$tfile
27235         $LCTL set_param osc.*.idle_timeout=10
27236         stack_trap "$LCTL set_param osc.*.idle_timeout=$old" EXIT
27237         # ensure ost1 is connected
27238         stat $DIR/$tfile >/dev/null || error "can't stat"
27239         wait_osc_import_state client ost1 FULL
27240         # no locks, no reqs to let the connection idle
27241         cancel_lru_locks osc
27242
27243 #define OBD_FAIL_PTLRPC_IDLE_RACE        0x533
27244         $LCTL set_param fail_loc=0x80000533
27245         sleep 15
27246         dd if=/dev/zero of=$DIR/$tfile count=1 conv=sync || error "dd failed"
27247 }
27248 run_test 812c "idle import vs lock enqueue race"
27249
27250 test_813() {
27251         local file_heat_sav=$($LCTL get_param -n llite.*.file_heat 2>/dev/null)
27252         [ -z "$file_heat_sav" ] && skip "no file heat support"
27253
27254         local readsample
27255         local writesample
27256         local readbyte
27257         local writebyte
27258         local readsample1
27259         local writesample1
27260         local readbyte1
27261         local writebyte1
27262
27263         local period_second=$($LCTL get_param -n llite.*.heat_period_second)
27264         local decay_pct=$($LCTL get_param -n llite.*.heat_decay_percentage)
27265
27266         $LCTL set_param -n llite.*.file_heat=1
27267         echo "Turn on file heat"
27268         echo "Period second: $period_second, Decay percentage: $decay_pct"
27269
27270         echo "QQQQ" > $DIR/$tfile
27271         echo "QQQQ" > $DIR/$tfile
27272         echo "QQQQ" > $DIR/$tfile
27273         cat $DIR/$tfile > /dev/null
27274         cat $DIR/$tfile > /dev/null
27275         cat $DIR/$tfile > /dev/null
27276         cat $DIR/$tfile > /dev/null
27277
27278         local out=$($LFS heat_get $DIR/$tfile)
27279
27280         $LFS heat_get $DIR/$tfile
27281         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
27282         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
27283         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
27284         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
27285
27286         [ $readsample -le 4 ] || error "read sample ($readsample) is wrong"
27287         [ $writesample -le 3 ] || error "write sample ($writesample) is wrong"
27288         [ $readbyte -le 20 ] || error "read bytes ($readbyte) is wrong"
27289         [ $writebyte -le 15 ] || error "write bytes ($writebyte) is wrong"
27290
27291         sleep $((period_second + 3))
27292         echo "Sleep $((period_second + 3)) seconds..."
27293         # The recursion formula to calculate the heat of the file f is as
27294         # follow:
27295         # Hi+1(f) = (1-P)*Hi(f)+ P*Ci
27296         # Where Hi is the heat value in the period between time points i*I and
27297         # (i+1)*I; Ci is the access count in the period; the symbol P refers
27298         # to the weight of Ci.
27299         out=$($LFS heat_get $DIR/$tfile)
27300         $LFS heat_get $DIR/$tfile
27301         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
27302         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
27303         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
27304         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
27305
27306         [ $(bc <<< "$readsample <= 4 * $decay_pct / 100") -eq 1 ] ||
27307                 error "read sample ($readsample) is wrong"
27308         [ $(bc <<< "$writesample <= 3 * $decay_pct / 100") -eq 1 ] ||
27309                 error "write sample ($writesample) is wrong"
27310         [ $(bc <<< "$readbyte <= 20 * $decay_pct / 100") -eq 1 ] ||
27311                 error "read bytes ($readbyte) is wrong"
27312         [ $(bc <<< "$writebyte <= 15 * $decay_pct / 100") -eq 1 ] ||
27313                 error "write bytes ($writebyte) is wrong"
27314
27315         echo "QQQQ" > $DIR/$tfile
27316         echo "QQQQ" > $DIR/$tfile
27317         echo "QQQQ" > $DIR/$tfile
27318         cat $DIR/$tfile > /dev/null
27319         cat $DIR/$tfile > /dev/null
27320         cat $DIR/$tfile > /dev/null
27321         cat $DIR/$tfile > /dev/null
27322
27323         sleep $((period_second + 3))
27324         echo "Sleep $((period_second + 3)) seconds..."
27325
27326         out=$($LFS heat_get $DIR/$tfile)
27327         $LFS heat_get $DIR/$tfile
27328         readsample1=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
27329         writesample1=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
27330         readbyte1=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
27331         writebyte1=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
27332
27333         [ $(bc <<< "$readsample1 <= ($readsample * (100 - $decay_pct) + \
27334                 4 * $decay_pct) / 100") -eq 1 ] ||
27335                 error "read sample ($readsample1) is wrong"
27336         [ $(bc <<< "$writesample1 <= ($writesample * (100 - $decay_pct) + \
27337                 3 * $decay_pct) / 100") -eq 1 ] ||
27338                 error "write sample ($writesample1) is wrong"
27339         [ $(bc <<< "$readbyte1 <= ($readbyte * (100 - $decay_pct) + \
27340                 20 * $decay_pct) / 100") -eq 1 ] ||
27341                 error "read bytes ($readbyte1) is wrong"
27342         [ $(bc <<< "$writebyte1 <= ($writebyte * (100 - $decay_pct) + \
27343                 15 * $decay_pct) / 100") -eq 1 ] ||
27344                 error "write bytes ($writebyte1) is wrong"
27345
27346         echo "Turn off file heat for the file $DIR/$tfile"
27347         $LFS heat_set -o $DIR/$tfile
27348
27349         echo "QQQQ" > $DIR/$tfile
27350         echo "QQQQ" > $DIR/$tfile
27351         echo "QQQQ" > $DIR/$tfile
27352         cat $DIR/$tfile > /dev/null
27353         cat $DIR/$tfile > /dev/null
27354         cat $DIR/$tfile > /dev/null
27355         cat $DIR/$tfile > /dev/null
27356
27357         out=$($LFS heat_get $DIR/$tfile)
27358         $LFS heat_get $DIR/$tfile
27359         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
27360         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
27361         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
27362         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
27363
27364         [ $readsample -eq 0 ] || error "read sample ($readsample) is wrong"
27365         [ $writesample -eq 0 ] || error "write sample ($writesample) is wrong"
27366         [ $readbyte -eq 0 ] || error "read bytes ($readbyte) is wrong"
27367         [ $writebyte -eq 0 ] || error "write bytes ($writebyte) is wrong"
27368
27369         echo "Trun on file heat for the file $DIR/$tfile"
27370         $LFS heat_set -O $DIR/$tfile
27371
27372         echo "QQQQ" > $DIR/$tfile
27373         echo "QQQQ" > $DIR/$tfile
27374         echo "QQQQ" > $DIR/$tfile
27375         cat $DIR/$tfile > /dev/null
27376         cat $DIR/$tfile > /dev/null
27377         cat $DIR/$tfile > /dev/null
27378         cat $DIR/$tfile > /dev/null
27379
27380         out=$($LFS heat_get $DIR/$tfile)
27381         $LFS heat_get $DIR/$tfile
27382         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
27383         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
27384         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
27385         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
27386
27387         [ $readsample -gt 0 ] || error "read sample ($readsample) is wrong"
27388         [ $writesample -gt 0 ] || error "write sample ($writesample) is wrong"
27389         [ $readbyte -gt 0 ] || error "read bytes ($readbyte) is wrong"
27390         [ $writebyte -gt 0 ] || error "write bytes ($writebyte) is wrong"
27391
27392         $LFS heat_set -c $DIR/$tfile
27393         $LCTL set_param -n llite.*.file_heat=0
27394         echo "Turn off file heat support for the Lustre filesystem"
27395
27396         echo "QQQQ" > $DIR/$tfile
27397         echo "QQQQ" > $DIR/$tfile
27398         echo "QQQQ" > $DIR/$tfile
27399         cat $DIR/$tfile > /dev/null
27400         cat $DIR/$tfile > /dev/null
27401         cat $DIR/$tfile > /dev/null
27402         cat $DIR/$tfile > /dev/null
27403
27404         out=$($LFS heat_get $DIR/$tfile)
27405         $LFS heat_get $DIR/$tfile
27406         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
27407         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
27408         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
27409         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
27410
27411         [ $readsample -eq 0 ] || error "read sample ($readsample) is wrong"
27412         [ $writesample -eq 0 ] || error "write sample ($writesample) is wrong"
27413         [ $readbyte -eq 0 ] || error "read bytes ($readbyte) is wrong"
27414         [ $writebyte -eq 0 ] || error "write bytes ($writebyte) is wrong"
27415
27416         $LCTL set_param -n llite.*.file_heat=$file_heat_sav
27417         rm -f $DIR/$tfile
27418 }
27419 run_test 813 "File heat verfication"
27420
27421 test_814()
27422 {
27423         dd of=$DIR/$tfile seek=128 bs=1k < /dev/null
27424         echo -n y >> $DIR/$tfile
27425         cp --sparse=always $DIR/$tfile $DIR/${tfile}.cp || error "copy failed"
27426         diff $DIR/$tfile $DIR/${tfile}.cp || error "files should be same"
27427 }
27428 run_test 814 "sparse cp works as expected (LU-12361)"
27429
27430 test_815()
27431 {
27432         writeme -b 100 $DIR/$tfile || error "write 100 bytes failed"
27433         writeme -b 0 $DIR/$tfile || error "write 0 byte failed"
27434 }
27435 run_test 815 "zero byte tiny write doesn't hang (LU-12382)"
27436
27437 test_816() {
27438         local ost1_imp=$(get_osc_import_name client ost1)
27439         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
27440                          cut -d'.' -f2)
27441
27442         $LFS setstripe -c 1 -i 0 $DIR/$tfile
27443         # ensure ost1 is connected
27444
27445         stat $DIR/$tfile >/dev/null || error "can't stat"
27446         wait_osc_import_state client ost1 FULL
27447         # no locks, no reqs to let the connection idle
27448         cancel_lru_locks osc
27449         lru_resize_disable osc
27450         local before
27451         local now
27452         before=$($LCTL get_param -n \
27453                  ldlm.namespaces.$imp_name.lru_size)
27454
27455         wait_osc_import_state client ost1 IDLE
27456         dd if=/dev/null of=$DIR/$tfile bs=1k count=1 conv=sync
27457         now=$($LCTL get_param -n \
27458               ldlm.namespaces.$imp_name.lru_size)
27459         [ $before == $now ] || error "lru_size changed $before != $now"
27460 }
27461 run_test 816 "do not reset lru_resize on idle reconnect"
27462
27463 cleanup_817() {
27464         umount $tmpdir
27465         exportfs -u localhost:$DIR/nfsexp
27466         rm -rf $DIR/nfsexp
27467 }
27468
27469 test_817() {
27470         systemctl restart nfs-server.service || skip "failed to restart nfsd"
27471
27472         mkdir -p $DIR/nfsexp
27473         exportfs -orw,no_root_squash localhost:$DIR/nfsexp ||
27474                 error "failed to export nfs"
27475
27476         tmpdir=$(mktemp -d /tmp/nfs-XXXXXX)
27477         stack_trap cleanup_817 EXIT
27478
27479         mount -t nfs -orw localhost:$DIR/nfsexp $tmpdir ||
27480                 error "failed to mount nfs to $tmpdir"
27481
27482         cp /bin/true $tmpdir
27483         $DIR/nfsexp/true || error "failed to execute 'true' command"
27484 }
27485 run_test 817 "nfsd won't cache write lock for exec file"
27486
27487 test_818() {
27488         mkdir $DIR/$tdir
27489         $LFS setstripe -c1 -i0 $DIR/$tfile
27490         $LFS setstripe -c1 -i1 $DIR/$tfile
27491         stop $SINGLEMDS
27492         #define OBD_FAIL_OSP_CANT_PROCESS_LLOG          0x2105
27493         do_facet $SINGLEMDS lctl set_param fail_loc=0x80002105
27494         start $SINGLEMDS $(mdsdevname ${SINGLEMDS//mds/}) $MDS_MOUNT_OPTS ||
27495                 error "start $SINGLEMDS failed"
27496         rm -rf $DIR/$tdir
27497 }
27498 run_test 818 "unlink with failed llog"
27499
27500 test_819a() {
27501         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
27502         cancel_lru_locks osc
27503         #define OBD_FAIL_OST_2BIG_NIOBUF                0x248
27504         do_facet $SINGLEMDS lctl set_param fail_loc=0x80000248
27505         dd if=$DIR/$tfile of=/dev/null bs=1M count=1
27506         rm -f $TDIR/$tfile
27507 }
27508 run_test 819a "too big niobuf in read"
27509
27510 test_819b() {
27511         #define OBD_FAIL_OST_2BIG_NIOBUF                0x248
27512         do_facet $SINGLEMDS lctl set_param fail_loc=0x80000248
27513         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
27514         cancel_lru_locks osc
27515         sleep 1
27516         rm -f $TDIR/$tfile
27517 }
27518 run_test 819b "too big niobuf in write"
27519
27520
27521 function test_820_start_ost() {
27522         sleep 5
27523
27524         for num in $(seq $OSTCOUNT); do
27525                 start ost$num $(ostdevname $num) $OST_MOUNT_OPTS
27526         done
27527 }
27528
27529 test_820() {
27530         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
27531
27532         mkdir $DIR/$tdir
27533         umount_client $MOUNT || error "umount failed"
27534         for num in $(seq $OSTCOUNT); do
27535                 stop ost$num
27536         done
27537
27538         # mount client with no active OSTs
27539         # so that the client can't initialize max LOV EA size
27540         # from OSC notifications
27541         mount_client $MOUNT || error "mount failed"
27542         # delay OST starting to keep this 0 max EA size for a while
27543         test_820_start_ost &
27544
27545         # create a directory on MDS2
27546         test_mkdir -i 1 -c1 $DIR/$tdir/mds2 ||
27547                 error "Failed to create directory"
27548         # open intent should update default EA size
27549         # see mdc_update_max_ea_from_body()
27550         # notice this is the very first RPC to MDS2
27551         out=$(cp /etc/services $DIR/$tdir/mds2 2>&1)
27552         ret=$?
27553         echo $out
27554         # With SSK, this situation can lead to -EPERM being returned.
27555         # In that case, simply retry.
27556         if [ $ret -ne 0 ] && $SHARED_KEY; then
27557                 if echo "$out" | grep -q "not permitted"; then
27558                         cp /etc/services $DIR/$tdir/mds2
27559                         ret=$?
27560                 fi
27561         fi
27562         [ $ret -eq 0 ] || error "Failed to copy files to mds$n"
27563 }
27564 run_test 820 "update max EA from open intent"
27565
27566 test_822() {
27567         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
27568
27569         save_lustre_params mds1 \
27570                 "osp.$FSNAME-OST*-osc-MDT0000.max_create_count" > $p
27571         do_facet $SINGLEMDS "$LCTL set_param -n \
27572                         osp.$FSNAME-OST*MDT0000.max_create_count=0"
27573         do_facet $SINGLEMDS "$LCTL set_param -n \
27574                         osp.$FSNAME-OST0000*MDT0000.max_create_count=20000"
27575
27576         # wait for statfs update to clear OS_STATFS_NOPRECREATE
27577         local maxage=$(do_facet mds1 $LCTL get_param -n \
27578                        osp.$FSNAME-OST0000*MDT0000.maxage)
27579         sleep $((maxage + 1))
27580
27581         #define OBD_FAIL_NET_ERROR_RPC          0x532
27582         do_facet mds1 "$LCTL set_param fail_loc=0x80000532 fail_val=5"
27583
27584         stack_trap "restore_lustre_params < $p; rm $p"
27585
27586         local count=$(do_facet $SINGLEMDS "lctl get_param -n \
27587                       osp.$FSNAME-OST0000*MDT0000.create_count")
27588         for i in $(seq 1 $count); do
27589                 touch $DIR/$tfile.${i} || error "touch failed"
27590         done
27591 }
27592 run_test 822 "test precreate failure"
27593
27594 test_823() {
27595         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
27596         local OST_MAX_PRECREATE=20000
27597
27598         save_lustre_params mds1 \
27599                 "osp.$FSNAME-OST*-osc-MDT0000.max_create_count" > $p
27600         do_facet $SINGLEMDS "$LCTL set_param -n \
27601                 osp.$FSNAME-OST*MDT0000.max_create_count=0"
27602         do_facet $SINGLEMDS "$LCTL set_param -n \
27603                 osp.$FSNAME-OST0000*MDT0000.max_create_count=$OST_MAX_PRECREATE"
27604
27605         stack_trap "restore_lustre_params < $p; rm $p"
27606
27607         do_facet $SINGLEMDS "$LCTL set_param -n \
27608                 osp.$FSNAME-OST*-osc-MDT*.create_count=100200"
27609
27610         local count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
27611                       osp.$FSNAME-OST0000*MDT0000.create_count")
27612         local max=$(do_facet $SINGLEMDS "$LCTL get_param -n \
27613                     osp.$FSNAME-OST0000*MDT0000.max_create_count")
27614         local expect_count=$(((($max/2)/256) * 256))
27615
27616         log "setting create_count to 100200:"
27617         log " -result- count: $count with max: $max, expecting: $expect_count"
27618
27619         [[ $count -eq expect_count ]] ||
27620                 error "Create count not set to max precreate."
27621 }
27622 run_test 823 "Setting create_count > OST_MAX_PRECREATE is lowered to maximum"
27623
27624 test_831() {
27625         local sync_changes=$(do_facet $SINGLEMDS \
27626                 $LCTL get_param -n osp.$FSNAME-OST0000-osc-MDT0000.sync_changes)
27627
27628         [ "$sync_changes" -gt 100 ] &&
27629                 skip "Sync changes $sync_changes > 100 already"
27630
27631         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
27632
27633         $LFS mkdir -i 0 $DIR/$tdir
27634         $LFS setstripe -c 1 -i 0 $DIR/$tdir
27635
27636         save_lustre_params mds1 \
27637                 "osp.$FSNAME-OST*-osc-MDT0000.max_sync_changes" > $p
27638         save_lustre_params mds1 \
27639                 "osp.$FSNAME-OST*-osc-MDT0000.max_rpcs_in_progress" >> $p
27640
27641         do_facet mds1 "$LCTL set_param -n \
27642                 osp.$FSNAME-OST*-osc-MDT0000.max_sync_changes=100 \
27643                 osp.$FSNAME-OST*-osc-MDT0000.max_rpcs_in_progress=128"
27644         stack_trap "restore_lustre_params < $p" EXIT
27645
27646         createmany -o $DIR/$tdir/f- 1000
27647         unlinkmany $DIR/$tdir/f- 1000 &
27648         local UNLINK_PID=$!
27649
27650         while sleep 1; do
27651                 sync_changes=$(do_facet mds1 \
27652                 $LCTL get_param -n osp.$FSNAME-OST0000-osc-MDT0000.sync_changes)
27653                 # the check in the code is racy, fail the test
27654                 # if the value above the limit by 10.
27655                 [ $sync_changes -gt 110 ] && {
27656                         kill -2 $UNLINK_PID
27657                         wait
27658                         error "osp changes throttling failed, $sync_changes>110"
27659                 }
27660                 kill -0 $UNLINK_PID 2> /dev/null || break
27661         done
27662         wait
27663 }
27664 run_test 831 "throttling unlink/setattr queuing on OSP"
27665
27666 #
27667 # tests that do cleanup/setup should be run at the end
27668 #
27669
27670 test_900() {
27671         [ $PARALLEL == "yes" ] && skip "skip parallel run"
27672         local ls
27673
27674         #define OBD_FAIL_MGC_PAUSE_PROCESS_LOG   0x903
27675         $LCTL set_param fail_loc=0x903
27676
27677         cancel_lru_locks MGC
27678
27679         FAIL_ON_ERROR=true cleanup
27680         FAIL_ON_ERROR=true setup
27681 }
27682 run_test 900 "umount should not race with any mgc requeue thread"
27683
27684 # LUS-6253/LU-11185
27685 test_901() {
27686         local oldc
27687         local newc
27688         local olds
27689         local news
27690         [ $PARALLEL == "yes" ] && skip "skip parallel run"
27691
27692         # some get_param have a bug to handle dot in param name
27693         cancel_lru_locks MGC
27694         oldc=$($LCTL get_param -n 'ldlm.namespaces.MGC*.lock_count')
27695         olds=$(do_facet mgs $LCTL get_param -n 'ldlm.namespaces.MGS*.lock_count')
27696         umount_client $MOUNT || error "umount failed"
27697         mount_client $MOUNT || error "mount failed"
27698         cancel_lru_locks MGC
27699         newc=$($LCTL get_param -n 'ldlm.namespaces.MGC*.lock_count')
27700         news=$(do_facet mgs $LCTL get_param -n 'ldlm.namespaces.MGS*.lock_count')
27701
27702         [ $oldc -lt $newc ] && error "mgc lock leak ($oldc != $newc)"
27703         [ $olds -lt $news ] && error "mgs lock leak ($olds != $news)"
27704
27705         return 0
27706 }
27707 run_test 901 "don't leak a mgc lock on client umount"
27708
27709 # LU-13377
27710 test_902() {
27711         [ $CLIENT_VERSION -lt $(version_code 2.13.52) ] &&
27712                 skip "client does not have LU-13377 fix"
27713         #define OBD_FAIL_LLITE_SHORT_COMMIT 0x1415
27714         $LCTL set_param fail_loc=0x1415
27715         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
27716         cancel_lru_locks osc
27717         rm -f $DIR/$tfile
27718 }
27719 run_test 902 "test short write doesn't hang lustre"
27720
27721 # LU-14711
27722 test_903() {
27723         $LFS setstripe -i 0 -c 1 $DIR/$tfile $DIR/${tfile}-2
27724         echo "blah" > $DIR/${tfile}-2
27725         dd if=/dev/zero of=$DIR/$tfile bs=1M count=6 conv=fsync
27726         #define OBD_FAIL_OSC_SLOW_PAGE_EVICT 0x417
27727         $LCTL set_param fail_loc=0x417 fail_val=20
27728
27729         mv $DIR/${tfile}-2 $DIR/$tfile # Destroys the big object
27730         sleep 1 # To start the destroy
27731         wait_destroy_complete 150 || error "Destroy taking too long"
27732         cat $DIR/$tfile > /dev/null || error "Evicted"
27733 }
27734 run_test 903 "Test long page discard does not cause evictions"
27735
27736 complete $SECONDS
27737 [ -f $EXT2_DEV ] && rm $EXT2_DEV || true
27738 check_and_cleanup_lustre
27739 if [ "$I_MOUNTED" != "yes" ]; then
27740         lctl set_param debug="$OLDDEBUG" 2> /dev/null || true
27741 fi
27742 exit_status