Whamcloud - gitweb
ce1e1aec53b1dc230a9d48bd523bd50676a29c99
[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 # createtest also checks that device nodes are created and
3353 # then visible correctly (#2091)
3354 test_28() { # bug 2091
3355         test_mkdir $DIR/d28
3356         $CREATETEST $DIR/d28/ct || error "createtest failed"
3357 }
3358 run_test 28 "create/mknod/mkdir with bad file types ============"
3359
3360 test_29() {
3361         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3362
3363         sync; sleep 1; sync # flush out any dirty pages from previous tests
3364         cancel_lru_locks
3365         test_mkdir $DIR/d29
3366         touch $DIR/d29/foo
3367         log 'first d29'
3368         ls -l $DIR/d29
3369
3370         declare -i LOCKCOUNTORIG=0
3371         for lock_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_count); do
3372                 let LOCKCOUNTORIG=$LOCKCOUNTORIG+$lock_count
3373         done
3374         [ $LOCKCOUNTORIG -eq 0 ] && error "No mdc lock count" && return 1
3375
3376         declare -i LOCKUNUSEDCOUNTORIG=0
3377         for unused_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_unused_count); do
3378                 let LOCKUNUSEDCOUNTORIG=$LOCKUNUSEDCOUNTORIG+$unused_count
3379         done
3380
3381         log 'second d29'
3382         ls -l $DIR/d29
3383         log 'done'
3384
3385         declare -i LOCKCOUNTCURRENT=0
3386         for lock_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_count); do
3387                 let LOCKCOUNTCURRENT=$LOCKCOUNTCURRENT+$lock_count
3388         done
3389
3390         declare -i LOCKUNUSEDCOUNTCURRENT=0
3391         for unused_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_unused_count); do
3392                 let LOCKUNUSEDCOUNTCURRENT=$LOCKUNUSEDCOUNTCURRENT+$unused_count
3393         done
3394
3395         if [[ $LOCKCOUNTCURRENT -gt $LOCKCOUNTORIG ]]; then
3396                 $LCTL set_param -n ldlm.dump_namespaces ""
3397                 error "CURRENT: $LOCKCOUNTCURRENT > $LOCKCOUNTORIG"
3398                 $LCTL dk | sort -k4 -t: > $TMP/test_29.dk
3399                 log "dumped log to $TMP/test_29.dk (bug 5793)"
3400                 return 2
3401         fi
3402         if [[ $LOCKUNUSEDCOUNTCURRENT -gt $LOCKUNUSEDCOUNTORIG ]]; then
3403                 error "UNUSED: $LOCKUNUSEDCOUNTCURRENT > $LOCKUNUSEDCOUNTORIG"
3404                 $LCTL dk | sort -k4 -t: > $TMP/test_29.dk
3405                 log "dumped log to $TMP/test_29.dk (bug 5793)"
3406                 return 3
3407         fi
3408 }
3409 run_test 29 "IT_GETATTR regression  ============================"
3410
3411 test_30a() { # was test_30
3412         cp $(which ls) $DIR || cp /bin/ls $DIR
3413         $DIR/ls / || error "Can't execute binary from lustre"
3414         rm $DIR/ls
3415 }
3416 run_test 30a "execute binary from Lustre (execve) =============="
3417
3418 test_30b() {
3419         cp `which ls` $DIR || cp /bin/ls $DIR
3420         chmod go+rx $DIR/ls
3421         $RUNAS $DIR/ls / || error "Can't execute binary from lustre as non-root"
3422         rm $DIR/ls
3423 }
3424 run_test 30b "execute binary from Lustre as non-root ==========="
3425
3426 test_30c() { # b=22376
3427         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3428
3429         cp $(which ls) $DIR || cp /bin/ls $DIR
3430         chmod a-rw $DIR/ls
3431         cancel_lru_locks mdc
3432         cancel_lru_locks osc
3433         $RUNAS $DIR/ls / || error "Can't execute binary from lustre"
3434         rm -f $DIR/ls
3435 }
3436 run_test 30c "execute binary from Lustre without read perms ===="
3437
3438 test_30d() {
3439         cp $(which dd) $DIR || error "failed to copy dd to $DIR/dd"
3440
3441         for i in {1..10}; do
3442                 $DIR/dd bs=1M count=128 if=/dev/zero of=$DIR/$tfile &
3443                 local PID=$!
3444                 sleep 1
3445                 $LCTL set_param ldlm.namespaces.*MDT*.lru_size=clear
3446                 wait $PID || error "executing dd from Lustre failed"
3447                 rm -f $DIR/$tfile
3448         done
3449
3450         rm -f $DIR/dd
3451 }
3452 run_test 30d "execute binary from Lustre while clear locks"
3453
3454 test_31a() {
3455         $OPENUNLINK $DIR/f31 $DIR/f31 || error "openunlink failed"
3456         $CHECKSTAT -a $DIR/f31 || error "$DIR/f31 exists"
3457 }
3458 run_test 31a "open-unlink file =================================="
3459
3460 test_31b() {
3461         touch $DIR/f31 || error "touch $DIR/f31 failed"
3462         ln $DIR/f31 $DIR/f31b || error "ln failed"
3463         $MULTIOP $DIR/f31b Ouc || error "multiop failed"
3464         $CHECKSTAT -t file $DIR/f31 || error "$DIR/f31 not file type"
3465 }
3466 run_test 31b "unlink file with multiple links while open ======="
3467
3468 test_31c() {
3469         touch $DIR/f31 || error "touch $DIR/f31 failed"
3470         ln $DIR/f31 $DIR/f31c || error "ln failed"
3471         multiop_bg_pause $DIR/f31 O_uc ||
3472                 error "multiop_bg_pause for $DIR/f31 failed"
3473         MULTIPID=$!
3474         $MULTIOP $DIR/f31c Ouc
3475         kill -USR1 $MULTIPID
3476         wait $MULTIPID
3477 }
3478 run_test 31c "open-unlink file with multiple links ============="
3479
3480 test_31d() {
3481         opendirunlink $DIR/d31d $DIR/d31d || error "opendirunlink failed"
3482         $CHECKSTAT -a $DIR/d31d || error "$DIR/d31d exists"
3483 }
3484 run_test 31d "remove of open directory ========================="
3485
3486 test_31e() { # bug 2904
3487         openfilleddirunlink $DIR/d31e || error "openfilleddirunlink failed"
3488 }
3489 run_test 31e "remove of open non-empty directory ==============="
3490
3491 test_31f() { # bug 4554
3492         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3493
3494         set -vx
3495         test_mkdir $DIR/d31f
3496         $LFS setstripe -S 1048576 -c 1 $DIR/d31f
3497         cp /etc/hosts $DIR/d31f
3498         ls -l $DIR/d31f
3499         $LFS getstripe $DIR/d31f/hosts
3500         multiop_bg_pause $DIR/d31f D_c || return 1
3501         MULTIPID=$!
3502
3503         rm -rv $DIR/d31f || error "first of $DIR/d31f"
3504         test_mkdir $DIR/d31f
3505         $LFS setstripe -S 1048576 -c 1 $DIR/d31f
3506         cp /etc/hosts $DIR/d31f
3507         ls -l $DIR/d31f
3508         $LFS getstripe $DIR/d31f/hosts
3509         multiop_bg_pause $DIR/d31f D_c || return 1
3510         MULTIPID2=$!
3511
3512         kill -USR1 $MULTIPID || error "first opendir $MULTIPID not running"
3513         wait $MULTIPID || error "first opendir $MULTIPID failed"
3514
3515         sleep 6
3516
3517         kill -USR1 $MULTIPID2 || error "second opendir $MULTIPID not running"
3518         wait $MULTIPID2 || error "second opendir $MULTIPID2 failed"
3519         set +vx
3520 }
3521 run_test 31f "remove of open directory with open-unlink file ==="
3522
3523 test_31g() {
3524         echo "-- cross directory link --"
3525         test_mkdir -c1 $DIR/${tdir}ga
3526         test_mkdir -c1 $DIR/${tdir}gb
3527         touch $DIR/${tdir}ga/f
3528         ln $DIR/${tdir}ga/f $DIR/${tdir}gb/g
3529         $CHECKSTAT -t file $DIR/${tdir}ga/f || error "source"
3530         [ `stat -c%h $DIR/${tdir}ga/f` == '2' ] || error "source nlink"
3531         $CHECKSTAT -t file $DIR/${tdir}gb/g || error "target"
3532         [ `stat -c%h $DIR/${tdir}gb/g` == '2' ] || error "target nlink"
3533 }
3534 run_test 31g "cross directory link==============="
3535
3536 test_31h() {
3537         echo "-- cross directory link --"
3538         test_mkdir -c1 $DIR/${tdir}
3539         test_mkdir -c1 $DIR/${tdir}/dir
3540         touch $DIR/${tdir}/f
3541         ln $DIR/${tdir}/f $DIR/${tdir}/dir/g
3542         $CHECKSTAT -t file $DIR/${tdir}/f || error "source"
3543         [ `stat -c%h $DIR/${tdir}/f` == '2' ] || error "source nlink"
3544         $CHECKSTAT -t file $DIR/${tdir}/dir/g || error "target"
3545         [ `stat -c%h $DIR/${tdir}/dir/g` == '2' ] || error "target nlink"
3546 }
3547 run_test 31h "cross directory link under child==============="
3548
3549 test_31i() {
3550         echo "-- cross directory link --"
3551         test_mkdir -c1 $DIR/$tdir
3552         test_mkdir -c1 $DIR/$tdir/dir
3553         touch $DIR/$tdir/dir/f
3554         ln $DIR/$tdir/dir/f $DIR/$tdir/g
3555         $CHECKSTAT -t file $DIR/$tdir/dir/f || error "source"
3556         [ `stat -c%h $DIR/$tdir/dir/f` == '2' ] || error "source nlink"
3557         $CHECKSTAT -t file $DIR/$tdir/g || error "target"
3558         [ `stat -c%h $DIR/$tdir/g` == '2' ] || error "target nlink"
3559 }
3560 run_test 31i "cross directory link under parent==============="
3561
3562 test_31j() {
3563         test_mkdir -c1 -p $DIR/$tdir
3564         test_mkdir -c1 -p $DIR/$tdir/dir1
3565         ln $DIR/$tdir/dir1 $DIR/$tdir/dir2 && error "ln for dir"
3566         link $DIR/$tdir/dir1 $DIR/$tdir/dir3 && error "link for dir"
3567         mlink $DIR/$tdir/dir1 $DIR/$tdir/dir4 && error "mlink for dir"
3568         mlink $DIR/$tdir/dir1 $DIR/$tdir/dir1 && error "mlink to the same dir"
3569         return 0
3570 }
3571 run_test 31j "link for directory==============="
3572
3573 test_31k() {
3574         test_mkdir -c1 -p $DIR/$tdir
3575         touch $DIR/$tdir/s
3576         touch $DIR/$tdir/exist
3577         mlink $DIR/$tdir/s $DIR/$tdir/t || error "mlink"
3578         mlink $DIR/$tdir/s $DIR/$tdir/exist && error "mlink to exist file"
3579         mlink $DIR/$tdir/s $DIR/$tdir/s && error "mlink to the same file"
3580         mlink $DIR/$tdir/s $DIR/$tdir && error "mlink to parent dir"
3581         mlink $DIR/$tdir $DIR/$tdir/s && error "mlink parent dir to target"
3582         mlink $DIR/$tdir/not-exist $DIR/$tdir/foo && error "mlink non-existing to new"
3583         mlink $DIR/$tdir/not-exist $DIR/$tdir/s && error "mlink non-existing to exist"
3584         return 0
3585 }
3586 run_test 31k "link to file: the same, non-existing, dir==============="
3587
3588 test_31m() {
3589         mkdir $DIR/d31m
3590         touch $DIR/d31m/s
3591         mkdir $DIR/d31m2
3592         touch $DIR/d31m2/exist
3593         mlink $DIR/d31m/s $DIR/d31m2/t || error "mlink"
3594         mlink $DIR/d31m/s $DIR/d31m2/exist && error "mlink to exist file"
3595         mlink $DIR/d31m/s $DIR/d31m2 && error "mlink to parent dir"
3596         mlink $DIR/d31m2 $DIR/d31m/s && error "mlink parent dir to target"
3597         mlink $DIR/d31m/not-exist $DIR/d31m2/foo && error "mlink non-existing to new"
3598         mlink $DIR/d31m/not-exist $DIR/d31m2/s && error "mlink non-existing to exist"
3599         return 0
3600 }
3601 run_test 31m "link to file: the same, non-existing, dir==============="
3602
3603 test_31n() {
3604         touch $DIR/$tfile || error "cannot create '$DIR/$tfile'"
3605         nlink=$(stat --format=%h $DIR/$tfile)
3606         [ ${nlink:--1} -eq 1 ] || error "nlink is $nlink, expected 1"
3607         local fd=$(free_fd)
3608         local cmd="exec $fd<$DIR/$tfile"
3609         eval $cmd
3610         cmd="exec $fd<&-"
3611         trap "eval $cmd" EXIT
3612         nlink=$(stat --dereference --format=%h /proc/self/fd/$fd)
3613         [ ${nlink:--1} -eq 1 ] || error "nlink is $nlink, expected 1"
3614         rm $DIR/$tfile || error "cannot remove '$DIR/$tfile'"
3615         nlink=$(stat --dereference --format=%h /proc/self/fd/$fd)
3616         [ ${nlink:--1} -eq 0 ] || error "nlink is $nlink, expected 0"
3617         eval $cmd
3618 }
3619 run_test 31n "check link count of unlinked file"
3620
3621 link_one() {
3622         local tempfile=$(mktemp $1_XXXXXX)
3623         mlink $tempfile $1 2> /dev/null &&
3624                 echo "$BASHPID: link $tempfile to $1 succeeded"
3625         munlink $tempfile
3626 }
3627
3628 test_31o() { # LU-2901
3629         test_mkdir $DIR/$tdir
3630         for LOOP in $(seq 100); do
3631                 rm -f $DIR/$tdir/$tfile*
3632                 for THREAD in $(seq 8); do
3633                         link_one $DIR/$tdir/$tfile.$LOOP &
3634                 done
3635                 wait
3636                 local LINKS=$(ls -1 $DIR/$tdir | grep -c $tfile.$LOOP)
3637                 [[ $LINKS -gt 1 ]] && ls $DIR/$tdir &&
3638                         error "$LINKS duplicate links to $tfile.$LOOP" &&
3639                         break || true
3640         done
3641 }
3642 run_test 31o "duplicate hard links with same filename"
3643
3644 test_31p() {
3645         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
3646
3647         test_mkdir $DIR/$tdir
3648         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
3649         $LFS setdirstripe -D -c2 -H all_char $DIR/$tdir/striped_dir
3650
3651         opendirunlink $DIR/$tdir/striped_dir/test1 ||
3652                 error "open unlink test1 failed"
3653         opendirunlink $DIR/$tdir/striped_dir/test2 ||
3654                 error "open unlink test2 failed"
3655
3656         $CHECKSTAT -a $DIR/$tdir/striped_dir/test1 ||
3657                 error "test1 still exists"
3658         $CHECKSTAT -a $DIR/$tdir/striped_dir/test2 ||
3659                 error "test2 still exists"
3660 }
3661 run_test 31p "remove of open striped directory"
3662
3663 test_31q() {
3664         [ $MDSCOUNT -lt 3 ] && skip_env "needs >= 3 MDTs"
3665
3666         $LFS mkdir -i 3,1 $DIR/$tdir || error "mkdir failed"
3667         index=$($LFS getdirstripe -i $DIR/$tdir)
3668         [ $index -eq 3 ] || error "first stripe index $index != 3"
3669         index=$($LFS getdirstripe $DIR/$tdir | tail -1 | awk '{print $1}')
3670         [ $index -eq 1 ] || error "second stripe index $index != 1"
3671
3672         # when "-c <stripe_count>" is set, the number of MDTs specified after
3673         # "-i" should equal to the stripe count
3674         $LFS mkdir -i 3,1 -c 3 $DIR/$tdir.2 && error "mkdir should fail" || true
3675 }
3676 run_test 31q "create striped directory on specific MDTs"
3677
3678 #LU-14949
3679 test_31r() {
3680         touch $DIR/$tfile.target
3681         touch $DIR/$tfile.source
3682
3683         #OBD_FAIL_LLITE_OPEN_DELAY 0x1419
3684         $LCTL set_param fail_loc=0x1419 fail_val=3
3685         cat $DIR/$tfile.target &
3686         CATPID=$!
3687
3688         # Guarantee open is waiting before we get here
3689         sleep 1
3690         mv $DIR/$tfile.source $DIR/$tfile.target
3691
3692         wait $CATPID
3693         RC=$?
3694         if [[ $RC -ne 0 ]]; then
3695                 error "open with cat failed, rc=$RC"
3696         fi
3697 }
3698 run_test 31r "open-rename(replace) race"
3699
3700 cleanup_test32_mount() {
3701         local rc=0
3702         trap 0
3703         local loopdev=$(losetup -a | grep $EXT2_DEV | sed -ne 's/:.*$//p')
3704         $UMOUNT $DIR/$tdir/ext2-mountpoint || rc=$?
3705         losetup -d $loopdev || true
3706         rm -rf $DIR/$tdir
3707         return $rc
3708 }
3709
3710 test_32a() {
3711         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3712
3713         echo "== more mountpoints and symlinks ================="
3714         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3715         trap cleanup_test32_mount EXIT
3716         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3717         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3718                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3719         $CHECKSTAT -t dir $DIR/$tdir/ext2-mountpoint/.. ||
3720                 error "$DIR/$tdir/ext2-mountpoint/.. not dir type"
3721         cleanup_test32_mount
3722 }
3723 run_test 32a "stat d32a/ext2-mountpoint/.. ====================="
3724
3725 test_32b() {
3726         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3727
3728         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3729         trap cleanup_test32_mount EXIT
3730         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3731         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3732                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3733         ls -al $DIR/$tdir/ext2-mountpoint/.. ||
3734                 error "Can't list $DIR/$tdir/ext2-mountpoint/.."
3735         cleanup_test32_mount
3736 }
3737 run_test 32b "open d32b/ext2-mountpoint/.. ====================="
3738
3739 test_32c() {
3740         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3741
3742         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3743         trap cleanup_test32_mount EXIT
3744         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3745         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3746                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3747         test_mkdir -p $DIR/$tdir/d2/test_dir
3748         $CHECKSTAT -t dir $DIR/$tdir/ext2-mountpoint/../d2/test_dir ||
3749                 error "$DIR/$tdir/ext2-mountpoint/../d2/test_dir not dir type"
3750         cleanup_test32_mount
3751 }
3752 run_test 32c "stat d32c/ext2-mountpoint/../d2/test_dir ========="
3753
3754 test_32d() {
3755         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3756
3757         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3758         trap cleanup_test32_mount EXIT
3759         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3760         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3761                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3762         test_mkdir -p $DIR/$tdir/d2/test_dir
3763         ls -al $DIR/$tdir/ext2-mountpoint/../d2/test_dir ||
3764                 error "Can't list $DIR/$tdir/ext2-mountpoint/../d2/test_dir"
3765         cleanup_test32_mount
3766 }
3767 run_test 32d "open d32d/ext2-mountpoint/../d2/test_dir"
3768
3769 test_32e() {
3770         rm -fr $DIR/$tdir
3771         test_mkdir -p $DIR/$tdir/tmp
3772         local tmp_dir=$DIR/$tdir/tmp
3773         ln -s $DIR/$tdir $tmp_dir/symlink11
3774         ln -s $tmp_dir/symlink11 $tmp_dir/../symlink01
3775         $CHECKSTAT -t link $DIR/$tdir/tmp/symlink11 || error "symlink11 bad"
3776         $CHECKSTAT -t link $DIR/$tdir/symlink01 || error "symlink01 bad"
3777 }
3778 run_test 32e "stat d32e/symlink->tmp/symlink->lustre-subdir"
3779
3780 test_32f() {
3781         rm -fr $DIR/$tdir
3782         test_mkdir -p $DIR/$tdir/tmp
3783         local tmp_dir=$DIR/$tdir/tmp
3784         ln -s $DIR/$tdir $tmp_dir/symlink11
3785         ln -s $tmp_dir/symlink11 $tmp_dir/../symlink01
3786         ls $DIR/$tdir/tmp/symlink11  || error "symlink11 bad"
3787         ls $DIR/$tdir/symlink01 || error "symlink01 bad"
3788 }
3789 run_test 32f "open d32f/symlink->tmp/symlink->lustre-subdir"
3790
3791 test_32g() {
3792         local tmp_dir=$DIR/$tdir/tmp
3793         test_mkdir -p $tmp_dir
3794         test_mkdir $DIR/${tdir}2
3795         ln -s $DIR/${tdir}2 $tmp_dir/symlink12
3796         ln -s $tmp_dir/symlink12 $tmp_dir/../symlink02
3797         $CHECKSTAT -t link $tmp_dir/symlink12 || error "symlink12 not a link"
3798         $CHECKSTAT -t link $DIR/$tdir/symlink02 || error "symlink02 not a link"
3799         $CHECKSTAT -t dir -f $tmp_dir/symlink12 || error "symlink12 not a dir"
3800         $CHECKSTAT -t dir -f $DIR/$tdir/symlink02 || error "symlink12 not a dir"
3801 }
3802 run_test 32g "stat d32g/symlink->tmp/symlink->lustre-subdir/${tdir}2"
3803
3804 test_32h() {
3805         rm -fr $DIR/$tdir $DIR/${tdir}2
3806         tmp_dir=$DIR/$tdir/tmp
3807         test_mkdir -p $tmp_dir
3808         test_mkdir $DIR/${tdir}2
3809         ln -s $DIR/${tdir}2 $tmp_dir/symlink12
3810         ln -s $tmp_dir/symlink12 $tmp_dir/../symlink02
3811         ls $tmp_dir/symlink12 || error "listing symlink12"
3812         ls $DIR/$tdir/symlink02  || error "listing symlink02"
3813 }
3814 run_test 32h "open d32h/symlink->tmp/symlink->lustre-subdir/${tdir}2"
3815
3816 test_32i() {
3817         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3818
3819         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3820         trap cleanup_test32_mount EXIT
3821         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3822         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3823                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3824         touch $DIR/$tdir/test_file
3825         $CHECKSTAT -t file $DIR/$tdir/ext2-mountpoint/../test_file ||
3826                 error "$DIR/$tdir/ext2-mountpoint/../test_file not file type"
3827         cleanup_test32_mount
3828 }
3829 run_test 32i "stat d32i/ext2-mountpoint/../test_file ==========="
3830
3831 test_32j() {
3832         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3833
3834         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3835         trap cleanup_test32_mount EXIT
3836         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3837         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3838                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3839         touch $DIR/$tdir/test_file
3840         cat $DIR/$tdir/ext2-mountpoint/../test_file ||
3841                 error "Can't open $DIR/$tdir/ext2-mountpoint/../test_file"
3842         cleanup_test32_mount
3843 }
3844 run_test 32j "open d32j/ext2-mountpoint/../test_file ==========="
3845
3846 test_32k() {
3847         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3848
3849         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         test_mkdir -p $DIR/$tdir/d2
3855         touch $DIR/$tdir/d2/test_file || error "touch failed"
3856         $CHECKSTAT -t file $DIR/$tdir/ext2-mountpoint/../d2/test_file ||
3857                 error "$DIR/$tdir/ext2-mountpoint/../d2/test_file not file type"
3858         cleanup_test32_mount
3859 }
3860 run_test 32k "stat d32k/ext2-mountpoint/../d2/test_file ========"
3861
3862 test_32l() {
3863         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3864
3865         rm -fr $DIR/$tdir
3866         trap cleanup_test32_mount EXIT
3867         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3868         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3869                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3870         test_mkdir -p $DIR/$tdir/d2
3871         touch $DIR/$tdir/d2/test_file || error "touch failed"
3872         cat  $DIR/$tdir/ext2-mountpoint/../d2/test_file ||
3873                 error "Can't open $DIR/$tdir/ext2-mountpoint/../d2/test_file"
3874         cleanup_test32_mount
3875 }
3876 run_test 32l "open d32l/ext2-mountpoint/../d2/test_file ========"
3877
3878 test_32m() {
3879         rm -fr $DIR/d32m
3880         test_mkdir -p $DIR/d32m/tmp
3881         TMP_DIR=$DIR/d32m/tmp
3882         ln -s $DIR $TMP_DIR/symlink11
3883         ln -s $TMP_DIR/symlink11 $TMP_DIR/../symlink01
3884         $CHECKSTAT -t link $DIR/d32m/tmp/symlink11 ||
3885                 error "symlink11 not a link"
3886         $CHECKSTAT -t link $DIR/d32m/symlink01 ||
3887                 error "symlink01 not a link"
3888 }
3889 run_test 32m "stat d32m/symlink->tmp/symlink->lustre-root ======"
3890
3891 test_32n() {
3892         rm -fr $DIR/d32n
3893         test_mkdir -p $DIR/d32n/tmp
3894         TMP_DIR=$DIR/d32n/tmp
3895         ln -s $DIR $TMP_DIR/symlink11
3896         ln -s $TMP_DIR/symlink11 $TMP_DIR/../symlink01
3897         ls -l $DIR/d32n/tmp/symlink11  || error "listing symlink11"
3898         ls -l $DIR/d32n/symlink01 || error "listing symlink01"
3899 }
3900 run_test 32n "open d32n/symlink->tmp/symlink->lustre-root ======"
3901
3902 test_32o() {
3903         touch $DIR/$tfile
3904         test_mkdir -p $DIR/d32o/tmp
3905         TMP_DIR=$DIR/d32o/tmp
3906         ln -s $DIR/$tfile $TMP_DIR/symlink12
3907         ln -s $TMP_DIR/symlink12 $TMP_DIR/../symlink02
3908         $CHECKSTAT -t link $DIR/d32o/tmp/symlink12 ||
3909                 error "symlink12 not a link"
3910         $CHECKSTAT -t link $DIR/d32o/symlink02 || error "symlink02 not a link"
3911         $CHECKSTAT -t file -f $DIR/d32o/tmp/symlink12 ||
3912                 error "$DIR/d32o/tmp/symlink12 not file type"
3913         $CHECKSTAT -t file -f $DIR/d32o/symlink02 ||
3914                 error "$DIR/d32o/symlink02 not file type"
3915 }
3916 run_test 32o "stat d32o/symlink->tmp/symlink->lustre-root/$tfile"
3917
3918 test_32p() {
3919         log 32p_1
3920         rm -fr $DIR/d32p
3921         log 32p_2
3922         rm -f $DIR/$tfile
3923         log 32p_3
3924         touch $DIR/$tfile
3925         log 32p_4
3926         test_mkdir -p $DIR/d32p/tmp
3927         log 32p_5
3928         TMP_DIR=$DIR/d32p/tmp
3929         log 32p_6
3930         ln -s $DIR/$tfile $TMP_DIR/symlink12
3931         log 32p_7
3932         ln -s $TMP_DIR/symlink12 $TMP_DIR/../symlink02
3933         log 32p_8
3934         cat $DIR/d32p/tmp/symlink12 ||
3935                 error "Can't open $DIR/d32p/tmp/symlink12"
3936         log 32p_9
3937         cat $DIR/d32p/symlink02 || error "Can't open $DIR/d32p/symlink02"
3938         log 32p_10
3939 }
3940 run_test 32p "open d32p/symlink->tmp/symlink->lustre-root/$tfile"
3941
3942 test_32q() {
3943         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3944
3945         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3946         trap cleanup_test32_mount EXIT
3947         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3948         touch $DIR/$tdir/ext2-mountpoint/under_the_mount || error "touch failed"
3949         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3950                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3951         ls $DIR/$tdir/ext2-mountpoint | grep "\<under_the_mount\>" && error
3952         cleanup_test32_mount
3953 }
3954 run_test 32q "stat follows mountpoints in Lustre (should return error)"
3955
3956 test_32r() {
3957         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3958
3959         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3960         trap cleanup_test32_mount EXIT
3961         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3962         touch $DIR/$tdir/ext2-mountpoint/under_the_mount || error "touch failed"
3963         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3964                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3965         ls $DIR/$tdir/ext2-mountpoint | grep -q under_the_mount && error || true
3966         cleanup_test32_mount
3967 }
3968 run_test 32r "opendir follows mountpoints in Lustre (should return error)"
3969
3970 test_33aa() {
3971         rm -f $DIR/$tfile
3972         touch $DIR/$tfile
3973         chmod 444 $DIR/$tfile
3974         chown $RUNAS_ID $DIR/$tfile
3975         log 33_1
3976         $RUNAS $OPENFILE -f O_RDWR $DIR/$tfile && error || true
3977         log 33_2
3978 }
3979 run_test 33aa "write file with mode 444 (should return error)"
3980
3981 test_33a() {
3982         rm -fr $DIR/$tdir
3983         test_mkdir $DIR/$tdir
3984         chown $RUNAS_ID $DIR/$tdir
3985         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $DIR/$tdir/$tfile ||
3986                 error "$RUNAS create $tdir/$tfile failed"
3987         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $DIR/$tdir/$tfile &&
3988                 error "open RDWR" || true
3989 }
3990 run_test 33a "test open file(mode=0444) with O_RDWR (should return error)"
3991
3992 test_33b() {
3993         rm -fr $DIR/$tdir
3994         test_mkdir $DIR/$tdir
3995         chown $RUNAS_ID $DIR/$tdir
3996         $RUNAS $OPENFILE -f 1286739555 $DIR/$tdir/$tfile || true
3997 }
3998 run_test 33b "test open file with malformed flags (No panic)"
3999
4000 test_33c() {
4001         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4002         remote_ost_nodsh && skip "remote OST with nodsh"
4003
4004         local ostnum
4005         local ostname
4006         local write_bytes
4007         local all_zeros
4008
4009         all_zeros=true
4010         test_mkdir $DIR/$tdir
4011         # Read: 0, Write: 4, create/destroy: 2/0, stat: 1, punch: 0
4012
4013         sync
4014         for ostnum in $(seq $OSTCOUNT); do
4015                 # test-framework's OST numbering is one-based, while Lustre's
4016                 # is zero-based
4017                 ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
4018                 # check if at least some write_bytes stats are counted
4019                 write_bytes=$(do_facet ost$ostnum lctl get_param -n \
4020                               obdfilter.$ostname.stats |
4021                               awk '/^write_bytes/ {print $7}' )
4022                 echo "baseline_write_bytes@ost$ostnum/$ostname=$write_bytes"
4023                 if (( ${write_bytes:-0} > 0 )); then
4024                         all_zeros=false
4025                         break
4026                 fi
4027         done
4028
4029         $all_zeros || return 0
4030
4031         # Write four bytes
4032         echo foo > $DIR/$tdir/bar
4033         # Really write them
4034         sync
4035
4036         # Total up write_bytes after writing.  We'd better find non-zeros.
4037         for ostnum in $(seq $OSTCOUNT); do
4038                 ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
4039                 write_bytes=$(do_facet ost$ostnum lctl get_param -n \
4040                               obdfilter/$ostname/stats |
4041                               awk '/^write_bytes/ {print $7}' )
4042                 echo "write_bytes@ost$ostnum/$ostname=$write_bytes"
4043                 if (( ${write_bytes:-0} > 0 )); then
4044                         all_zeros=false
4045                         break
4046                 fi
4047         done
4048
4049         if $all_zeros; then
4050                 for ostnum in $(seq $OSTCOUNT); do
4051                         ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
4052                         echo "Check write_bytes is in obdfilter.*.stats:"
4053                         do_facet ost$ostnum lctl get_param -n \
4054                                 obdfilter.$ostname.stats
4055                 done
4056                 error "OST not keeping write_bytes stats (b=22312)"
4057         fi
4058 }
4059 run_test 33c "test write_bytes stats"
4060
4061 test_33d() {
4062         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
4063         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4064
4065         local MDTIDX=1
4066         local remote_dir=$DIR/$tdir/remote_dir
4067
4068         test_mkdir $DIR/$tdir
4069         $LFS mkdir -i $MDTIDX $remote_dir ||
4070                 error "create remote directory failed"
4071
4072         touch $remote_dir/$tfile
4073         chmod 444 $remote_dir/$tfile
4074         chown $RUNAS_ID $remote_dir/$tfile
4075
4076         $RUNAS $OPENFILE -f O_RDWR $DIR/$tfile && error || true
4077
4078         chown $RUNAS_ID $remote_dir
4079         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $remote_dir/f33 ||
4080                                         error "create" || true
4081         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $remote_dir/f33 &&
4082                                     error "open RDWR" || true
4083         $RUNAS $OPENFILE -f 1286739555 $remote_dir/f33 || true
4084 }
4085 run_test 33d "openfile with 444 modes and malformed flags under remote dir"
4086
4087 test_33e() {
4088         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
4089
4090         mkdir $DIR/$tdir
4091
4092         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
4093         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
4094         mkdir $DIR/$tdir/local_dir
4095
4096         local s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
4097         local s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
4098         local l_mode=$(stat -c%f $DIR/$tdir/local_dir)
4099
4100         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
4101                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode"
4102
4103         rmdir $DIR/$tdir/* || error "rmdir failed"
4104
4105         umask 777
4106         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
4107         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
4108         mkdir $DIR/$tdir/local_dir
4109
4110         s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
4111         s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
4112         l_mode=$(stat -c%f $DIR/$tdir/local_dir)
4113
4114         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
4115                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode 777"
4116
4117         rmdir $DIR/$tdir/* || error "rmdir(umask 777) failed"
4118
4119         umask 000
4120         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
4121         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
4122         mkdir $DIR/$tdir/local_dir
4123
4124         s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
4125         s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
4126         l_mode=$(stat -c%f $DIR/$tdir/local_dir)
4127
4128         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
4129                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode 0"
4130 }
4131 run_test 33e "mkdir and striped directory should have same mode"
4132
4133 cleanup_33f() {
4134         trap 0
4135         do_facet $SINGLEMDS $LCTL set_param mdt.*.enable_remote_dir_gid=0
4136 }
4137
4138 test_33f() {
4139         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
4140         remote_mds_nodsh && skip "remote MDS with nodsh"
4141
4142         mkdir $DIR/$tdir
4143         chmod go+rwx $DIR/$tdir
4144         do_facet $SINGLEMDS $LCTL set_param mdt.*.enable_remote_dir_gid=-1
4145         trap cleanup_33f EXIT
4146
4147         $RUNAS lfs mkdir -i 0 -c$MDSCOUNT $DIR/$tdir/striped_dir ||
4148                 error "cannot create striped directory"
4149
4150         $RUNAS touch $DIR/$tdir/striped_dir/{0..16} ||
4151                 error "cannot create files in striped directory"
4152
4153         $RUNAS rm $DIR/$tdir/striped_dir/{0..16} ||
4154                 error "cannot remove files in striped directory"
4155
4156         $RUNAS rmdir $DIR/$tdir/striped_dir ||
4157                 error "cannot remove striped directory"
4158
4159         cleanup_33f
4160 }
4161 run_test 33f "nonroot user can create, access, and remove a striped directory"
4162
4163 test_33g() {
4164         mkdir -p $DIR/$tdir/dir2
4165
4166         local err=$($RUNAS mkdir $DIR/$tdir/dir2 2>&1)
4167         echo $err
4168         [[ $err =~ "exists" ]] || error "Not exists error"
4169 }
4170 run_test 33g "nonroot user create already existing root created file"
4171
4172 test_33h() {
4173         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
4174         [ $MDS1_VERSION -lt $(version_code 2.13.50) ] &&
4175                 skip "Need MDS version at least 2.13.50"
4176
4177         test_mkdir -c $MDSCOUNT -H crush $DIR/$tdir ||
4178                 error "mkdir $tdir failed"
4179         touch $DIR/$tdir/$tfile || error "touch $tfile failed"
4180
4181         local index=$($LFS getstripe -m $DIR/$tdir/$tfile)
4182         local index2
4183
4184         for fname in $DIR/$tdir/$tfile.bak \
4185                      $DIR/$tdir/$tfile.SAV \
4186                      $DIR/$tdir/$tfile.orig \
4187                      $DIR/$tdir/$tfile~; do
4188                 touch $fname  || error "touch $fname failed"
4189                 index2=$($LFS getstripe -m $fname)
4190                 [ $index -eq $index2 ] ||
4191                         error "$fname MDT index mismatch $index != $index2"
4192         done
4193
4194         local failed=0
4195         for i in {1..250}; do
4196                 for fname in $(mktemp -u $DIR/$tdir/.$tfile.XXXXXX) \
4197                              $(mktemp $DIR/$tdir/$tfile.XXXXXXXX); do
4198                         touch $fname  || error "touch $fname failed"
4199                         index2=$($LFS getstripe -m $fname)
4200                         if [[ $index != $index2 ]]; then
4201                                 failed=$((failed + 1))
4202                                 echo "$fname MDT index mismatch $index != $index2"
4203                         fi
4204                 done
4205         done
4206         echo "$failed MDT index mismatches"
4207         (( failed < 20 )) || error "MDT index mismatch $failed times"
4208
4209 }
4210 run_test 33h "temp file is located on the same MDT as target"
4211
4212 TEST_34_SIZE=${TEST_34_SIZE:-2000000000000}
4213 test_34a() {
4214         rm -f $DIR/f34
4215         $MCREATE $DIR/f34 || error "mcreate failed"
4216         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
4217                 error "getstripe failed"
4218         $TRUNCATE $DIR/f34 $TEST_34_SIZE || error "truncate failed"
4219         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
4220                 error "getstripe failed"
4221         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4222                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4223 }
4224 run_test 34a "truncate file that has not been opened ==========="
4225
4226 test_34b() {
4227         [ ! -f $DIR/f34 ] && test_34a
4228         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4229                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4230         $OPENFILE -f O_RDONLY $DIR/f34
4231         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
4232                 error "getstripe failed"
4233         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4234                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4235 }
4236 run_test 34b "O_RDONLY opening file doesn't create objects ====="
4237
4238 test_34c() {
4239         [ ! -f $DIR/f34 ] && test_34a
4240         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4241                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4242         $OPENFILE -f O_RDWR $DIR/f34
4243         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" &&
4244                 error "$LFS getstripe failed"
4245         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4246                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4247 }
4248 run_test 34c "O_RDWR opening file-with-size works =============="
4249
4250 test_34d() {
4251         [ ! -f $DIR/f34 ] && test_34a
4252         dd if=/dev/zero of=$DIR/f34 conv=notrunc bs=4k count=1 ||
4253                 error "dd failed"
4254         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4255                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4256         rm $DIR/f34
4257 }
4258 run_test 34d "write to sparse file ============================="
4259
4260 test_34e() {
4261         rm -f $DIR/f34e
4262         $MCREATE $DIR/f34e || error "mcreate failed"
4263         $TRUNCATE $DIR/f34e 1000 || error "truncate failed"
4264         $CHECKSTAT -s 1000 $DIR/f34e ||
4265                 error "Size of $DIR/f34e not equal to 1000 bytes"
4266         $OPENFILE -f O_RDWR $DIR/f34e
4267         $CHECKSTAT -s 1000 $DIR/f34e ||
4268                 error "Size of $DIR/f34e not equal to 1000 bytes"
4269 }
4270 run_test 34e "create objects, some with size and some without =="
4271
4272 test_34f() { # bug 6242, 6243
4273         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4274
4275         SIZE34F=48000
4276         rm -f $DIR/f34f
4277         $MCREATE $DIR/f34f || error "mcreate failed"
4278         $TRUNCATE $DIR/f34f $SIZE34F || error "truncating $DIR/f3f to $SIZE34F"
4279         dd if=$DIR/f34f of=$TMP/f34f
4280         $CHECKSTAT -s $SIZE34F $TMP/f34f || error "$TMP/f34f not $SIZE34F bytes"
4281         dd if=/dev/zero of=$TMP/f34fzero bs=$SIZE34F count=1
4282         cmp $DIR/f34f $TMP/f34fzero || error "$DIR/f34f not all zero"
4283         cmp $TMP/f34f $TMP/f34fzero || error "$TMP/f34f not all zero"
4284         rm $TMP/f34f $TMP/f34fzero $DIR/f34f
4285 }
4286 run_test 34f "read from a file with no objects until EOF ======="
4287
4288 test_34g() {
4289         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4290
4291         dd if=/dev/zero of=$DIR/$tfile bs=1 count=100 seek=$TEST_34_SIZE ||
4292                 error "dd failed"
4293         $TRUNCATE $DIR/$tfile $((TEST_34_SIZE / 2))|| error "truncate failed"
4294         $CHECKSTAT -s $((TEST_34_SIZE / 2)) $DIR/$tfile ||
4295                 error "Size of $DIR/$tfile not equal to $((TEST_34_SIZE / 2))"
4296         cancel_lru_locks osc
4297         $CHECKSTAT -s $((TEST_34_SIZE / 2)) $DIR/$tfile ||
4298                 error "wrong size after lock cancel"
4299
4300         $TRUNCATE $DIR/$tfile $TEST_34_SIZE || error "truncate failed"
4301         $CHECKSTAT -s $TEST_34_SIZE $DIR/$tfile ||
4302                 error "expanding truncate failed"
4303         cancel_lru_locks osc
4304         $CHECKSTAT -s $TEST_34_SIZE $DIR/$tfile ||
4305                 error "wrong expanded size after lock cancel"
4306 }
4307 run_test 34g "truncate long file ==============================="
4308
4309 test_34h() {
4310         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4311
4312         local gid=10
4313         local sz=1000
4314
4315         dd if=/dev/zero of=$DIR/$tfile bs=1M count=10 || error "dd failed"
4316         sync # Flush the cache so that multiop below does not block on cache
4317              # flush when getting the group lock
4318         $MULTIOP $DIR/$tfile OG${gid}T${sz}g${gid}c &
4319         MULTIPID=$!
4320
4321         # Since just timed wait is not good enough, let's do a sync write
4322         # that way we are sure enough time for a roundtrip + processing
4323         # passed + 2 seconds of extra margin.
4324         dd if=/dev/zero of=$DIR/${tfile}-1 bs=$PAGE_SIZE oflag=direct count=1
4325         rm $DIR/${tfile}-1
4326         sleep 2
4327
4328         if [[ `ps h -o comm -p $MULTIPID` == "multiop" ]]; then
4329                 error "Multiop blocked on ftruncate, pid=$MULTIPID"
4330                 kill -9 $MULTIPID
4331         fi
4332         wait $MULTIPID
4333         local nsz=`stat -c %s $DIR/$tfile`
4334         [[ $nsz == $sz ]] || error "New size wrong $nsz != $sz"
4335 }
4336 run_test 34h "ftruncate file under grouplock should not block"
4337
4338 test_35a() {
4339         cp /bin/sh $DIR/f35a
4340         chmod 444 $DIR/f35a
4341         chown $RUNAS_ID $DIR/f35a
4342         $RUNAS $DIR/f35a && error || true
4343         rm $DIR/f35a
4344 }
4345 run_test 35a "exec file with mode 444 (should return and not leak)"
4346
4347 test_36a() {
4348         rm -f $DIR/f36
4349         utime $DIR/f36 || error "utime failed for MDS"
4350 }
4351 run_test 36a "MDS utime check (mknod, utime)"
4352
4353 test_36b() {
4354         echo "" > $DIR/f36
4355         utime $DIR/f36 || error "utime failed for OST"
4356 }
4357 run_test 36b "OST utime check (open, utime)"
4358
4359 test_36c() {
4360         rm -f $DIR/d36/f36
4361         test_mkdir $DIR/d36
4362         chown $RUNAS_ID $DIR/d36
4363         $RUNAS utime $DIR/d36/f36 || error "utime failed for MDS as non-root"
4364 }
4365 run_test 36c "non-root MDS utime check (mknod, utime)"
4366
4367 test_36d() {
4368         [ ! -d $DIR/d36 ] && test_36c
4369         echo "" > $DIR/d36/f36
4370         $RUNAS utime $DIR/d36/f36 || error "utime failed for OST as non-root"
4371 }
4372 run_test 36d "non-root OST utime check (open, utime)"
4373
4374 test_36e() {
4375         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID -- skipping"
4376
4377         test_mkdir $DIR/$tdir
4378         touch $DIR/$tdir/$tfile
4379         $RUNAS utime $DIR/$tdir/$tfile &&
4380                 error "utime worked, expected failure" || true
4381 }
4382 run_test 36e "utime on non-owned file (should return error)"
4383
4384 subr_36fh() {
4385         local fl="$1"
4386         local LANG_SAVE=$LANG
4387         local LC_LANG_SAVE=$LC_LANG
4388         export LANG=C LC_LANG=C # for date language
4389
4390         DATESTR="Dec 20  2000"
4391         test_mkdir $DIR/$tdir
4392         lctl set_param fail_loc=$fl
4393         date; date +%s
4394         cp /etc/hosts $DIR/$tdir/$tfile
4395         sync & # write RPC generated with "current" inode timestamp, but delayed
4396         sleep 1
4397         touch --date="$DATESTR" $DIR/$tdir/$tfile # setattr timestamp in past
4398         LS_BEFORE="`ls -l $DIR/$tdir/$tfile`" # old timestamp from client cache
4399         cancel_lru_locks $OSC
4400         LS_AFTER="`ls -l $DIR/$tdir/$tfile`"  # timestamp from OST object
4401         date; date +%s
4402         [ "$LS_BEFORE" != "$LS_AFTER" ] && \
4403                 echo "BEFORE: $LS_BEFORE" && \
4404                 echo "AFTER : $LS_AFTER" && \
4405                 echo "WANT  : $DATESTR" && \
4406                 error "$DIR/$tdir/$tfile timestamps changed" || true
4407
4408         export LANG=$LANG_SAVE LC_LANG=$LC_LANG_SAVE
4409 }
4410
4411 test_36f() {
4412         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4413
4414         #define OBD_FAIL_OST_BRW_PAUSE_BULK 0x214
4415         subr_36fh "0x80000214"
4416 }
4417 run_test 36f "utime on file racing with OST BRW write =========="
4418
4419 test_36g() {
4420         remote_ost_nodsh && skip "remote OST with nodsh"
4421         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4422         [ $MDS1_VERSION -lt $(version_code 2.12.51) ] &&
4423                 skip "Need MDS version at least 2.12.51"
4424
4425         local fmd_max_age
4426         local fmd
4427         local facet="ost1"
4428         local tgt="obdfilter"
4429
4430         [[ $OSC == "mdc" ]] && tgt="mdt" && facet="mds1"
4431
4432         test_mkdir $DIR/$tdir
4433         fmd_max_age=$(do_facet $facet \
4434                 "lctl get_param -n $tgt.*.tgt_fmd_seconds 2> /dev/null | \
4435                 head -n 1")
4436
4437         echo "FMD max age: ${fmd_max_age}s"
4438         touch $DIR/$tdir/$tfile
4439         fmd=$(do_facet $facet "lctl get_param -n $tgt.*.exports.*.fmd_count" |
4440                 gawk '{cnt=cnt+$1}  END{print cnt}')
4441         echo "FMD before: $fmd"
4442         [[ $fmd == 0 ]] &&
4443                 error "FMD wasn't create by touch"
4444         sleep $((fmd_max_age + 12))
4445         fmd=$(do_facet $facet "lctl get_param -n $tgt.*.exports.*.fmd_count" |
4446                 gawk '{cnt=cnt+$1}  END{print cnt}')
4447         echo "FMD after: $fmd"
4448         [[ $fmd == 0 ]] ||
4449                 error "FMD wasn't expired by ping"
4450 }
4451 run_test 36g "FMD cache expiry ====================="
4452
4453 test_36h() {
4454         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4455
4456         #define OBD_FAIL_OST_BRW_PAUSE_BULK2 0x227
4457         subr_36fh "0x80000227"
4458 }
4459 run_test 36h "utime on file racing with OST BRW write =========="
4460
4461 test_36i() {
4462         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
4463
4464         test_mkdir $DIR/$tdir
4465         $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir
4466
4467         local mtime=$(stat -c%Y $DIR/$tdir/striped_dir)
4468         local new_mtime=$((mtime + 200))
4469
4470         #change Modify time of striped dir
4471         touch -m -d @$new_mtime $DIR/$tdir/striped_dir ||
4472                         error "change mtime failed"
4473
4474         local got=$(stat -c%Y $DIR/$tdir/striped_dir)
4475
4476         [ "$new_mtime" = "$got" ] || error "expect $new_mtime got $got"
4477 }
4478 run_test 36i "change mtime on striped directory"
4479
4480 # test_37 - duplicate with tests 32q 32r
4481
4482 test_38() {
4483         local file=$DIR/$tfile
4484         touch $file
4485         openfile -f O_DIRECTORY $file
4486         local RC=$?
4487         local ENOTDIR=20
4488         [ $RC -eq 0 ] && error "opened file $file with O_DIRECTORY" || true
4489         [ $RC -eq $ENOTDIR ] || error "error $RC should be ENOTDIR ($ENOTDIR)"
4490 }
4491 run_test 38 "open a regular file with O_DIRECTORY should return -ENOTDIR ==="
4492
4493 test_39a() { # was test_39
4494         touch $DIR/$tfile
4495         touch $DIR/${tfile}2
4496 #       ls -l  $DIR/$tfile $DIR/${tfile}2
4497 #       ls -lu  $DIR/$tfile $DIR/${tfile}2
4498 #       ls -lc  $DIR/$tfile $DIR/${tfile}2
4499         sleep 2
4500         $OPENFILE -f O_CREAT:O_TRUNC:O_WRONLY $DIR/${tfile}2
4501         if [ ! $DIR/${tfile}2 -nt $DIR/$tfile ]; then
4502                 echo "mtime"
4503                 ls -l --full-time $DIR/$tfile $DIR/${tfile}2
4504                 echo "atime"
4505                 ls -lu --full-time $DIR/$tfile $DIR/${tfile}2
4506                 echo "ctime"
4507                 ls -lc --full-time $DIR/$tfile $DIR/${tfile}2
4508                 error "O_TRUNC didn't change timestamps"
4509         fi
4510 }
4511 run_test 39a "mtime changed on create"
4512
4513 test_39b() {
4514         test_mkdir -c1 $DIR/$tdir
4515         cp -p /etc/passwd $DIR/$tdir/fopen
4516         cp -p /etc/passwd $DIR/$tdir/flink
4517         cp -p /etc/passwd $DIR/$tdir/funlink
4518         cp -p /etc/passwd $DIR/$tdir/frename
4519         ln $DIR/$tdir/funlink $DIR/$tdir/funlink2
4520
4521         sleep 1
4522         echo "aaaaaa" >> $DIR/$tdir/fopen
4523         echo "aaaaaa" >> $DIR/$tdir/flink
4524         echo "aaaaaa" >> $DIR/$tdir/funlink
4525         echo "aaaaaa" >> $DIR/$tdir/frename
4526
4527         local open_new=`stat -c %Y $DIR/$tdir/fopen`
4528         local link_new=`stat -c %Y $DIR/$tdir/flink`
4529         local unlink_new=`stat -c %Y $DIR/$tdir/funlink`
4530         local rename_new=`stat -c %Y $DIR/$tdir/frename`
4531
4532         cat $DIR/$tdir/fopen > /dev/null
4533         ln $DIR/$tdir/flink $DIR/$tdir/flink2
4534         rm -f $DIR/$tdir/funlink2
4535         mv -f $DIR/$tdir/frename $DIR/$tdir/frename2
4536
4537         for (( i=0; i < 2; i++ )) ; do
4538                 local open_new2=`stat -c %Y $DIR/$tdir/fopen`
4539                 local link_new2=`stat -c %Y $DIR/$tdir/flink`
4540                 local unlink_new2=`stat -c %Y $DIR/$tdir/funlink`
4541                 local rename_new2=`stat -c %Y $DIR/$tdir/frename2`
4542
4543                 [ $open_new2 -eq $open_new ] || error "open file reverses mtime"
4544                 [ $link_new2 -eq $link_new ] || error "link file reverses mtime"
4545                 [ $unlink_new2 -eq $unlink_new ] || error "unlink file reverses mtime"
4546                 [ $rename_new2 -eq $rename_new ] || error "rename file reverses mtime"
4547
4548                 cancel_lru_locks $OSC
4549                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4550         done
4551 }
4552 run_test 39b "mtime change on open, link, unlink, rename  ======"
4553
4554 # this should be set to past
4555 TEST_39_MTIME=`date -d "1 year ago" +%s`
4556
4557 # bug 11063
4558 test_39c() {
4559         touch $DIR1/$tfile
4560         sleep 2
4561         local mtime0=`stat -c %Y $DIR1/$tfile`
4562
4563         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4564         local mtime1=`stat -c %Y $DIR1/$tfile`
4565         [ "$mtime1" = $TEST_39_MTIME ] || \
4566                 error "mtime is not set to past: $mtime1, should be $TEST_39_MTIME"
4567
4568         local d1=`date +%s`
4569         echo hello >> $DIR1/$tfile
4570         local d2=`date +%s`
4571         local mtime2=`stat -c %Y $DIR1/$tfile`
4572         [ "$mtime2" -ge "$d1" ] && [ "$mtime2" -le "$d2" ] || \
4573                 error "mtime is not updated on write: $d1 <= $mtime2 <= $d2"
4574
4575         mv $DIR1/$tfile $DIR1/$tfile-1
4576
4577         for (( i=0; i < 2; i++ )) ; do
4578                 local mtime3=`stat -c %Y $DIR1/$tfile-1`
4579                 [ "$mtime2" = "$mtime3" ] || \
4580                         error "mtime ($mtime2) changed (to $mtime3) on rename"
4581
4582                 cancel_lru_locks $OSC
4583                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4584         done
4585 }
4586 run_test 39c "mtime change on rename ==========================="
4587
4588 # bug 21114
4589 test_39d() {
4590         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4591
4592         touch $DIR1/$tfile
4593         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4594
4595         for (( i=0; i < 2; i++ )) ; do
4596                 local mtime=`stat -c %Y $DIR1/$tfile`
4597                 [ $mtime = $TEST_39_MTIME ] || \
4598                         error "mtime($mtime) is not set to $TEST_39_MTIME"
4599
4600                 cancel_lru_locks $OSC
4601                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4602         done
4603 }
4604 run_test 39d "create, utime, stat =============================="
4605
4606 # bug 21114
4607 test_39e() {
4608         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4609
4610         touch $DIR1/$tfile
4611         local mtime1=`stat -c %Y $DIR1/$tfile`
4612
4613         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4614
4615         for (( i=0; i < 2; i++ )) ; do
4616                 local mtime2=`stat -c %Y $DIR1/$tfile`
4617                 [ $mtime2 = $TEST_39_MTIME ] || \
4618                         error "mtime($mtime2) is not set to $TEST_39_MTIME"
4619
4620                 cancel_lru_locks $OSC
4621                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4622         done
4623 }
4624 run_test 39e "create, stat, utime, stat ========================"
4625
4626 # bug 21114
4627 test_39f() {
4628         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4629
4630         touch $DIR1/$tfile
4631         mtime1=`stat -c %Y $DIR1/$tfile`
4632
4633         sleep 2
4634         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4635
4636         for (( i=0; i < 2; i++ )) ; do
4637                 local mtime2=`stat -c %Y $DIR1/$tfile`
4638                 [ $mtime2 = $TEST_39_MTIME ] || \
4639                         error "mtime($mtime2) is not set to $TEST_39_MTIME"
4640
4641                 cancel_lru_locks $OSC
4642                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4643         done
4644 }
4645 run_test 39f "create, stat, sleep, utime, stat ================="
4646
4647 # bug 11063
4648 test_39g() {
4649         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4650
4651         echo hello >> $DIR1/$tfile
4652         local mtime1=`stat -c %Y $DIR1/$tfile`
4653
4654         sleep 2
4655         chmod o+r $DIR1/$tfile
4656
4657         for (( i=0; i < 2; i++ )) ; do
4658                 local mtime2=`stat -c %Y $DIR1/$tfile`
4659                 [ "$mtime1" = "$mtime2" ] || \
4660                         error "lost mtime: $mtime2, should be $mtime1"
4661
4662                 cancel_lru_locks $OSC
4663                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4664         done
4665 }
4666 run_test 39g "write, chmod, stat ==============================="
4667
4668 # bug 11063
4669 test_39h() {
4670         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4671
4672         touch $DIR1/$tfile
4673         sleep 1
4674
4675         local d1=`date`
4676         echo hello >> $DIR1/$tfile
4677         local mtime1=`stat -c %Y $DIR1/$tfile`
4678
4679         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4680         local d2=`date`
4681         if [ "$d1" != "$d2" ]; then
4682                 echo "write and touch not within one second"
4683         else
4684                 for (( i=0; i < 2; i++ )) ; do
4685                         local mtime2=`stat -c %Y $DIR1/$tfile`
4686                         [ "$mtime2" = $TEST_39_MTIME ] || \
4687                                 error "lost mtime: $mtime2, should be $TEST_39_MTIME"
4688
4689                         cancel_lru_locks $OSC
4690                         if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4691                 done
4692         fi
4693 }
4694 run_test 39h "write, utime within one second, stat ============="
4695
4696 test_39i() {
4697         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4698
4699         touch $DIR1/$tfile
4700         sleep 1
4701
4702         echo hello >> $DIR1/$tfile
4703         local mtime1=`stat -c %Y $DIR1/$tfile`
4704
4705         mv $DIR1/$tfile $DIR1/$tfile-1
4706
4707         for (( i=0; i < 2; i++ )) ; do
4708                 local mtime2=`stat -c %Y $DIR1/$tfile-1`
4709
4710                 [ "$mtime1" = "$mtime2" ] || \
4711                         error "lost mtime: $mtime2, should be $mtime1"
4712
4713                 cancel_lru_locks $OSC
4714                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4715         done
4716 }
4717 run_test 39i "write, rename, stat =============================="
4718
4719 test_39j() {
4720         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4721
4722         start_full_debug_logging
4723         touch $DIR1/$tfile
4724         sleep 1
4725
4726         #define OBD_FAIL_OSC_DELAY_SETTIME       0x412
4727         lctl set_param fail_loc=0x80000412
4728         multiop_bg_pause $DIR1/$tfile oO_RDWR:w2097152_c ||
4729                 error "multiop failed"
4730         local multipid=$!
4731         local mtime1=`stat -c %Y $DIR1/$tfile`
4732
4733         mv $DIR1/$tfile $DIR1/$tfile-1
4734
4735         kill -USR1 $multipid
4736         wait $multipid || error "multiop close failed"
4737
4738         for (( i=0; i < 2; i++ )) ; do
4739                 local mtime2=`stat -c %Y $DIR1/$tfile-1`
4740                 [ "$mtime1" = "$mtime2" ] ||
4741                         error "mtime is lost on close: $mtime2, " \
4742                               "should be $mtime1"
4743
4744                 cancel_lru_locks
4745                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4746         done
4747         lctl set_param fail_loc=0
4748         stop_full_debug_logging
4749 }
4750 run_test 39j "write, rename, close, stat ======================="
4751
4752 test_39k() {
4753         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4754
4755         touch $DIR1/$tfile
4756         sleep 1
4757
4758         multiop_bg_pause $DIR1/$tfile oO_RDWR:w2097152_c || error "multiop failed"
4759         local multipid=$!
4760         local mtime1=`stat -c %Y $DIR1/$tfile`
4761
4762         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4763
4764         kill -USR1 $multipid
4765         wait $multipid || error "multiop close failed"
4766
4767         for (( i=0; i < 2; i++ )) ; do
4768                 local mtime2=`stat -c %Y $DIR1/$tfile`
4769
4770                 [ "$mtime2" = $TEST_39_MTIME ] || \
4771                         error "mtime is lost on close: $mtime2, should be $TEST_39_MTIME"
4772
4773                 cancel_lru_locks
4774                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4775         done
4776 }
4777 run_test 39k "write, utime, close, stat ========================"
4778
4779 # this should be set to future
4780 TEST_39_ATIME=`date -d "1 year" +%s`
4781
4782 test_39l() {
4783         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4784         remote_mds_nodsh && skip "remote MDS with nodsh"
4785
4786         local atime_diff=$(do_facet $SINGLEMDS \
4787                                 lctl get_param -n mdd.*MDT0000*.atime_diff)
4788         rm -rf $DIR/$tdir
4789         mkdir_on_mdt0 $DIR/$tdir
4790
4791         # test setting directory atime to future
4792         touch -a -d @$TEST_39_ATIME $DIR/$tdir
4793         local atime=$(stat -c %X $DIR/$tdir)
4794         [ "$atime" = $TEST_39_ATIME ] ||
4795                 error "atime is not set to future: $atime, $TEST_39_ATIME"
4796
4797         # test setting directory atime from future to now
4798         local now=$(date +%s)
4799         touch -a -d @$now $DIR/$tdir
4800
4801         atime=$(stat -c %X $DIR/$tdir)
4802         [ "$atime" -eq "$now"  ] ||
4803                 error "atime is not updated from future: $atime, $now"
4804
4805         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=2
4806         sleep 3
4807
4808         # test setting directory atime when now > dir atime + atime_diff
4809         local d1=$(date +%s)
4810         ls $DIR/$tdir
4811         local d2=$(date +%s)
4812         cancel_lru_locks mdc
4813         atime=$(stat -c %X $DIR/$tdir)
4814         [ "$atime" -ge "$d1" -a "$atime" -le "$d2" ] ||
4815                 error "atime is not updated  : $atime, should be $d2"
4816
4817         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=60
4818         sleep 3
4819
4820         # test not setting directory atime when now < dir atime + atime_diff
4821         ls $DIR/$tdir
4822         cancel_lru_locks mdc
4823         atime=$(stat -c %X $DIR/$tdir)
4824         [ "$atime" -ge "$d1" -a "$atime" -le "$d2" ] ||
4825                 error "atime is updated to $atime, should remain $d1<atime<$d2"
4826
4827         do_facet $SINGLEMDS \
4828                 lctl set_param -n mdd.*MDT0000*.atime_diff=$atime_diff
4829 }
4830 run_test 39l "directory atime update ==========================="
4831
4832 test_39m() {
4833         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4834
4835         touch $DIR1/$tfile
4836         sleep 2
4837         local far_past_mtime=$(date -d "May 29 1953" +%s)
4838         local far_past_atime=$(date -d "Dec 17 1903" +%s)
4839
4840         touch -m -d @$far_past_mtime $DIR1/$tfile
4841         touch -a -d @$far_past_atime $DIR1/$tfile
4842
4843         for (( i=0; i < 2; i++ )) ; do
4844                 local timestamps=$(stat -c "%X %Y" $DIR1/$tfile)
4845                 [ "$timestamps" = "$far_past_atime $far_past_mtime" ] || \
4846                         error "atime or mtime set incorrectly"
4847
4848                 cancel_lru_locks $OSC
4849                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4850         done
4851 }
4852 run_test 39m "test atime and mtime before 1970"
4853
4854 test_39n() { # LU-3832
4855         remote_mds_nodsh && skip "remote MDS with nodsh"
4856
4857         local atime_diff=$(do_facet $SINGLEMDS \
4858                 lctl get_param -n mdd.*MDT0000*.atime_diff)
4859         local atime0
4860         local atime1
4861         local atime2
4862
4863         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=1
4864
4865         rm -rf $DIR/$tfile
4866         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 status=noxfer
4867         atime0=$(stat -c %X $DIR/$tfile)
4868
4869         sleep 5
4870         $MULTIOP $DIR/$tfile oO_RDONLY:O_NOATIME:r4096c
4871         atime1=$(stat -c %X $DIR/$tfile)
4872
4873         sleep 5
4874         cancel_lru_locks mdc
4875         cancel_lru_locks osc
4876         $MULTIOP $DIR/$tfile oO_RDONLY:O_NOATIME:r4096c
4877         atime2=$(stat -c %X $DIR/$tfile)
4878
4879         do_facet $SINGLEMDS \
4880                 lctl set_param -n mdd.*MDT0000*.atime_diff=$atime_diff
4881
4882         [ "$atime0" -eq "$atime1" ] || error "atime0 $atime0 != atime1 $atime1"
4883         [ "$atime1" -eq "$atime2" ] || error "atime0 $atime0 != atime1 $atime1"
4884 }
4885 run_test 39n "check that O_NOATIME is honored"
4886
4887 test_39o() {
4888         TESTDIR=$DIR/$tdir/$tfile
4889         [ -e $TESTDIR ] && rm -rf $TESTDIR
4890         mkdir -p $TESTDIR
4891         cd $TESTDIR
4892         links1=2
4893         ls
4894         mkdir a b
4895         ls
4896         links2=$(stat -c %h .)
4897         [ $(($links1 + 2)) != $links2 ] &&
4898                 error "wrong links count $(($links1 + 2)) != $links2"
4899         rmdir b
4900         links3=$(stat -c %h .)
4901         [ $(($links1 + 1)) != $links3 ] &&
4902                 error "wrong links count $links1 != $links3"
4903         return 0
4904 }
4905 run_test 39o "directory cached attributes updated after create"
4906
4907 test_39p() {
4908         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
4909
4910         local MDTIDX=1
4911         TESTDIR=$DIR/$tdir/$tdir
4912         [ -e $TESTDIR ] && rm -rf $TESTDIR
4913         test_mkdir -p $TESTDIR
4914         cd $TESTDIR
4915         links1=2
4916         ls
4917         test_mkdir -i $MDTIDX $TESTDIR/remote_dir1
4918         test_mkdir -i $MDTIDX $TESTDIR/remote_dir2
4919         ls
4920         links2=$(stat -c %h .)
4921         [ $(($links1 + 2)) != $links2 ] &&
4922                 error "wrong links count $(($links1 + 2)) != $links2"
4923         rmdir remote_dir2
4924         links3=$(stat -c %h .)
4925         [ $(($links1 + 1)) != $links3 ] &&
4926                 error "wrong links count $links1 != $links3"
4927         return 0
4928 }
4929 run_test 39p "remote directory cached attributes updated after create ========"
4930
4931 test_39r() {
4932         [ $OST1_VERSION -ge $(version_code 2.13.52) ] ||
4933                 skip "no atime update on old OST"
4934         if [ "$ost1_FSTYPE" != ldiskfs ]; then
4935                 skip_env "ldiskfs only test"
4936         fi
4937
4938         local saved_adiff
4939         saved_adiff=$(do_facet ost1 \
4940                 lctl get_param -n obdfilter.*OST0000.atime_diff)
4941         stack_trap "do_facet ost1 \
4942                 lctl set_param obdfilter.*.atime_diff=$saved_adiff"
4943
4944         do_facet ost1 "lctl set_param obdfilter.*.atime_diff=5"
4945
4946         $LFS setstripe -i 0 $DIR/$tfile
4947         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 ||
4948                 error "can't write initial file"
4949         cancel_lru_locks osc
4950
4951         # exceed atime_diff and access file
4952         sleep 6
4953         dd if=$DIR/$tfile of=/dev/null bs=4k count=1 ||
4954                 error "can't udpate atime"
4955
4956         local atime_cli=$(stat -c %X $DIR/$tfile)
4957         echo "client atime: $atime_cli"
4958         # allow atime update to be written to device
4959         do_facet ost1 "$LCTL set_param -n osd*.*OST*.force_sync 1"
4960         sleep 5
4961
4962         local ostdev=$(ostdevname 1)
4963         local fid=($(lfs getstripe -y $DIR/$tfile |
4964                         awk '/l_fid:/ { print $2 }' | tr ':' ' '))
4965         local objpath="O/0/d$((${fid[1]} % 32))/$((${fid[1]}))"
4966         local cmd="debugfs -c -R \\\"stat $objpath\\\" $ostdev"
4967
4968         echo "OST atime: $(do_facet ost1 "$cmd" |& grep atime)"
4969         local atime_ost=$(do_facet ost1 "$cmd" |&
4970                           awk -F'[: ]' '/atime:/ { print $4 }')
4971         (( atime_cli == atime_ost )) ||
4972                 error "atime on client $atime_cli != ost $atime_ost"
4973 }
4974 run_test 39r "lazy atime update on OST"
4975
4976 test_39q() { # LU-8041
4977         local testdir=$DIR/$tdir
4978         mkdir -p $testdir
4979         multiop_bg_pause $testdir D_c || error "multiop failed"
4980         local multipid=$!
4981         cancel_lru_locks mdc
4982         kill -USR1 $multipid
4983         local atime=$(stat -c %X $testdir)
4984         [ "$atime" -ne 0 ] || error "atime is zero"
4985 }
4986 run_test 39q "close won't zero out atime"
4987
4988 test_40() {
4989         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1
4990         $RUNAS $OPENFILE -f O_WRONLY:O_TRUNC $DIR/$tfile &&
4991                 error "openfile O_WRONLY:O_TRUNC $tfile failed"
4992         $CHECKSTAT -t file -s 4096 $DIR/$tfile ||
4993                 error "$tfile is not 4096 bytes in size"
4994 }
4995 run_test 40 "failed open(O_TRUNC) doesn't truncate ============="
4996
4997 test_41() {
4998         # bug 1553
4999         small_write $DIR/f41 18
5000 }
5001 run_test 41 "test small file write + fstat ====================="
5002
5003 count_ost_writes() {
5004         lctl get_param -n ${OSC}.*.stats |
5005                 awk -vwrites=0 '/ost_write/ { writes += $2 } \
5006                         END { printf("%0.0f", writes) }'
5007 }
5008
5009 # decent default
5010 WRITEBACK_SAVE=500
5011 DIRTY_RATIO_SAVE=40
5012 MAX_DIRTY_RATIO=50
5013 BG_DIRTY_RATIO_SAVE=10
5014 MAX_BG_DIRTY_RATIO=25
5015
5016 start_writeback() {
5017         trap 0
5018         # in 2.6, restore /proc/sys/vm/dirty_writeback_centisecs,
5019         # dirty_ratio, dirty_background_ratio
5020         if [ -f /proc/sys/vm/dirty_writeback_centisecs ]; then
5021                 sysctl -w vm.dirty_writeback_centisecs=$WRITEBACK_SAVE
5022                 sysctl -w vm.dirty_background_ratio=$BG_DIRTY_RATIO_SAVE
5023                 sysctl -w vm.dirty_ratio=$DIRTY_RATIO_SAVE
5024         else
5025                 # if file not here, we are a 2.4 kernel
5026                 kill -CONT `pidof kupdated`
5027         fi
5028 }
5029
5030 stop_writeback() {
5031         # setup the trap first, so someone cannot exit the test at the
5032         # exact wrong time and mess up a machine
5033         trap start_writeback EXIT
5034         # in 2.6, save and 0 /proc/sys/vm/dirty_writeback_centisecs
5035         if [ -f /proc/sys/vm/dirty_writeback_centisecs ]; then
5036                 WRITEBACK_SAVE=`sysctl -n vm.dirty_writeback_centisecs`
5037                 sysctl -w vm.dirty_writeback_centisecs=0
5038                 sysctl -w vm.dirty_writeback_centisecs=0
5039                 # save and increase /proc/sys/vm/dirty_ratio
5040                 DIRTY_RATIO_SAVE=`sysctl -n vm.dirty_ratio`
5041                 sysctl -w vm.dirty_ratio=$MAX_DIRTY_RATIO
5042                 # save and increase /proc/sys/vm/dirty_background_ratio
5043                 BG_DIRTY_RATIO_SAVE=`sysctl -n vm.dirty_background_ratio`
5044                 sysctl -w vm.dirty_background_ratio=$MAX_BG_DIRTY_RATIO
5045         else
5046                 # if file not here, we are a 2.4 kernel
5047                 kill -STOP `pidof kupdated`
5048         fi
5049 }
5050
5051 # ensure that all stripes have some grant before we test client-side cache
5052 setup_test42() {
5053         for i in `seq -f $DIR/f42-%g 1 $OSTCOUNT`; do
5054                 dd if=/dev/zero of=$i bs=4k count=1
5055                 rm $i
5056         done
5057 }
5058
5059 # Tests 42* verify that our behaviour is correct WRT caching, file closure,
5060 # file truncation, and file removal.
5061 test_42a() {
5062         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5063
5064         setup_test42
5065         cancel_lru_locks $OSC
5066         stop_writeback
5067         sync; sleep 1; sync # just to be safe
5068         BEFOREWRITES=`count_ost_writes`
5069         lctl get_param -n osc.*[oO][sS][cC][_-]*.cur_grant_bytes | grep "[0-9]"
5070         dd if=/dev/zero of=$DIR/f42a bs=1024 count=100
5071         AFTERWRITES=`count_ost_writes`
5072         [ $BEFOREWRITES -eq $AFTERWRITES ] || \
5073                 error "$BEFOREWRITES < $AFTERWRITES"
5074         start_writeback
5075 }
5076 run_test 42a "ensure that we don't flush on close"
5077
5078 test_42b() {
5079         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5080
5081         setup_test42
5082         cancel_lru_locks $OSC
5083         stop_writeback
5084         sync
5085         dd if=/dev/zero of=$DIR/f42b bs=1024 count=100
5086         BEFOREWRITES=$(count_ost_writes)
5087         $MUNLINK $DIR/f42b || error "$MUNLINK $DIR/f42b: $?"
5088         AFTERWRITES=$(count_ost_writes)
5089         if [[ $BEFOREWRITES -lt $AFTERWRITES ]]; then
5090                 error "$BEFOREWRITES < $AFTERWRITES on unlink"
5091         fi
5092         BEFOREWRITES=$(count_ost_writes)
5093         sync || error "sync: $?"
5094         AFTERWRITES=$(count_ost_writes)
5095         if [[ $BEFOREWRITES -lt $AFTERWRITES ]]; then
5096                 error "$BEFOREWRITES < $AFTERWRITES on sync"
5097         fi
5098         dmesg | grep 'error from obd_brw_async' && error 'error writing back'
5099         start_writeback
5100         return 0
5101 }
5102 run_test 42b "test destroy of file with cached dirty data ======"
5103
5104 # if these tests just want to test the effect of truncation,
5105 # they have to be very careful.  consider:
5106 # - the first open gets a {0,EOF}PR lock
5107 # - the first write conflicts and gets a {0, count-1}PW
5108 # - the rest of the writes are under {count,EOF}PW
5109 # - the open for truncate tries to match a {0,EOF}PR
5110 #   for the filesize and cancels the PWs.
5111 # any number of fixes (don't get {0,EOF} on open, match
5112 # composite locks, do smarter file size management) fix
5113 # this, but for now we want these tests to verify that
5114 # the cancellation with truncate intent works, so we
5115 # start the file with a full-file pw lock to match against
5116 # until the truncate.
5117 trunc_test() {
5118         test=$1
5119         file=$DIR/$test
5120         offset=$2
5121         cancel_lru_locks $OSC
5122         stop_writeback
5123         # prime the file with 0,EOF PW to match
5124         touch $file
5125         $TRUNCATE $file 0
5126         sync; sync
5127         # now the real test..
5128         dd if=/dev/zero of=$file bs=1024 count=100
5129         BEFOREWRITES=`count_ost_writes`
5130         $TRUNCATE $file $offset
5131         cancel_lru_locks $OSC
5132         AFTERWRITES=`count_ost_writes`
5133         start_writeback
5134 }
5135
5136 test_42c() {
5137         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5138
5139         trunc_test 42c 1024
5140         [ $BEFOREWRITES -eq $AFTERWRITES ] &&
5141                 error "beforewrites $BEFOREWRITES == afterwrites $AFTERWRITES on truncate"
5142         rm $file
5143 }
5144 run_test 42c "test partial truncate of file with cached dirty data"
5145
5146 test_42d() {
5147         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5148
5149         trunc_test 42d 0
5150         [ $BEFOREWRITES -eq $AFTERWRITES ] ||
5151                 error "beforewrites $BEFOREWRITES != afterwrites $AFTERWRITES on truncate"
5152         rm $file
5153 }
5154 run_test 42d "test complete truncate of file with cached dirty data"
5155
5156 test_42e() { # bug22074
5157         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5158
5159         local TDIR=$DIR/${tdir}e
5160         local pages=16 # hardcoded 16 pages, don't change it.
5161         local files=$((OSTCOUNT * 500)) # hopefully 500 files on each OST
5162         local proc_osc0="osc.${FSNAME}-OST0000-osc-[^MDT]*"
5163         local max_dirty_mb
5164         local warmup_files
5165
5166         test_mkdir $DIR/${tdir}e
5167         $LFS setstripe -c 1 $TDIR
5168         createmany -o $TDIR/f $files
5169
5170         max_dirty_mb=$($LCTL get_param -n $proc_osc0/max_dirty_mb)
5171
5172         # we assume that with $OSTCOUNT files, at least one of them will
5173         # be allocated on OST0.
5174         warmup_files=$((OSTCOUNT * max_dirty_mb))
5175         createmany -o $TDIR/w $warmup_files
5176
5177         # write a large amount of data into one file and sync, to get good
5178         # avail_grant number from OST.
5179         for ((i=0; i<$warmup_files; i++)); do
5180                 idx=$($LFS getstripe -i $TDIR/w$i)
5181                 [ $idx -ne 0 ] && continue
5182                 dd if=/dev/zero of=$TDIR/w$i bs="$max_dirty_mb"M count=1
5183                 break
5184         done
5185         [[ $i -gt $warmup_files ]] && error "OST0 is still cold"
5186         sync
5187         $LCTL get_param $proc_osc0/cur_dirty_bytes
5188         $LCTL get_param $proc_osc0/cur_grant_bytes
5189
5190         # create as much dirty pages as we can while not to trigger the actual
5191         # RPCs directly. but depends on the env, VFS may trigger flush during this
5192         # period, hopefully we are good.
5193         for ((i=0; i<$warmup_files; i++)); do
5194                 idx=$($LFS getstripe -i $TDIR/w$i)
5195                 [ $idx -ne 0 ] && continue
5196                 dd if=/dev/zero of=$TDIR/w$i bs=1M count=1 2>/dev/null
5197         done
5198         $LCTL get_param $proc_osc0/cur_dirty_bytes
5199         $LCTL get_param $proc_osc0/cur_grant_bytes
5200
5201         # perform the real test
5202         $LCTL set_param $proc_osc0/rpc_stats 0
5203         for ((;i<$files; i++)); do
5204                 [ $($LFS getstripe -i $TDIR/f$i) -eq 0 ] || continue
5205                 dd if=/dev/zero of=$TDIR/f$i bs=$PAGE_SIZE count=$pages 2>/dev/null
5206         done
5207         sync
5208         $LCTL get_param $proc_osc0/rpc_stats
5209
5210         local percent=0
5211         local have_ppr=false
5212         $LCTL get_param $proc_osc0/rpc_stats |
5213                 while read PPR RRPC RPCT RCUM BAR WRPC WPCT WCUM; do
5214                         # skip lines until we are at the RPC histogram data
5215                         [ "$PPR" == "pages" ] && have_ppr=true && continue
5216                         $have_ppr || continue
5217
5218                         # we only want the percent stat for < 16 pages
5219                         [[ $(echo $PPR | tr -d ':') -ge $pages ]] && break
5220
5221                         percent=$((percent + WPCT))
5222                         if [[ $percent -gt 15 ]]; then
5223                                 error "less than 16-pages write RPCs" \
5224                                       "$percent% > 15%"
5225                                 break
5226                         fi
5227                 done
5228         rm -rf $TDIR
5229 }
5230 run_test 42e "verify sub-RPC writes are not done synchronously"
5231
5232 test_43A() { # was test_43
5233         test_mkdir $DIR/$tdir
5234         cp -p /bin/ls $DIR/$tdir/$tfile
5235         $MULTIOP $DIR/$tdir/$tfile Ow_c &
5236         pid=$!
5237         # give multiop a chance to open
5238         sleep 1
5239
5240         $DIR/$tdir/$tfile && error "execute $DIR/$tdir/$tfile succeeded" || true
5241         kill -USR1 $pid
5242         # Wait for multiop to exit
5243         wait $pid
5244 }
5245 run_test 43A "execution of file opened for write should return -ETXTBSY"
5246
5247 test_43a() {
5248         test_mkdir $DIR/$tdir
5249         cp -p $(which sleep) $DIR/$tdir/sleep || error "can't copy"
5250         $DIR/$tdir/sleep 60 &
5251         SLEEP_PID=$!
5252         # Make sure exec of $tdir/sleep wins race with truncate
5253         sleep 1
5254         $MULTIOP $DIR/$tdir/sleep Oc && error "expected error, got success"
5255         kill $SLEEP_PID
5256 }
5257 run_test 43a "open(RDWR) of file being executed should return -ETXTBSY"
5258
5259 test_43b() {
5260         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5261
5262         test_mkdir $DIR/$tdir
5263         cp -p $(which sleep) $DIR/$tdir/sleep || error "can't copy"
5264         $DIR/$tdir/sleep 60 &
5265         SLEEP_PID=$!
5266         # Make sure exec of $tdir/sleep wins race with truncate
5267         sleep 1
5268         $TRUNCATE $DIR/$tdir/sleep 0 && error "expected error, got success"
5269         kill $SLEEP_PID
5270 }
5271 run_test 43b "truncate of file being executed should return -ETXTBSY"
5272
5273 test_43c() {
5274         local testdir="$DIR/$tdir"
5275         test_mkdir $testdir
5276         cp $SHELL $testdir/
5277         ( cd $(dirname $SHELL) && md5sum $(basename $SHELL) ) |
5278                 ( cd $testdir && md5sum -c )
5279 }
5280 run_test 43c "md5sum of copy into lustre"
5281
5282 test_44A() { # was test_44
5283         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
5284
5285         dd if=/dev/zero of=$DIR/f1 bs=4k count=1 seek=1023
5286         dd if=$DIR/f1 bs=4k count=1 > /dev/null
5287 }
5288 run_test 44A "zero length read from a sparse stripe"
5289
5290 test_44a() {
5291         local nstripe=$($LFS getstripe -c -d $DIR)
5292         [ -z "$nstripe" ] && skip "can't get stripe info"
5293         [[ $nstripe -gt $OSTCOUNT ]] &&
5294                 skip "Wrong default stripe_count: $nstripe OSTCOUNT: $OSTCOUNT"
5295
5296         local stride=$($LFS getstripe -S -d $DIR)
5297         if [[ $nstripe -eq 0 || $nstripe -eq -1 ]]; then
5298                 nstripe=$($LFS df $DIR | grep OST: | wc -l)
5299         fi
5300
5301         OFFSETS="0 $((stride/2)) $((stride-1))"
5302         for offset in $OFFSETS; do
5303                 for i in $(seq 0 $((nstripe-1))); do
5304                         local GLOBALOFFSETS=""
5305                         # size in Bytes
5306                         local size=$((((i + 2 * $nstripe )*$stride + $offset)))
5307                         local myfn=$DIR/d44a-$size
5308                         echo "--------writing $myfn at $size"
5309                         ll_sparseness_write $myfn $size ||
5310                                 error "ll_sparseness_write"
5311                         GLOBALOFFSETS="$GLOBALOFFSETS $size"
5312                         ll_sparseness_verify $myfn $GLOBALOFFSETS ||
5313                                 error "ll_sparseness_verify $GLOBALOFFSETS"
5314
5315                         for j in $(seq 0 $((nstripe-1))); do
5316                                 # size in Bytes
5317                                 size=$((((j + $nstripe )*$stride + $offset)))
5318                                 ll_sparseness_write $myfn $size ||
5319                                         error "ll_sparseness_write"
5320                                 GLOBALOFFSETS="$GLOBALOFFSETS $size"
5321                         done
5322                         ll_sparseness_verify $myfn $GLOBALOFFSETS ||
5323                                 error "ll_sparseness_verify $GLOBALOFFSETS"
5324                         rm -f $myfn
5325                 done
5326         done
5327 }
5328 run_test 44a "test sparse pwrite ==============================="
5329
5330 dirty_osc_total() {
5331         tot=0
5332         for d in `lctl get_param -n ${OSC}.*.cur_dirty_bytes`; do
5333                 tot=$(($tot + $d))
5334         done
5335         echo $tot
5336 }
5337 do_dirty_record() {
5338         before=`dirty_osc_total`
5339         echo executing "\"$*\""
5340         eval $*
5341         after=`dirty_osc_total`
5342         echo before $before, after $after
5343 }
5344 test_45() {
5345         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5346
5347         f="$DIR/f45"
5348         # Obtain grants from OST if it supports it
5349         echo blah > ${f}_grant
5350         stop_writeback
5351         sync
5352         do_dirty_record "echo blah > $f"
5353         [[ $before -eq $after ]] && error "write wasn't cached"
5354         do_dirty_record "> $f"
5355         [[ $before -gt $after ]] || error "truncate didn't lower dirty count"
5356         do_dirty_record "echo blah > $f"
5357         [[ $before -eq $after ]] && error "write wasn't cached"
5358         do_dirty_record "sync"
5359         [[ $before -gt $after ]] || error "writeback didn't lower dirty count"
5360         do_dirty_record "echo blah > $f"
5361         [[ $before -eq $after ]] && error "write wasn't cached"
5362         do_dirty_record "cancel_lru_locks osc"
5363         [[ $before -gt $after ]] ||
5364                 error "lock cancellation didn't lower dirty count"
5365         start_writeback
5366 }
5367 run_test 45 "osc io page accounting ============================"
5368
5369 # in a 2 stripe file (lov.sh), page 1023 maps to page 511 in its object.  this
5370 # test tickles a bug where re-dirtying a page was failing to be mapped to the
5371 # objects offset and an assert hit when an rpc was built with 1023's mapped
5372 # offset 511 and 511's raw 511 offset. it also found general redirtying bugs.
5373 test_46() {
5374         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5375
5376         f="$DIR/f46"
5377         stop_writeback
5378         sync
5379         dd if=/dev/zero of=$f bs=$PAGE_SIZE seek=511 count=1
5380         sync
5381         dd conv=notrunc if=/dev/zero of=$f bs=$PAGE_SIZE seek=1023 count=1
5382         dd conv=notrunc if=/dev/zero of=$f bs=$PAGE_SIZE seek=511 count=1
5383         sync
5384         start_writeback
5385 }
5386 run_test 46 "dirtying a previously written page ================"
5387
5388 # test_47 is removed "Device nodes check" is moved to test_28
5389
5390 test_48a() { # bug 2399
5391         [ "$mds1_FSTYPE" = "zfs" ] &&
5392         [ $MDS1_VERSION -lt $(version_code 2.3.63) ] &&
5393                 skip "MDS prior to 2.3.63 handle ZFS dir .. incorrectly"
5394
5395         test_mkdir $DIR/$tdir
5396         cd $DIR/$tdir
5397         mv $DIR/$tdir $DIR/$tdir.new || error "move directory failed"
5398         test_mkdir $DIR/$tdir
5399         touch foo || error "'touch foo' failed after recreating cwd"
5400         test_mkdir bar
5401         touch .foo || error "'touch .foo' failed after recreating cwd"
5402         test_mkdir .bar
5403         ls . > /dev/null || error "'ls .' failed after recreating cwd"
5404         ls .. > /dev/null || error "'ls ..' failed after removing cwd"
5405         cd . || error "'cd .' failed after recreating cwd"
5406         mkdir . && error "'mkdir .' worked after recreating cwd"
5407         rmdir . && error "'rmdir .' worked after recreating cwd"
5408         ln -s . baz || error "'ln -s .' failed after recreating cwd"
5409         cd .. || error "'cd ..' failed after recreating cwd"
5410 }
5411 run_test 48a "Access renamed working dir (should return errors)="
5412
5413 test_48b() { # bug 2399
5414         rm -rf $DIR/$tdir
5415         test_mkdir $DIR/$tdir
5416         cd $DIR/$tdir
5417         rmdir $DIR/$tdir || error "remove cwd $DIR/$tdir failed"
5418         touch foo && error "'touch foo' worked after removing cwd"
5419         mkdir foo && error "'mkdir foo' worked after removing cwd"
5420         touch .foo && error "'touch .foo' worked after removing cwd"
5421         mkdir .foo && error "'mkdir .foo' worked after removing cwd"
5422         ls . > /dev/null && error "'ls .' worked after removing cwd"
5423         ls .. > /dev/null || error "'ls ..' failed after removing cwd"
5424         mkdir . && error "'mkdir .' worked after removing cwd"
5425         rmdir . && error "'rmdir .' worked after removing cwd"
5426         ln -s . foo && error "'ln -s .' worked after removing cwd"
5427         cd .. || echo "'cd ..' failed after removing cwd `pwd`"  #bug 3517
5428 }
5429 run_test 48b "Access removed working dir (should return errors)="
5430
5431 test_48c() { # bug 2350
5432         #lctl set_param debug=-1
5433         #set -vx
5434         rm -rf $DIR/$tdir
5435         test_mkdir -p $DIR/$tdir/dir
5436         cd $DIR/$tdir/dir
5437         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
5438         $TRACE touch foo && error "touch foo worked after removing cwd"
5439         $TRACE mkdir foo && error "'mkdir foo' worked after removing cwd"
5440         touch .foo && error "touch .foo worked after removing cwd"
5441         mkdir .foo && error "mkdir .foo worked after removing cwd"
5442         $TRACE ls . && error "'ls .' worked after removing cwd"
5443         $TRACE ls .. || error "'ls ..' failed after removing cwd"
5444         $TRACE mkdir . && error "'mkdir .' worked after removing cwd"
5445         $TRACE rmdir . && error "'rmdir .' worked after removing cwd"
5446         $TRACE ln -s . foo && error "'ln -s .' worked after removing cwd"
5447         $TRACE cd .. || echo "'cd ..' failed after removing cwd `pwd`" #bug 3415
5448 }
5449 run_test 48c "Access removed working subdir (should return errors)"
5450
5451 test_48d() { # bug 2350
5452         #lctl set_param debug=-1
5453         #set -vx
5454         rm -rf $DIR/$tdir
5455         test_mkdir -p $DIR/$tdir/dir
5456         cd $DIR/$tdir/dir
5457         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
5458         $TRACE rmdir $DIR/$tdir || error "remove parent $DIR/$tdir failed"
5459         $TRACE touch foo && error "'touch foo' worked after removing parent"
5460         $TRACE mkdir foo && error "mkdir foo worked after removing parent"
5461         touch .foo && error "'touch .foo' worked after removing parent"
5462         mkdir .foo && error "mkdir .foo worked after removing parent"
5463         $TRACE ls . && error "'ls .' worked after removing parent"
5464         $TRACE ls .. && error "'ls ..' worked after removing parent"
5465         $TRACE mkdir . && error "'mkdir .' worked after removing parent"
5466         $TRACE rmdir . && error "'rmdir .' worked after removing parent"
5467         $TRACE ln -s . foo && error "'ln -s .' worked after removing parent"
5468         true
5469 }
5470 run_test 48d "Access removed parent subdir (should return errors)"
5471
5472 test_48e() { # bug 4134
5473         #lctl set_param debug=-1
5474         #set -vx
5475         rm -rf $DIR/$tdir
5476         test_mkdir -p $DIR/$tdir/dir
5477         cd $DIR/$tdir/dir
5478         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
5479         $TRACE rmdir $DIR/$tdir || error "remove parent $DIR/$tdir failed"
5480         $TRACE touch $DIR/$tdir || error "'touch $DIR/$tdir' failed"
5481         $TRACE chmod +x $DIR/$tdir || error "'chmod +x $DIR/$tdir' failed"
5482         # On a buggy kernel addition of "touch foo" after cd .. will
5483         # produce kernel oops in lookup_hash_it
5484         touch ../foo && error "'cd ..' worked after recreate parent"
5485         cd $DIR
5486         $TRACE rm $DIR/$tdir || error "rm '$DIR/$tdir' failed"
5487 }
5488 run_test 48e "Access to recreated parent subdir (should return errors)"
5489
5490 test_48f() {
5491         [[ $MDS1_VERSION -ge $(version_code 2.13.55) ]] ||
5492                 skip "need MDS >= 2.13.55"
5493         [[ $MDSCOUNT -ge 2 ]] || skip "needs >= 2 MDTs"
5494         [[ "$(facet_host mds1)" != "$(facet_host mds2)" ]] ||
5495                 skip "needs different host for mdt1 mdt2"
5496         [[ $(facet_fstype mds1) == ldiskfs ]] || skip "ldiskfs only"
5497
5498         $LFS mkdir -i0 $DIR/$tdir
5499         $LFS mkdir -i 1 $DIR/$tdir/sub1 $DIR/$tdir/sub2 $DIR/$tdir/sub3
5500
5501         for d in sub1 sub2 sub3; do
5502                 #define OBD_FAIL_OSD_REF_DEL    0x19c
5503                 do_facet mds1 $LCTL set_param fail_loc=0x8000019c
5504                 rm -rf $DIR/$tdir/$d && error "rm $d should fail"
5505         done
5506
5507         rm -d --interactive=never $DIR/$tdir || error "rm $tdir fail"
5508 }
5509 run_test 48f "non-zero nlink dir unlink won't LBUG()"
5510
5511 test_49() { # LU-1030
5512         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5513         remote_ost_nodsh && skip "remote OST with nodsh"
5514
5515         # get ost1 size - $FSNAME-OST0000
5516         ost1_size=$(do_facet ost1 $LFS df | grep ${ost1_svc} |
5517                 awk '{ print $4 }')
5518         # write 800M at maximum
5519         [[ $ost1_size -lt 2 ]] && ost1_size=2
5520         [[ $ost1_size -gt 819200 ]] && ost1_size=819200
5521
5522         $LFS setstripe -c 1 -i 0 $DIR/$tfile
5523         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((ost1_size >> 2)) &
5524         local dd_pid=$!
5525
5526         # change max_pages_per_rpc while writing the file
5527         local osc1_mppc=osc.$(get_osc_import_name client ost1).max_pages_per_rpc
5528         local orig_mppc=$($LCTL get_param -n $osc1_mppc)
5529         # loop until dd process exits
5530         while ps ax -opid | grep -wq $dd_pid; do
5531                 $LCTL set_param $osc1_mppc=$((RANDOM % 256 + 1))
5532                 sleep $((RANDOM % 5 + 1))
5533         done
5534         # restore original max_pages_per_rpc
5535         $LCTL set_param $osc1_mppc=$orig_mppc
5536         rm $DIR/$tfile || error "rm $DIR/$tfile failed"
5537 }
5538 run_test 49 "Change max_pages_per_rpc won't break osc extent"
5539
5540 test_50() {
5541         # bug 1485
5542         test_mkdir $DIR/$tdir
5543         cd $DIR/$tdir
5544         ls /proc/$$/cwd || error "ls /proc/$$/cwd failed"
5545 }
5546 run_test 50 "special situations: /proc symlinks  ==============="
5547
5548 test_51a() {    # was test_51
5549         # bug 1516 - create an empty entry right after ".." then split dir
5550         test_mkdir -c1 $DIR/$tdir
5551         touch $DIR/$tdir/foo
5552         $MCREATE $DIR/$tdir/bar
5553         rm $DIR/$tdir/foo
5554         createmany -m $DIR/$tdir/longfile 201
5555         FNUM=202
5556         while [[ $(ls -sd $DIR/$tdir | awk '{ print $1 }') -eq 4 ]]; do
5557                 $MCREATE $DIR/$tdir/longfile$FNUM
5558                 FNUM=$(($FNUM + 1))
5559                 echo -n "+"
5560         done
5561         echo
5562         ls -l $DIR/$tdir > /dev/null || error "ls -l $DIR/$tdir failed"
5563 }
5564 run_test 51a "special situations: split htree with empty entry =="
5565
5566 cleanup_print_lfs_df () {
5567         trap 0
5568         $LFS df
5569         $LFS df -i
5570 }
5571
5572 test_51b() {
5573         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5574
5575         local dir=$DIR/$tdir
5576         local nrdirs=$((65536 + 100))
5577
5578         # cleanup the directory
5579         rm -fr $dir
5580
5581         mkdir_on_mdt -i $((RANDOM % MDSCOUNT)) $dir
5582
5583         $LFS df
5584         $LFS df -i
5585         local mdtidx=$(printf "%04x" $($LFS getstripe -m $dir))
5586         local numfree=$(lctl get_param -n mdc.$FSNAME-MDT$mdtidx*.filesfree)
5587         [[ $numfree -lt $nrdirs ]] &&
5588                 skip "not enough free inodes ($numfree) on MDT$mdtidx"
5589
5590         # need to check free space for the directories as well
5591         local blkfree=$(lctl get_param -n mdc.$FSNAME-MDT$mdtidx*.kbytesavail)
5592         numfree=$(( blkfree / $(fs_inode_ksize) ))
5593         [[ $numfree -lt $nrdirs ]] && skip "not enough blocks ($numfree)"
5594
5595         trap cleanup_print_lfs_df EXIT
5596
5597         # create files
5598         createmany -d $dir/d $nrdirs || {
5599                 unlinkmany $dir/d $nrdirs
5600                 error "failed to create $nrdirs subdirs in MDT$mdtidx:$dir"
5601         }
5602
5603         # really created :
5604         nrdirs=$(ls -U $dir | wc -l)
5605
5606         # unlink all but 100 subdirectories, then check it still works
5607         local left=100
5608         local delete=$((nrdirs - left))
5609
5610         $LFS df
5611         $LFS df -i
5612
5613         # for ldiskfs the nlink count should be 1, but this is OSD specific
5614         # and so this is listed for informational purposes only
5615         echo "nlink before: $(stat -c %h $dir), created before: $nrdirs"
5616         unlinkmany -d $dir/d $delete ||
5617                 error "unlink of first $delete subdirs failed"
5618
5619         echo "nlink between: $(stat -c %h $dir)"
5620         local found=$(ls -U $dir | wc -l)
5621         [ $found -ne $left ] &&
5622                 error "can't find subdirs: found only $found, expected $left"
5623
5624         unlinkmany -d $dir/d $delete $left ||
5625                 error "unlink of second $left subdirs failed"
5626         # regardless of whether the backing filesystem tracks nlink accurately
5627         # or not, the nlink count shouldn't be more than "." and ".." here
5628         local after=$(stat -c %h $dir)
5629         [[ $after -gt 2 ]] && error "nlink after: $after > 2" ||
5630                 echo "nlink after: $after"
5631
5632         cleanup_print_lfs_df
5633 }
5634 run_test 51b "exceed 64k subdirectory nlink limit on create, verify unlink"
5635
5636 test_51d() {
5637         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5638         [[ $OSTCOUNT -lt 3 ]] && skip_env "needs >= 3 OSTs"
5639         local qos_old
5640
5641         test_mkdir $DIR/$tdir
5642         $LFS setstripe -c $OSTCOUNT $DIR/$tdir
5643
5644         qos_old=$(do_facet mds1 \
5645                 "$LCTL get_param -n lod.$FSNAME-*.qos_threshold_rr" | head -n 1)
5646         do_nodes $(comma_list $(mdts_nodes)) \
5647                 "$LCTL set_param lod.$FSNAME-*.qos_threshold_rr=100"
5648         stack_trap "do_nodes $(comma_list $(mdts_nodes)) \
5649                 '$LCTL set_param lod.$FSNAME-*.qos_threshold_rr=${qos_old%%%}'"
5650
5651         createmany -o $DIR/$tdir/t- 1000
5652         $LFS getstripe $DIR/$tdir > $TMP/$tfile
5653         for ((n = 0; n < $OSTCOUNT; n++)); do
5654                 objs[$n]=$(awk -vobjs=0 '($1 == '$n') { objs += 1 } \
5655                            END { printf("%0.0f", objs) }' $TMP/$tfile)
5656                 objs0[$n]=$(grep -A 1 idx $TMP/$tfile | awk -vobjs=0 \
5657                             '($1 == '$n') { objs += 1 } \
5658                             END { printf("%0.0f", objs) }')
5659                 log "OST$n has ${objs[$n]} objects, ${objs0[$n]} are index 0"
5660         done
5661         unlinkmany $DIR/$tdir/t- 1000
5662
5663         nlast=0
5664         for ((n = 0; n < $OSTCOUNT; n++)); do
5665                 (( ${objs[$n]} > ${objs[$nlast]} * 4 / 5 )) ||
5666                         { $LFS df && $LFS df -i &&
5667                         error "OST $n has fewer objects vs. OST $nlast" \
5668                               " (${objs[$n]} < ${objs[$nlast]}"; }
5669                 (( ${objs[$n]} < ${objs[$nlast]} * 5 / 4 )) ||
5670                         { $LFS df && $LFS df -i &&
5671                         error "OST $n has fewer objects vs. OST $nlast" \
5672                               " (${objs[$n]} < ${objs[$nlast]}"; }
5673
5674                 (( ${objs0[$n]} > ${objs0[$nlast]} * 4 / 5 )) ||
5675                         { $LFS df && $LFS df -i &&
5676                         error "OST $n has fewer #0 objects vs. OST $nlast" \
5677                               " (${objs0[$n]} < ${objs0[$nlast]}"; }
5678                 (( ${objs0[$n]} < ${objs0[$nlast]} * 5 / 4 )) ||
5679                         { $LFS df && $LFS df -i &&
5680                         error "OST $n has fewer #0 objects vs. OST $nlast" \
5681                               " (${objs0[$n]} < ${objs0[$nlast]}"; }
5682                 nlast=$n
5683         done
5684 }
5685 run_test 51d "check object distribution"
5686
5687 test_51e() {
5688         if [ "$mds1_FSTYPE" != ldiskfs ]; then
5689                 skip_env "ldiskfs only test"
5690         fi
5691
5692         test_mkdir -c1 $DIR/$tdir
5693         test_mkdir -c1 $DIR/$tdir/d0
5694
5695         touch $DIR/$tdir/d0/foo
5696         createmany -l $DIR/$tdir/d0/foo $DIR/$tdir/d0/f- 65001 &&
5697                 error "file exceed 65000 nlink limit!"
5698         unlinkmany $DIR/$tdir/d0/f- 65001
5699         return 0
5700 }
5701 run_test 51e "check file nlink limit"
5702
5703 test_51f() {
5704         test_mkdir $DIR/$tdir
5705
5706         local max=100000
5707         local ulimit_old=$(ulimit -n)
5708         local spare=20 # number of spare fd's for scripts/libraries, etc.
5709         local mdt=$($LFS getstripe -m $DIR/$tdir)
5710         local numfree=$($LFS df -i $DIR/$tdir | awk '/MDT:'$mdt'/ { print $4 }')
5711
5712         echo "MDT$mdt numfree=$numfree, max=$max"
5713         [[ $numfree -gt $max ]] && numfree=$max || numfree=$((numfree * 7 / 8))
5714         if [ $((numfree + spare)) -gt $ulimit_old ]; then
5715                 while ! ulimit -n $((numfree + spare)); do
5716                         numfree=$((numfree * 3 / 4))
5717                 done
5718                 echo "changed ulimit from $ulimit_old to $((numfree + spare))"
5719         else
5720                 echo "left ulimit at $ulimit_old"
5721         fi
5722
5723         createmany -o -k -t 120 $DIR/$tdir/f $numfree || {
5724                 unlinkmany $DIR/$tdir/f $numfree
5725                 error "create+open $numfree files in $DIR/$tdir failed"
5726         }
5727         ulimit -n $ulimit_old
5728
5729         # if createmany exits at 120s there will be fewer than $numfree files
5730         unlinkmany $DIR/$tdir/f $numfree || true
5731 }
5732 run_test 51f "check many open files limit"
5733
5734 test_52a() {
5735         [ -f $DIR/$tdir/foo ] && chattr -a $DIR/$tdir/foo
5736         test_mkdir $DIR/$tdir
5737         touch $DIR/$tdir/foo
5738         chattr +a $DIR/$tdir/foo || error "chattr +a failed"
5739         echo bar >> $DIR/$tdir/foo || error "append bar failed"
5740         cp /etc/hosts $DIR/$tdir/foo && error "cp worked"
5741         rm -f $DIR/$tdir/foo 2>/dev/null && error "rm worked"
5742         link $DIR/$tdir/foo $DIR/$tdir/foo_link 2>/dev/null &&
5743                                         error "link worked"
5744         echo foo >> $DIR/$tdir/foo || error "append foo failed"
5745         mrename $DIR/$tdir/foo $DIR/$tdir/foo_ren && error "rename worked"
5746         lsattr $DIR/$tdir/foo | egrep -q "^-+a[-e]+ $DIR/$tdir/foo" ||
5747                                                      error "lsattr"
5748         chattr -a $DIR/$tdir/foo || error "chattr -a failed"
5749         cp -r $DIR/$tdir $TMP/
5750         rm -fr $DIR/$tdir $TMP/$tdir || error "cleanup rm failed"
5751 }
5752 run_test 52a "append-only flag test (should return errors)"
5753
5754 test_52b() {
5755         [ -f $DIR/$tdir/foo ] && chattr -i $DIR/$tdir/foo
5756         test_mkdir $DIR/$tdir
5757         touch $DIR/$tdir/foo
5758         chattr +i $DIR/$tdir/foo || error "chattr +i failed"
5759         cat test > $DIR/$tdir/foo && error "cat test worked"
5760         cp /etc/hosts $DIR/$tdir/foo && error "cp worked"
5761         rm -f $DIR/$tdir/foo 2>/dev/null && error "rm worked"
5762         link $DIR/$tdir/foo $DIR/$tdir/foo_link 2>/dev/null &&
5763                                         error "link worked"
5764         echo foo >> $DIR/$tdir/foo && error "echo worked"
5765         mrename $DIR/$tdir/foo $DIR/$tdir/foo_ren && error "rename worked"
5766         [ -f $DIR/$tdir/foo ] || error "$tdir/foo is not a file"
5767         [ -f $DIR/$tdir/foo_ren ] && error "$tdir/foo_ren is not a file"
5768         lsattr $DIR/$tdir/foo | egrep -q "^-+i[-e]+ $DIR/$tdir/foo" ||
5769                                                         error "lsattr"
5770         chattr -i $DIR/$tdir/foo || error "chattr failed"
5771
5772         rm -fr $DIR/$tdir || error "unable to remove $DIR/$tdir"
5773 }
5774 run_test 52b "immutable flag test (should return errors) ======="
5775
5776 test_53() {
5777         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5778         remote_mds_nodsh && skip "remote MDS with nodsh"
5779         remote_ost_nodsh && skip "remote OST with nodsh"
5780
5781         local param
5782         local param_seq
5783         local ostname
5784         local mds_last
5785         local mds_last_seq
5786         local ost_last
5787         local ost_last_seq
5788         local ost_last_id
5789         local ostnum
5790         local node
5791         local found=false
5792         local support_last_seq=true
5793
5794         [[ $MDS1_VERSION -ge $(version_code 2.3.60) ]] ||
5795                 support_last_seq=false
5796
5797         # only test MDT0000
5798         local mdtosc=$(get_mdtosc_proc_path $SINGLEMDS)
5799         local value
5800         for value in $(do_facet $SINGLEMDS \
5801                        $LCTL get_param osp.$mdtosc.prealloc_last_id) ; do
5802                 param=$(echo ${value[0]} | cut -d "=" -f1)
5803                 ostname=$(echo $param | cut -d "." -f2 | cut -d - -f 1-2)
5804
5805                 if $support_last_seq; then
5806                         param_seq=$(echo $param |
5807                                 sed -e s/prealloc_last_id/prealloc_last_seq/g)
5808                         mds_last_seq=$(do_facet $SINGLEMDS \
5809                                        $LCTL get_param -n $param_seq)
5810                 fi
5811                 mds_last=$(do_facet $SINGLEMDS $LCTL get_param -n $param)
5812
5813                 ostnum=$(index_from_ostuuid ${ostname}_UUID)
5814                 node=$(facet_active_host ost$((ostnum+1)))
5815                 param="obdfilter.$ostname.last_id"
5816                 for ost_last in $(do_node $node $LCTL get_param -n $param) ; do
5817                         echo "$ostname.last_id=$ost_last; MDS.last_id=$mds_last"
5818                         ost_last_id=$ost_last
5819
5820                         if $support_last_seq; then
5821                                 ost_last_id=$(echo $ost_last |
5822                                               awk -F':' '{print $2}' |
5823                                               sed -e "s/^0x//g")
5824                                 ost_last_seq=$(echo $ost_last |
5825                                                awk -F':' '{print $1}')
5826                                 [[ $ost_last_seq = $mds_last_seq ]] || continue
5827                         fi
5828
5829                         if [[ $ost_last_id != $mds_last ]]; then
5830                                 error "$ost_last_id != $mds_last"
5831                         else
5832                                 found=true
5833                                 break
5834                         fi
5835                 done
5836         done
5837         $found || error "can not match last_seq/last_id for $mdtosc"
5838         return 0
5839 }
5840 run_test 53 "verify that MDS and OSTs agree on pre-creation ===="
5841
5842 test_54a() {
5843         perl -MSocket -e ';' || skip "no Socket perl module installed"
5844
5845         $SOCKETSERVER $DIR/socket ||
5846                 error "$SOCKETSERVER $DIR/socket failed: $?"
5847         $SOCKETCLIENT $DIR/socket ||
5848                 error "$SOCKETCLIENT $DIR/socket failed: $?"
5849         $MUNLINK $DIR/socket || error "$MUNLINK $DIR/socket failed: $?"
5850 }
5851 run_test 54a "unix domain socket test =========================="
5852
5853 test_54b() {
5854         f="$DIR/f54b"
5855         mknod $f c 1 3
5856         chmod 0666 $f
5857         dd if=/dev/zero of=$f bs=$PAGE_SIZE count=1
5858 }
5859 run_test 54b "char device works in lustre ======================"
5860
5861 find_loop_dev() {
5862         [ -b /dev/loop/0 ] && LOOPBASE=/dev/loop/
5863         [ -b /dev/loop0 ] && LOOPBASE=/dev/loop
5864         [ -z "$LOOPBASE" ] && echo "/dev/loop/0 and /dev/loop0 gone?" && return
5865
5866         for i in $(seq 3 7); do
5867                 losetup $LOOPBASE$i > /dev/null 2>&1 && continue
5868                 LOOPDEV=$LOOPBASE$i
5869                 LOOPNUM=$i
5870                 break
5871         done
5872 }
5873
5874 cleanup_54c() {
5875         local rc=0
5876         loopdev="$DIR/loop54c"
5877
5878         trap 0
5879         $UMOUNT $DIR/$tdir || rc=$?
5880         losetup -d $loopdev || true
5881         losetup -d $LOOPDEV || true
5882         rm -rf $loopdev $DIR/$tfile $DIR/$tdir
5883         return $rc
5884 }
5885
5886 test_54c() {
5887         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5888
5889         loopdev="$DIR/loop54c"
5890
5891         find_loop_dev
5892         [ -z "$LOOPNUM" ] && skip_env "couldn't find empty loop device"
5893         trap cleanup_54c EXIT
5894         mknod $loopdev b 7 $LOOPNUM
5895         echo "make a loop file system with $DIR/$tfile on $loopdev ($LOOPNUM)."
5896         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE seek=1024 count=1 > /dev/null
5897         losetup $loopdev $DIR/$tfile ||
5898                 error "can't set up $loopdev for $DIR/$tfile"
5899         mkfs.ext2 $loopdev || error "mke2fs on $loopdev"
5900         test_mkdir $DIR/$tdir
5901         mount -t ext2 $loopdev $DIR/$tdir ||
5902                 error "error mounting $loopdev on $DIR/$tdir"
5903         dd if=/dev/zero of=$DIR/$tdir/tmp bs=$PAGE_SIZE count=30 ||
5904                 error "dd write"
5905         df $DIR/$tdir
5906         dd if=$DIR/$tdir/tmp of=/dev/zero bs=$PAGE_SIZE count=30 ||
5907                 error "dd read"
5908         cleanup_54c
5909 }
5910 run_test 54c "block device works in lustre ====================="
5911
5912 test_54d() {
5913         f="$DIR/f54d"
5914         string="aaaaaa"
5915         mknod $f p
5916         [ "$string" = $(echo $string > $f | cat $f) ] || error "$f != $string"
5917 }
5918 run_test 54d "fifo device works in lustre ======================"
5919
5920 test_54e() {
5921         f="$DIR/f54e"
5922         string="aaaaaa"
5923         cp -aL /dev/console $f
5924         echo $string > $f || error "echo $string to $f failed"
5925 }
5926 run_test 54e "console/tty device works in lustre ======================"
5927
5928 test_56a() {
5929         local numfiles=3
5930         local numdirs=2
5931         local dir=$DIR/$tdir
5932
5933         rm -rf $dir
5934         test_mkdir -p $dir/dir
5935         for i in $(seq $numfiles); do
5936                 touch $dir/file$i
5937                 touch $dir/dir/file$i
5938         done
5939
5940         local numcomp=$($LFS getstripe --component-count $dir)
5941
5942         [[ $numcomp == 0 ]] && numcomp=1
5943
5944         # test lfs getstripe with --recursive
5945         local filenum=$($LFS getstripe -r $dir | egrep -c "obdidx|l_ost_idx")
5946
5947         [[ $filenum -eq $((numfiles * 2)) ]] ||
5948                 error "$LFS getstripe -r: found $filenum != $((numfiles * 2))"
5949         filenum=$($LFS getstripe $dir | egrep -c "obdidx|l_ost_idx")
5950         [[ $filenum -eq $numfiles ]] ||
5951                 error "$LFS getstripe $dir: found $filenum, not $numfiles"
5952         echo "$LFS getstripe showed obdidx or l_ost_idx"
5953
5954         # test lfs getstripe with file instead of dir
5955         filenum=$($LFS getstripe $dir/file1 | egrep -c "obdidx|l_ost_idx")
5956         [[ $filenum -eq 1 ]] ||
5957                 error "$LFS getstripe $dir/file1: found $filenum, not 1"
5958         echo "$LFS getstripe file1 passed"
5959
5960         #test lfs getstripe with --verbose
5961         filenum=$($LFS getstripe --verbose $dir | grep -c lmm_magic)
5962         [[ $filenum -eq $((numfiles * numcomp)) ]] ||
5963                 error "$LFS getstripe --verbose $dir: "\
5964                       "got $filenum want $((numfiles * numcomp)) lmm_magic"
5965         [[ $($LFS getstripe $dir | grep -c lmm_magic) -eq 0 ]] ||
5966                 error "$LFS getstripe $dir: showed lmm_magic"
5967
5968         #test lfs getstripe with -v prints lmm_fid
5969         filenum=$($LFS getstripe -v $dir | grep -c lmm_fid)
5970         local countfids=$((numdirs + numfiles * numcomp))
5971         [[ $filenum -eq $countfids ]] ||
5972                 error "$LFS getstripe -v $dir: "\
5973                       "got $filenum want $countfids lmm_fid"
5974         [[ $($LFS getstripe $dir | grep -c lmm_fid) -eq 0 ]] ||
5975                 error "$LFS getstripe $dir: showed lmm_fid by default"
5976         echo "$LFS getstripe --verbose passed"
5977
5978         #check for FID information
5979         local fid1=$($LFS getstripe --fid $dir/file1)
5980         local fid2=$($LFS getstripe --verbose $dir/file1 |
5981                      awk '/lmm_fid: / { print $2; exit; }')
5982         local fid3=$($LFS path2fid $dir/file1)
5983
5984         [ "$fid1" != "$fid2" ] &&
5985                 error "getstripe --fid '$fid1' != getstripe --verbose '$fid2'"
5986         [ "$fid1" != "$fid3" ] &&
5987                 error "getstripe --fid '$fid1' != lfs path2fid '$fid3'"
5988         echo "$LFS getstripe --fid passed"
5989
5990         #test lfs getstripe with --obd
5991         $LFS getstripe --obd wrong_uuid $dir 2>&1 | grep -q "unknown obduuid" ||
5992                 error "$LFS getstripe --obd wrong_uuid: should return error"
5993
5994         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
5995
5996         local ostidx=1
5997         local obduuid=$(ostuuid_from_index $ostidx)
5998         local found=$($LFS getstripe -r --obd $obduuid $dir |
5999                 grep 'lmm_stripe_offset:' | grep -c " $ostidx\$")
6000
6001         filenum=$($LFS getstripe -ir $dir | grep -c "^$ostidx\$")
6002         [[ $($LFS getstripe -id $dir) -ne $ostidx ]] ||
6003                 ((filenum--))
6004         [[ $($LFS getstripe -id $dir/dir) -ne $ostidx ]] ||
6005                 ((filenum--))
6006
6007         [[ $found -eq $filenum ]] ||
6008                 error "$LFS getstripe --obd: found $found expect $filenum"
6009         [[ $($LFS getstripe -r -v --obd $obduuid $dir |
6010                 sed '/^[         ]*'${ostidx}'[  ]/d' |
6011                 sed -n '/^[      ]*[0-9][0-9]*[  ]/p' | wc -l) -eq 0 ]] ||
6012                 error "$LFS getstripe --obd: should not show file on other obd"
6013         echo "$LFS getstripe --obd passed"
6014 }
6015 run_test 56a "check $LFS getstripe"
6016
6017 test_56b() {
6018         local dir=$DIR/$tdir
6019         local numdirs=3
6020
6021         test_mkdir $dir
6022         for i in $(seq $numdirs); do
6023                 test_mkdir $dir/dir$i
6024         done
6025
6026         # test lfs getdirstripe default mode is non-recursion, which is
6027         # different from lfs getstripe
6028         local dircnt=$($LFS getdirstripe $dir | grep -c lmv_stripe_count)
6029
6030         [[ $dircnt -eq 1 ]] ||
6031                 error "$LFS getdirstripe: found $dircnt, not 1"
6032         dircnt=$($LFS getdirstripe --recursive $dir |
6033                 grep -c lmv_stripe_count)
6034         [[ $dircnt -eq $((numdirs + 1)) ]] ||
6035                 error "$LFS getdirstripe -r: $dircnt, != $((numdirs + 1))"
6036 }
6037 run_test 56b "check $LFS getdirstripe"
6038
6039 test_56c() {
6040         remote_ost_nodsh && skip "remote OST with nodsh"
6041
6042         local ost_idx=0
6043         local ost_name=$(ostname_from_index $ost_idx)
6044         local old_status=$(ost_dev_status $ost_idx)
6045         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
6046
6047         [[ -z "$old_status" ]] ||
6048                 skip_env "OST $ost_name is in $old_status status"
6049
6050         do_facet ost1 $LCTL set_param -n obdfilter.$ost_name.degraded=1
6051         [[ $OST1_VERSION -lt $(version_code 2.12.55) ]] || do_facet ost1 \
6052                 $LCTL set_param -n obdfilter.$ost_name.no_precreate=1
6053         if [[ $OST1_VERSION -ge $(version_code 2.12.57) ]]; then
6054                 save_lustre_params ost1 osd-*.$ost_name.nonrotational > $p
6055                 do_facet ost1 $LCTL set_param -n osd-*.$ost_name.nonrotational=1
6056         fi
6057
6058         [[ $($LFS df -v $MOUNT |& grep -c "inactive device") -eq 0 ]] ||
6059                 error "$LFS df -v showing inactive devices"
6060         sleep_maxage
6061
6062         local new_status=$(ost_dev_status $ost_idx $MOUNT -v)
6063
6064         [[ "$new_status" =~ "D" ]] ||
6065                 error "$ost_name status is '$new_status', missing 'D'"
6066         if [[ $OST1_VERSION -ge $(version_code 2.12.55) ]]; then
6067                 [[ "$new_status" =~ "N" ]] ||
6068                         error "$ost_name status is '$new_status', missing 'N'"
6069         fi
6070         if [[ $OST1_VERSION -ge $(version_code 2.12.57) ]]; then
6071                 [[ "$new_status" =~ "f" ]] ||
6072                         error "$ost_name status is '$new_status', missing 'f'"
6073         fi
6074
6075         do_facet ost1 $LCTL set_param -n obdfilter.$ost_name.degraded=0
6076         [[ $OST1_VERSION -lt $(version_code 2.12.55) ]] || do_facet ost1 \
6077                 $LCTL set_param -n obdfilter.$ost_name.no_precreate=0
6078         [[ -z "$p" ]] && restore_lustre_params < $p || true
6079         sleep_maxage
6080
6081         new_status=$(ost_dev_status $ost_idx)
6082         [[ ! "$new_status" =~ "D" && ! "$new_status" =~ "N" ]] ||
6083                 error "$ost_name status is '$new_status', has 'D' and/or 'N'"
6084         # can't check 'f' as devices may actually be on flash
6085 }
6086 run_test 56c "check 'lfs df' showing device status"
6087
6088 test_56d() {
6089         local mdts=$($LFS df -v $MOUNT | grep -c MDT)
6090         local osts=$($LFS df -v $MOUNT | grep -c OST)
6091
6092         $LFS df $MOUNT
6093
6094         (( mdts == MDSCOUNT )) ||
6095                 error "lfs df -v showed $mdts MDTs, not $MDSCOUNT"
6096         (( osts == OSTCOUNT )) ||
6097                 error "lfs df -v showed $osts OSTs, not $OSTCOUNT"
6098 }
6099 run_test 56d "'lfs df -v' prints only configured devices"
6100
6101 test_56e() {
6102         err_enoent=2 # No such file or directory
6103         err_eopnotsupp=95 # Operation not supported
6104
6105         enoent_mnt=/pmt1 # Invalid dentry. Path not present
6106         notsup_mnt=/tmp  # Valid dentry, but Not a lustreFS
6107
6108         # Check for handling of path not exists
6109         output=$($LFS df $enoent_mnt 2>&1)
6110         ret=$?
6111
6112         fs=$(echo $output | awk -F: '{print $2}' | awk '{print $3}' | tr -d \')
6113         [[ $fs = $enoent_mnt && $ret -eq $err_enoent ]] ||
6114                 error "expect failure $err_enoent, not $ret"
6115
6116         # Check for handling of non-Lustre FS
6117         output=$($LFS df $notsup_mnt)
6118         ret=$?
6119
6120         fs=$(echo $output | awk '{print $1}' | awk -F: '{print $2}')
6121         [[ $fs = $notsup_mnt && $ret -eq $err_eopnotsupp ]] ||
6122                 error "expect success $err_eopnotsupp, not $ret"
6123
6124         # Check for multiple LustreFS argument
6125         output=$($LFS df $MOUNT $MOUNT $MOUNT | grep -c "filesystem_summary:")
6126         ret=$?
6127
6128         [[ $output -eq 3 && $ret -eq 0 ]] ||
6129                 error "expect success 3, not $output, rc = $ret"
6130
6131         # Check for correct non-Lustre FS handling among multiple
6132         # LustreFS argument
6133         output=$($LFS df $MOUNT $notsup_mnt $MOUNT |
6134                 grep -c "filesystem_summary:"; exit ${PIPESTATUS[0]})
6135         ret=$?
6136
6137         [[ $output -eq 2 && $ret -eq $err_eopnotsupp ]] ||
6138                 error "expect success 2, not $output, rc = $ret"
6139 }
6140 run_test 56e "'lfs df' Handle non LustreFS & multiple LustreFS"
6141
6142 NUMFILES=3
6143 NUMDIRS=3
6144 setup_56() {
6145         local local_tdir="$1"
6146         local local_numfiles="$2"
6147         local local_numdirs="$3"
6148         local dir_params="$4"
6149         local dir_stripe_params="$5"
6150
6151         if [ ! -d "$local_tdir" ] ; then
6152                 test_mkdir -p $dir_stripe_params $local_tdir
6153                 [ "$dir_params" ] && $LFS setstripe $dir_params $local_tdir
6154                 for i in $(seq $local_numfiles) ; do
6155                         touch $local_tdir/file$i
6156                 done
6157                 for i in $(seq $local_numdirs) ; do
6158                         test_mkdir $dir_stripe_params $local_tdir/dir$i
6159                         for j in $(seq $local_numfiles) ; do
6160                                 touch $local_tdir/dir$i/file$j
6161                         done
6162                 done
6163         fi
6164 }
6165
6166 setup_56_special() {
6167         local local_tdir=$1
6168         local local_numfiles=$2
6169         local local_numdirs=$3
6170
6171         setup_56 $local_tdir $local_numfiles $local_numdirs
6172
6173         if [ ! -e "$local_tdir/loop${local_numfiles}b" ] ; then
6174                 for i in $(seq $local_numfiles) ; do
6175                         mknod $local_tdir/loop${i}b b 7 $i
6176                         mknod $local_tdir/null${i}c c 1 3
6177                         ln -s $local_tdir/file1 $local_tdir/link${i}
6178                 done
6179                 for i in $(seq $local_numdirs) ; do
6180                         mknod $local_tdir/dir$i/loop${i}b b 7 $i
6181                         mknod $local_tdir/dir$i/null${i}c c 1 3
6182                         ln -s $local_tdir/dir$i/file1 $local_tdir/dir$i/link${i}
6183                 done
6184         fi
6185 }
6186
6187 test_56g() {
6188         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6189         local expected=$(($NUMDIRS + 2))
6190
6191         setup_56 $dir $NUMFILES $NUMDIRS
6192
6193         # test lfs find with -name
6194         for i in $(seq $NUMFILES) ; do
6195                 local nums=$($LFS find -name "*$i" $dir | wc -l)
6196
6197                 [ $nums -eq $expected ] ||
6198                         error "lfs find -name '*$i' $dir wrong: "\
6199                               "found $nums, expected $expected"
6200         done
6201 }
6202 run_test 56g "check lfs find -name"
6203
6204 test_56h() {
6205         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6206         local expected=$(((NUMDIRS + 1) * (NUMFILES - 1) + NUMFILES))
6207
6208         setup_56 $dir $NUMFILES $NUMDIRS
6209
6210         # test lfs find with ! -name
6211         for i in $(seq $NUMFILES) ; do
6212                 local nums=$($LFS find ! -name "*$i" $dir | wc -l)
6213
6214                 [ $nums -eq $expected ] ||
6215                         error "lfs find ! -name '*$i' $dir wrong: "\
6216                               "found $nums, expected $expected"
6217         done
6218 }
6219 run_test 56h "check lfs find ! -name"
6220
6221 test_56i() {
6222         local dir=$DIR/$tdir
6223
6224         test_mkdir $dir
6225
6226         local cmd="$LFS find -ost $(ostuuid_from_index 0 $dir) $dir"
6227         local out=$($cmd)
6228
6229         [ -z "$out" ] || error "'$cmd' returned directory '$out'"
6230 }
6231 run_test 56i "check 'lfs find -ost UUID' skips directories"
6232
6233 test_56j() {
6234         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6235
6236         setup_56_special $dir $NUMFILES $NUMDIRS
6237
6238         local expected=$((NUMDIRS + 1))
6239         local cmd="$LFS find -type d $dir"
6240         local nums=$($cmd | wc -l)
6241
6242         [ $nums -eq $expected ] ||
6243                 error "'$cmd' wrong: found $nums, expected $expected"
6244 }
6245 run_test 56j "check lfs find -type d"
6246
6247 test_56k() {
6248         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6249
6250         setup_56_special $dir $NUMFILES $NUMDIRS
6251
6252         local expected=$(((NUMDIRS + 1) * NUMFILES))
6253         local cmd="$LFS find -type f $dir"
6254         local nums=$($cmd | wc -l)
6255
6256         [ $nums -eq $expected ] ||
6257                 error "'$cmd' wrong: found $nums, expected $expected"
6258 }
6259 run_test 56k "check lfs find -type f"
6260
6261 test_56l() {
6262         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6263
6264         setup_56_special $dir $NUMFILES $NUMDIRS
6265
6266         local expected=$((NUMDIRS + NUMFILES))
6267         local cmd="$LFS find -type b $dir"
6268         local nums=$($cmd | wc -l)
6269
6270         [ $nums -eq $expected ] ||
6271                 error "'$cmd' wrong: found $nums, expected $expected"
6272 }
6273 run_test 56l "check lfs find -type b"
6274
6275 test_56m() {
6276         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6277
6278         setup_56_special $dir $NUMFILES $NUMDIRS
6279
6280         local expected=$((NUMDIRS + NUMFILES))
6281         local cmd="$LFS find -type c $dir"
6282         local nums=$($cmd | wc -l)
6283         [ $nums -eq $expected ] ||
6284                 error "'$cmd' wrong: found $nums, expected $expected"
6285 }
6286 run_test 56m "check lfs find -type c"
6287
6288 test_56n() {
6289         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6290         setup_56_special $dir $NUMFILES $NUMDIRS
6291
6292         local expected=$((NUMDIRS + NUMFILES))
6293         local cmd="$LFS find -type l $dir"
6294         local nums=$($cmd | wc -l)
6295
6296         [ $nums -eq $expected ] ||
6297                 error "'$cmd' wrong: found $nums, expected $expected"
6298 }
6299 run_test 56n "check lfs find -type l"
6300
6301 test_56o() {
6302         local dir=$DIR/$tdir
6303
6304         setup_56 $dir $NUMFILES $NUMDIRS
6305         utime $dir/file1 > /dev/null || error "utime (1)"
6306         utime $dir/file2 > /dev/null || error "utime (2)"
6307         utime $dir/dir1 > /dev/null || error "utime (3)"
6308         utime $dir/dir2 > /dev/null || error "utime (4)"
6309         utime $dir/dir1/file1 > /dev/null || error "utime (5)"
6310         dd if=/dev/zero count=1 >> $dir/dir1/file1 && sync
6311
6312         local expected=4
6313         local nums=$($LFS find -mtime +0 $dir | wc -l)
6314
6315         [ $nums -eq $expected ] ||
6316                 error "lfs find -mtime +0 $dir: found $nums expect $expected"
6317
6318         expected=12
6319         cmd="$LFS find -mtime 0 $dir"
6320         nums=$($cmd | wc -l)
6321         [ $nums -eq $expected ] ||
6322                 error "'$cmd' wrong: found $nums, expected $expected"
6323 }
6324 run_test 56o "check lfs find -mtime for old files"
6325
6326 test_56ob() {
6327         local dir=$DIR/$tdir
6328         local expected=1
6329         local count=0
6330
6331         # just to make sure there is something that won't be found
6332         test_mkdir $dir
6333         touch $dir/$tfile.now
6334
6335         for age in year week day hour min; do
6336                 count=$((count + 1))
6337
6338                 touch $dir/$tfile-a.$age $dir/$tfile-m.$age
6339                 touch --date="$count $age ago" -a $dir/$tfile-a.$age
6340                 touch --date="$count $age ago" -m $dir/$tfile-m.$age
6341
6342                 local cmd="$LFS find $dir -mtime $count${age:0:1}"
6343                 local nums=$($cmd | wc -l)
6344                 [ $nums -eq $expected ] ||
6345                         error "'$cmd' wrong: found $nums, expected $expected"
6346
6347                 cmd="$LFS find $dir -atime $count${age:0:1}"
6348                 nums=$($cmd | wc -l)
6349                 [ $nums -eq $expected ] ||
6350                         error "'$cmd' wrong: found $nums, expected $expected"
6351         done
6352
6353         sleep 2
6354         cmd="$LFS find $dir -ctime +1s -type f"
6355         nums=$($cmd | wc -l)
6356         (( $nums == $count * 2 + 1)) ||
6357                 error "'$cmd' wrong: found $nums, expected $((count * 2 + 1))"
6358 }
6359 run_test 56ob "check lfs find -atime -mtime -ctime with units"
6360
6361 test_newerXY_base() {
6362         local x=$1
6363         local y=$2
6364         local dir=$DIR/$tdir
6365         local ref
6366         local negref
6367
6368         if [ $y == "t" ]; then
6369                 if [ $x == "b" ]; then
6370                         ref=\"$(do_facet mds1 date +"%Y-%m-%d\ %H:%M:%S")\"
6371                 else
6372                         ref=\"$(date +"%Y-%m-%d %H:%M:%S")\"
6373                 fi
6374         else
6375                 ref=$DIR/$tfile.newer.$x$y
6376                 touch $ref || error "touch $ref failed"
6377         fi
6378
6379         echo "before = $ref"
6380         sleep 2
6381         setup_56 $dir $NUMFILES $NUMDIRS "-i0 -c1" "-i0 -c1"
6382         sleep 2
6383         if [ $y == "t" ]; then
6384                 if [ $x == "b" ]; then
6385                         negref=\"$(do_facet mds1 date +"%Y-%m-%d\ %H:%M:%S")\"
6386                 else
6387                         negref=\"$(date +"%Y-%m-%d %H:%M:%S")\"
6388                 fi
6389         else
6390                 negref=$DIR/$tfile.negnewer.$x$y
6391                 touch $negref || error "touch $negref failed"
6392         fi
6393
6394         echo "after = $negref"
6395         local cmd="$LFS find $dir -newer$x$y $ref"
6396         local nums=$(eval $cmd | wc -l)
6397         local expected=$(((NUMFILES + 2) * NUMDIRS + 1))
6398
6399         [ $nums -eq $expected ] || { ls -lauR --full-time $dir ;
6400                 error "'$cmd' wrong: found $nums newer, expected $expected"  ; }
6401
6402         cmd="$LFS find $dir ! -newer$x$y $negref"
6403         nums=$(eval $cmd | wc -l)
6404         [ $nums -eq $expected ] || { ls -lauR --full-time $dir ;
6405                 error "'$cmd' wrong: found $nums older, expected $expected"  ; }
6406
6407         cmd="$LFS find $dir -newer$x$y $ref ! -newer$x$y $negref"
6408         nums=$(eval $cmd | wc -l)
6409         [ $nums -eq $expected ] || { ls -lauR --full-time $dir ;
6410                 error "'$cmd' wrong: found $nums between, expected $expected"; }
6411
6412         rm -rf $DIR/*
6413 }
6414
6415 test_56oc() {
6416         test_newerXY_base "a" "a"
6417         test_newerXY_base "a" "m"
6418         test_newerXY_base "a" "c"
6419         test_newerXY_base "m" "a"
6420         test_newerXY_base "m" "m"
6421         test_newerXY_base "m" "c"
6422         test_newerXY_base "c" "a"
6423         test_newerXY_base "c" "m"
6424         test_newerXY_base "c" "c"
6425
6426         [[ -n "$sles_version" ]] &&
6427                 echo "skip timestamp tests on SLES, LU-13665" && return 0
6428
6429         test_newerXY_base "a" "t"
6430         test_newerXY_base "m" "t"
6431         test_newerXY_base "c" "t"
6432
6433         [[ $MDS1_VERSION -lt $(version_code 2.13.54) ||
6434            $CLIENT_VERSION -lt $(version_code 2.13.54) ]] &&
6435                 ! btime_supported && echo "btime unsupported" && return 0
6436
6437         test_newerXY_base "b" "b"
6438         test_newerXY_base "b" "t"
6439 }
6440 run_test 56oc "check lfs find -newerXY work"
6441
6442 btime_supported() {
6443         local dir=$DIR/$tdir
6444         local rc
6445
6446         mkdir -p $dir
6447         touch $dir/$tfile
6448         $LFS find $dir -btime -1d -type f
6449         rc=$?
6450         rm -rf $dir
6451         return $rc
6452 }
6453
6454 test_56od() {
6455         [ $MDS1_VERSION -lt $(version_code 2.13.53) ] &&
6456                 ! btime_supported && skip "btime unsupported on MDS"
6457
6458         [ $CLIENT_VERSION -lt $(version_code 2.13.53) ] &&
6459                 ! btime_supported && skip "btime unsupported on clients"
6460
6461         local dir=$DIR/$tdir
6462         local ref=$DIR/$tfile.ref
6463         local negref=$DIR/$tfile.negref
6464
6465         mkdir $dir || error "mkdir $dir failed"
6466         touch $dir/$tfile.n1 || error "touch $dir/$tfile.n1 failed"
6467         touch $dir/$tfile.n2 || error "touch $dir/$tfile.n2 failed"
6468         mkdir $dir/$tdir.n1 || error "mkdir $dir/$tdir.n1 failed"
6469         mkdir $dir/$tdir.n2 || error "mkdir $dir/$tdir.n2 failed"
6470         touch $ref || error "touch $ref failed"
6471         # sleep 3 seconds at least
6472         sleep 3
6473
6474         local before=$(do_facet mds1 date +%s)
6475         local skew=$(($(date +%s) - before + 1))
6476
6477         if (( skew < 0 && skew > -5 )); then
6478                 sleep $((0 - skew + 1))
6479                 skew=0
6480         fi
6481
6482         # Set the dir stripe params to limit files all on MDT0,
6483         # otherwise we need to calc the max clock skew between
6484         # the client and MDTs.
6485         setup_56 $dir/d.btime $NUMFILES $NUMDIRS "-i0 -c1" "-i0 -c1"
6486         sleep 2
6487         touch $negref || error "touch $negref failed"
6488
6489         local cmd="$LFS find $dir -newerbb $ref ! -newerbb $negref -type f"
6490         local nums=$($cmd | wc -l)
6491         local expected=$(((NUMFILES + 1) * NUMDIRS))
6492
6493         [ $nums -eq $expected ] ||
6494                 error "'$cmd' wrong: found $nums, expected $expected"
6495
6496         cmd="$LFS find $dir -newerbb $ref ! -newerbb $negref -type d"
6497         nums=$($cmd | wc -l)
6498         expected=$((NUMFILES + 1))
6499         [ $nums -eq $expected ] ||
6500                 error "'$cmd' wrong: found $nums, expected $expected"
6501
6502         [ $skew -lt 0 ] && return
6503
6504         local after=$(do_facet mds1 date +%s)
6505         local age=$((after - before + 1 + skew))
6506
6507         cmd="$LFS find $dir -btime -${age}s -type f"
6508         nums=$($cmd | wc -l)
6509         expected=$(((NUMFILES + 1) * NUMDIRS))
6510
6511         echo "Clock skew between client and server: $skew, age:$age"
6512         [ $nums -eq $expected ] ||
6513                 error "'$cmd' wrong: found $nums, expected $expected"
6514
6515         expected=$(($NUMDIRS + 1))
6516         cmd="$LFS find $dir -btime -${age}s -type d"
6517         nums=$($cmd | wc -l)
6518         [ $nums -eq $expected ] ||
6519                 error "'$cmd' wrong: found $nums, expected $expected"
6520         rm -f $ref $negref || error "Failed to remove $ref $negref"
6521 }
6522 run_test 56od "check lfs find -btime with units"
6523
6524 test_56p() {
6525         [ $RUNAS_ID -eq $UID ] &&
6526                 skip_env "RUNAS_ID = UID = $UID -- skipping"
6527
6528         local dir=$DIR/$tdir
6529
6530         setup_56 $dir $NUMFILES $NUMDIRS
6531         chown $RUNAS_ID $dir/file* || error "chown $DIR/${tdir}g/file$i failed"
6532
6533         local expected=$NUMFILES
6534         local cmd="$LFS find -uid $RUNAS_ID $dir"
6535         local nums=$($cmd | wc -l)
6536
6537         [ $nums -eq $expected ] ||
6538                 error "'$cmd' wrong: found $nums, expected $expected"
6539
6540         expected=$(((NUMFILES + 1) * NUMDIRS + 1))
6541         cmd="$LFS find ! -uid $RUNAS_ID $dir"
6542         nums=$($cmd | wc -l)
6543         [ $nums -eq $expected ] ||
6544                 error "'$cmd' wrong: found $nums, expected $expected"
6545 }
6546 run_test 56p "check lfs find -uid and ! -uid"
6547
6548 test_56q() {
6549         [ $RUNAS_ID -eq $UID ] &&
6550                 skip_env "RUNAS_ID = UID = $UID -- skipping"
6551
6552         local dir=$DIR/$tdir
6553
6554         setup_56 $dir $NUMFILES $NUMDIRS
6555         chgrp $RUNAS_GID $dir/file* || error "chown $dir/file$i failed"
6556
6557         local expected=$NUMFILES
6558         local cmd="$LFS find -gid $RUNAS_GID $dir"
6559         local nums=$($cmd | wc -l)
6560
6561         [ $nums -eq $expected ] ||
6562                 error "'$cmd' wrong: found $nums, expected $expected"
6563
6564         expected=$(( ($NUMFILES+1) * $NUMDIRS + 1))
6565         cmd="$LFS find ! -gid $RUNAS_GID $dir"
6566         nums=$($cmd | wc -l)
6567         [ $nums -eq $expected ] ||
6568                 error "'$cmd' wrong: found $nums, expected $expected"
6569 }
6570 run_test 56q "check lfs find -gid and ! -gid"
6571
6572 test_56r() {
6573         local dir=$DIR/$tdir
6574
6575         setup_56 $dir $NUMFILES $NUMDIRS
6576
6577         local expected=12
6578         local cmd="$LFS find -size 0 -type f -lazy $dir"
6579         local nums=$($cmd | wc -l)
6580
6581         [ $nums -eq $expected ] ||
6582                 error "'$cmd' wrong: found $nums, expected $expected"
6583         cmd="$LFS find -size 0 -type f $dir"
6584         nums=$($cmd | wc -l)
6585         [ $nums -eq $expected ] ||
6586                 error "'$cmd' wrong: found $nums, expected $expected"
6587
6588         expected=0
6589         cmd="$LFS find ! -size 0 -type f -lazy $dir"
6590         nums=$($cmd | wc -l)
6591         [ $nums -eq $expected ] ||
6592                 error "'$cmd' wrong: found $nums, expected $expected"
6593         cmd="$LFS find ! -size 0 -type f $dir"
6594         nums=$($cmd | wc -l)
6595         [ $nums -eq $expected ] ||
6596                 error "'$cmd' wrong: found $nums, expected $expected"
6597
6598         echo "test" > $dir/$tfile
6599         echo "test2" > $dir/$tfile.2 && sync
6600         expected=1
6601         cmd="$LFS find -size 5 -type f -lazy $dir"
6602         nums=$($cmd | wc -l)
6603         [ $nums -eq $expected ] ||
6604                 error "'$cmd' wrong: found $nums, expected $expected"
6605         cmd="$LFS find -size 5 -type f $dir"
6606         nums=$($cmd | wc -l)
6607         [ $nums -eq $expected ] ||
6608                 error "'$cmd' wrong: found $nums, expected $expected"
6609
6610         expected=1
6611         cmd="$LFS find -size +5 -type f -lazy $dir"
6612         nums=$($cmd | wc -l)
6613         [ $nums -eq $expected ] ||
6614                 error "'$cmd' wrong: found $nums, expected $expected"
6615         cmd="$LFS find -size +5 -type f $dir"
6616         nums=$($cmd | wc -l)
6617         [ $nums -eq $expected ] ||
6618                 error "'$cmd' wrong: found $nums, expected $expected"
6619
6620         expected=2
6621         cmd="$LFS find -size +0 -type f -lazy $dir"
6622         nums=$($cmd | wc -l)
6623         [ $nums -eq $expected ] ||
6624                 error "'$cmd' wrong: found $nums, expected $expected"
6625         cmd="$LFS find -size +0 -type f $dir"
6626         nums=$($cmd | wc -l)
6627         [ $nums -eq $expected ] ||
6628                 error "'$cmd' wrong: found $nums, expected $expected"
6629
6630         expected=2
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=12
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 run_test 56r "check lfs find -size works"
6651
6652 test_56ra_sub() {
6653         local expected=$1
6654         local glimpses=$2
6655         local cmd="$3"
6656
6657         cancel_lru_locks $OSC
6658
6659         local rpcs_before=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
6660         local nums=$($cmd | wc -l)
6661
6662         [ $nums -eq $expected ] ||
6663                 error "'$cmd' wrong: found $nums, expected $expected"
6664
6665         local rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
6666
6667         if (( rpcs_before + glimpses != rpcs_after )); then
6668                 echo "Before: $rpcs_before After: $rpcs_after $NUMFILES"
6669                 $LCTL get_param osc.*.stats | grep ldlm_glimpse_enqueue
6670
6671                 if [[ $glimpses == 0 ]]; then
6672                         error "'$cmd' should not send glimpse RPCs to OST"
6673                 else
6674                         error "'$cmd' should send $glimpses glimpse RPCs to OST"
6675                 fi
6676         fi
6677 }
6678
6679 test_56ra() {
6680         [[ $MDS1_VERSION -gt $(version_code 2.12.58) ]] ||
6681                 skip "MDS < 2.12.58 doesn't return LSOM data"
6682         local dir=$DIR/$tdir
6683         local old_agl=$($LCTL get_param -n llite.*.statahead_agl)
6684
6685         [[ $OSC == "mdc" ]] && skip "statahead not needed for DoM files"
6686
6687         # statahead_agl may cause extra glimpse which confuses results. LU-13017
6688         $LCTL set_param -n llite.*.statahead_agl=0
6689         stack_trap "$LCTL set_param -n llite.*.statahead_agl=$old_agl"
6690
6691         setup_56 $dir $NUMFILES $NUMDIRS "-c 1"
6692         # open and close all files to ensure LSOM is updated
6693         cancel_lru_locks $OSC
6694         find $dir -type f | xargs cat > /dev/null
6695
6696         #   expect_found  glimpse_rpcs  command_to_run
6697         test_56ra_sub 12  0 "$LFS find -size 0 -type f -lazy $dir"
6698         test_56ra_sub 12 12 "$LFS find -size 0 -type f $dir"
6699         test_56ra_sub  0  0 "$LFS find ! -size 0 -type f -lazy $dir"
6700         test_56ra_sub  0 12 "$LFS find ! -size 0 -type f $dir"
6701
6702         echo "test" > $dir/$tfile
6703         echo "test2" > $dir/$tfile.2 && sync
6704         cancel_lru_locks $OSC
6705         cat $dir/$tfile $dir/$tfile.2 > /dev/null
6706
6707         test_56ra_sub  1  0 "$LFS find -size 5 -type f -lazy $dir"
6708         test_56ra_sub  1 14 "$LFS find -size 5 -type f $dir"
6709         test_56ra_sub  1  0 "$LFS find -size +5 -type f -lazy $dir"
6710         test_56ra_sub  1 14 "$LFS find -size +5 -type f $dir"
6711
6712         test_56ra_sub  2  0 "$LFS find -size +0 -type f -lazy $dir"
6713         test_56ra_sub  2 14 "$LFS find -size +0 -type f $dir"
6714         test_56ra_sub  2  0 "$LFS find ! -size -5 -type f -lazy $dir"
6715         test_56ra_sub  2 14 "$LFS find ! -size -5 -type f $dir"
6716         test_56ra_sub 12  0 "$LFS find -size -5 -type f -lazy $dir"
6717         test_56ra_sub 12 14 "$LFS find -size -5 -type f $dir"
6718 }
6719 run_test 56ra "check lfs find -size -lazy works for data on OSTs"
6720
6721 test_56rb() {
6722         local dir=$DIR/$tdir
6723         local tmp=$TMP/$tfile.log
6724         local mdt_idx;
6725
6726         test_mkdir -p $dir || error "failed to mkdir $dir"
6727         $LFS setstripe -c 1 -i 0 $dir/$tfile ||
6728                 error "failed to setstripe $dir/$tfile"
6729         mdt_idx=$($LFS getdirstripe -i $dir)
6730         dd if=/dev/zero of=$dir/$tfile bs=1M count=1
6731
6732         stack_trap "rm -f $tmp" EXIT
6733         $LFS find --size +100K --ost 0 $dir |& tee $tmp
6734         ! grep -q obd_uuid $tmp ||
6735                 error "failed to find --size +100K --ost 0 $dir"
6736         $LFS find --size +100K --mdt $mdt_idx $dir |& tee $tmp
6737         ! grep -q obd_uuid $tmp ||
6738                 error "failed to find --size +100K --mdt $mdt_idx $dir"
6739 }
6740 run_test 56rb "check lfs find --size --ost/--mdt works"
6741
6742 test_56rc() {
6743         (( MDSCOUNT >= 2 )) || skip "needs at least 2 MDTs"
6744         local dir=$DIR/$tdir
6745         local found
6746
6747         test_mkdir -c 2 -H all_char $dir || error "failed to mkdir $dir"
6748         $LFS mkdir -c 2 --mdt-hash all_char $dir/$tdir-all{1..10}
6749         (( $MDSCOUNT > 2 )) &&
6750                 $LFS mkdir -c 3 --mdt-hash fnv_1a_64 $dir/$tdir-fnv{1..10}
6751         mkdir $dir/$tdir-{1..10}
6752         touch $dir/$tfile-{1..10}
6753
6754         found=$($LFS find $dir --mdt-count 2 | wc -l)
6755         expect=11
6756         (( $found == $expect )) || error "found $found 2-stripe, expect $expect"
6757
6758         found=$($LFS find $dir -T +1 | wc -l)
6759         (( $MDSCOUNT > 2 )) && expect=$((expect + 10))
6760         (( $found == $expect )) || error "found $found 2+stripe, expect $expect"
6761
6762         found=$($LFS find $dir --mdt-hash all_char | wc -l)
6763         expect=11
6764         (( $found == $expect )) || error "found $found all_char, expect $expect"
6765
6766         found=$($LFS find $dir --mdt-hash fnv_1a_64 | wc -l)
6767         (( $MDSCOUNT > 2 )) && expect=10 || expect=0
6768         (( $found == $expect )) || error "found $found all_char, expect $expect"
6769 }
6770 run_test 56rc "check lfs find --mdt-count/--mdt-hash works"
6771
6772 test_56s() { # LU-611 #LU-9369
6773         [[ $OSTCOUNT -lt 2 ]] && skip_env "need at least 2 OSTs"
6774
6775         local dir=$DIR/$tdir
6776         local onestripe=$(((NUMDIRS + 1) * NUMFILES))
6777
6778         setup_56 $dir $NUMFILES $NUMDIRS "-c 1"
6779         for i in $(seq $NUMDIRS); do
6780                 $LFS setstripe -c $((OSTCOUNT + 1)) $dir/dir$i/$tfile
6781         done
6782
6783         local expected=$NUMDIRS
6784         local cmd="$LFS find -c $OSTCOUNT $dir"
6785         local nums=$($cmd | wc -l)
6786
6787         [ $nums -eq $expected ] || {
6788                 $LFS getstripe -R $dir
6789                 error "'$cmd' wrong: found $nums, expected $expected"
6790         }
6791
6792         expected=$((NUMDIRS + onestripe))
6793         cmd="$LFS find -stripe-count +0 -type f $dir"
6794         nums=$($cmd | wc -l)
6795         [ $nums -eq $expected ] || {
6796                 $LFS getstripe -R $dir
6797                 error "'$cmd' wrong: found $nums, expected $expected"
6798         }
6799
6800         expected=$onestripe
6801         cmd="$LFS find -stripe-count 1 -type f $dir"
6802         nums=$($cmd | wc -l)
6803         [ $nums -eq $expected ] || {
6804                 $LFS getstripe -R $dir
6805                 error "'$cmd' wrong: found $nums, expected $expected"
6806         }
6807
6808         cmd="$LFS find -stripe-count -2 -type f $dir"
6809         nums=$($cmd | wc -l)
6810         [ $nums -eq $expected ] || {
6811                 $LFS getstripe -R $dir
6812                 error "'$cmd' wrong: found $nums, expected $expected"
6813         }
6814
6815         expected=0
6816         cmd="$LFS find -stripe-count $((OSTCOUNT + 1)) -type f $dir"
6817         nums=$($cmd | wc -l)
6818         [ $nums -eq $expected ] || {
6819                 $LFS getstripe -R $dir
6820                 error "'$cmd' wrong: found $nums, expected $expected"
6821         }
6822 }
6823 run_test 56s "check lfs find -stripe-count works"
6824
6825 test_56t() { # LU-611 #LU-9369
6826         local dir=$DIR/$tdir
6827
6828         setup_56 $dir 0 $NUMDIRS
6829         for i in $(seq $NUMDIRS); do
6830                 $LFS setstripe -S 8M $dir/dir$i/$tfile
6831         done
6832
6833         local expected=$NUMDIRS
6834         local cmd="$LFS find -S 8M $dir"
6835         local nums=$($cmd | wc -l)
6836
6837         [ $nums -eq $expected ] || {
6838                 $LFS getstripe -R $dir
6839                 error "'$cmd' wrong: found $nums, expected $expected"
6840         }
6841         rm -rf $dir
6842
6843         setup_56 $dir $NUMFILES $NUMDIRS "--stripe-size 512k"
6844
6845         $LFS setstripe -S 256k $dir/$tfile.{0,1,2,3}
6846
6847         expected=$(((NUMDIRS + 1) * NUMFILES))
6848         cmd="$LFS find -stripe-size 512k -type f $dir"
6849         nums=$($cmd | wc -l)
6850         [ $nums -eq $expected ] ||
6851                 error "'$cmd' wrong: found $nums, expected $expected"
6852
6853         cmd="$LFS find -stripe-size +320k -type f $dir"
6854         nums=$($cmd | wc -l)
6855         [ $nums -eq $expected ] ||
6856                 error "'$cmd' wrong: found $nums, expected $expected"
6857
6858         expected=$(((NUMDIRS + 1) * NUMFILES + 4))
6859         cmd="$LFS find -stripe-size +200k -type f $dir"
6860         nums=$($cmd | wc -l)
6861         [ $nums -eq $expected ] ||
6862                 error "'$cmd' wrong: found $nums, expected $expected"
6863
6864         cmd="$LFS find -stripe-size -640k -type f $dir"
6865         nums=$($cmd | wc -l)
6866         [ $nums -eq $expected ] ||
6867                 error "'$cmd' wrong: found $nums, expected $expected"
6868
6869         expected=4
6870         cmd="$LFS find -stripe-size 256k -type f $dir"
6871         nums=$($cmd | wc -l)
6872         [ $nums -eq $expected ] ||
6873                 error "'$cmd' wrong: found $nums, expected $expected"
6874
6875         cmd="$LFS find -stripe-size -320k -type f $dir"
6876         nums=$($cmd | wc -l)
6877         [ $nums -eq $expected ] ||
6878                 error "'$cmd' wrong: found $nums, expected $expected"
6879
6880         expected=0
6881         cmd="$LFS find -stripe-size 1024k -type f $dir"
6882         nums=$($cmd | wc -l)
6883         [ $nums -eq $expected ] ||
6884                 error "'$cmd' wrong: found $nums, expected $expected"
6885 }
6886 run_test 56t "check lfs find -stripe-size works"
6887
6888 test_56u() { # LU-611
6889         local dir=$DIR/$tdir
6890
6891         setup_56 $dir $NUMFILES $NUMDIRS "-i 0 -c 1"
6892
6893         if [[ $OSTCOUNT -gt 1 ]]; then
6894                 $LFS setstripe -i 1 -c 1 $dir/$tfile.{0,1,2,3}
6895                 onestripe=4
6896         else
6897                 onestripe=0
6898         fi
6899
6900         local expected=$(((NUMDIRS + 1) * NUMFILES))
6901         local cmd="$LFS find -stripe-index 0 -type f $dir"
6902         local nums=$($cmd | wc -l)
6903
6904         [ $nums -eq $expected ] ||
6905                 error "'$cmd' wrong: found $nums, expected $expected"
6906
6907         expected=$onestripe
6908         cmd="$LFS find -stripe-index 1 -type f $dir"
6909         nums=$($cmd | wc -l)
6910         [ $nums -eq $expected ] ||
6911                 error "'$cmd' wrong: found $nums, expected $expected"
6912
6913         cmd="$LFS find ! -stripe-index 0 -type f $dir"
6914         nums=$($cmd | wc -l)
6915         [ $nums -eq $expected ] ||
6916                 error "'$cmd' wrong: found $nums, expected $expected"
6917
6918         expected=0
6919         # This should produce an error and not return any files
6920         cmd="$LFS find -stripe-index $OSTCOUNT -type f $dir"
6921         nums=$($cmd 2>/dev/null | wc -l)
6922         [ $nums -eq $expected ] ||
6923                 error "'$cmd' wrong: found $nums, expected $expected"
6924
6925         if [[ $OSTCOUNT -gt 1 ]]; then
6926                 expected=$(((NUMDIRS + 1) * NUMFILES + onestripe))
6927                 cmd="$LFS find -stripe-index 0,1 -type f $dir"
6928                 nums=$($cmd | wc -l)
6929                 [ $nums -eq $expected ] ||
6930                         error "'$cmd' wrong: found $nums, expected $expected"
6931         fi
6932 }
6933 run_test 56u "check lfs find -stripe-index works"
6934
6935 test_56v() {
6936         local mdt_idx=0
6937         local dir=$DIR/$tdir
6938
6939         setup_56 $dir $NUMFILES $NUMDIRS
6940
6941         UUID=$(mdtuuid_from_index $mdt_idx $dir)
6942         [ -z "$UUID" ] && error "mdtuuid_from_index cannot find MDT $mdt_idx"
6943
6944         for file in $($LFS find -m $UUID $dir); do
6945                 file_midx=$($LFS getstripe -m $file)
6946                 [ $file_midx -eq $mdt_idx ] ||
6947                         error "lfs find -m $UUID != getstripe -m $file_midx"
6948         done
6949 }
6950 run_test 56v "check 'lfs find -m match with lfs getstripe -m'"
6951
6952 test_56w() {
6953         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
6954         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6955
6956         local dir=$DIR/$tdir
6957
6958         setup_56 $dir $NUMFILES $NUMDIRS "-c $OSTCOUNT" "-c1"
6959
6960         local stripe_size=$($LFS getstripe -S -d $dir) ||
6961                 error "$LFS getstripe -S -d $dir failed"
6962         stripe_size=${stripe_size%% *}
6963
6964         local file_size=$((stripe_size * OSTCOUNT))
6965         local file_num=$((NUMDIRS * NUMFILES + NUMFILES))
6966         local required_space=$((file_num * file_size))
6967         local free_space=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
6968                            head -n1)
6969         [[ $free_space -le $((required_space / 1024)) ]] &&
6970                 skip_env "need $required_space, have $free_space kbytes"
6971
6972         local dd_bs=65536
6973         local dd_count=$((file_size / dd_bs))
6974
6975         # write data into the files
6976         local i
6977         local j
6978         local file
6979
6980         for i in $(seq $NUMFILES); do
6981                 file=$dir/file$i
6982                 yes | dd bs=$dd_bs count=$dd_count of=$file &>/dev/null ||
6983                         error "write data into $file failed"
6984         done
6985         for i in $(seq $NUMDIRS); do
6986                 for j in $(seq $NUMFILES); do
6987                         file=$dir/dir$i/file$j
6988                         yes|dd bs=$dd_bs count=$dd_count of=$file &>/dev/null ||
6989                                 error "write data into $file failed"
6990                 done
6991         done
6992
6993         # $LFS_MIGRATE will fail if hard link migration is unsupported
6994         if [[ $MDS1_VERSION -gt $(version_code 2.5.55) ]]; then
6995                 createmany -l$dir/dir1/file1 $dir/dir1/link 200 ||
6996                         error "creating links to $dir/dir1/file1 failed"
6997         fi
6998
6999         local expected=-1
7000
7001         [[ $OSTCOUNT -gt 1 ]] && expected=$((OSTCOUNT - 1))
7002
7003         # lfs_migrate file
7004         local cmd="$LFS_MIGRATE -y -c $expected $dir/file1"
7005
7006         echo "$cmd"
7007         eval $cmd || error "$cmd failed"
7008
7009         check_stripe_count $dir/file1 $expected
7010
7011         if [ $MDS1_VERSION -ge $(version_code 2.6.90) ];
7012         then
7013                 # lfs_migrate file onto OST 0 if it is on OST 1, or onto
7014                 # OST 1 if it is on OST 0. This file is small enough to
7015                 # be on only one stripe.
7016                 file=$dir/migr_1_ost
7017                 dd bs=$dd_bs count=1 if=/dev/urandom of=$file >/dev/null 2>&1 ||
7018                         error "write data into $file failed"
7019                 local obdidx=$($LFS getstripe -i $file)
7020                 local oldmd5=$(md5sum $file)
7021                 local newobdidx=0
7022
7023                 [[ $obdidx -eq 0 ]] && newobdidx=1
7024                 cmd="$LFS migrate -i $newobdidx $file"
7025                 echo $cmd
7026                 eval $cmd || error "$cmd failed"
7027
7028                 local realobdix=$($LFS getstripe -i $file)
7029                 local newmd5=$(md5sum $file)
7030
7031                 [[ $newobdidx -ne $realobdix ]] &&
7032                         error "new OST is different (was=$obdidx, "\
7033                               "wanted=$newobdidx, got=$realobdix)"
7034                 [[ "$oldmd5" != "$newmd5" ]] &&
7035                         error "md5sum differ: $oldmd5, $newmd5"
7036         fi
7037
7038         # lfs_migrate dir
7039         cmd="$LFS_MIGRATE -y -c $expected $dir/dir1"
7040         echo "$cmd"
7041         eval $cmd || error "$cmd failed"
7042
7043         for j in $(seq $NUMFILES); do
7044                 check_stripe_count $dir/dir1/file$j $expected
7045         done
7046
7047         # lfs_migrate works with lfs find
7048         cmd="$LFS find -stripe_count $OSTCOUNT -type f $dir |
7049              $LFS_MIGRATE -y -c $expected"
7050         echo "$cmd"
7051         eval $cmd || error "$cmd failed"
7052
7053         for i in $(seq 2 $NUMFILES); do
7054                 check_stripe_count $dir/file$i $expected
7055         done
7056         for i in $(seq 2 $NUMDIRS); do
7057                 for j in $(seq $NUMFILES); do
7058                 check_stripe_count $dir/dir$i/file$j $expected
7059                 done
7060         done
7061 }
7062 run_test 56w "check lfs_migrate -c stripe_count works"
7063
7064 test_56wb() {
7065         local file1=$DIR/$tdir/file1
7066         local create_pool=false
7067         local initial_pool=$($LFS getstripe -p $DIR)
7068         local pool_list=()
7069         local pool=""
7070
7071         echo -n "Creating test dir..."
7072         test_mkdir $DIR/$tdir &> /dev/null || error "cannot create dir"
7073         echo "done."
7074
7075         echo -n "Creating test file..."
7076         touch $file1 || error "cannot create file"
7077         echo "done."
7078
7079         echo -n "Detecting existing pools..."
7080         pool_list=($($LFS pool_list $FSNAME | grep "$FSNAME\." | cut -d. -f2))
7081
7082         if [ ${#pool_list[@]} -gt 0 ]; then
7083                 echo "${pool_list[@]}"
7084                 for thispool in "${pool_list[@]}"; do
7085                         if [[ -z "$initial_pool" ||
7086                               "$initial_pool" != "$thispool" ]]; then
7087                                 pool="$thispool"
7088                                 echo "Using existing pool '$pool'"
7089                                 break
7090                         fi
7091                 done
7092         else
7093                 echo "none detected."
7094         fi
7095         if [ -z "$pool" ]; then
7096                 pool=${POOL:-testpool}
7097                 [ "$initial_pool" = "$pool" ] && pool="testpool2"
7098                 echo -n "Creating pool '$pool'..."
7099                 create_pool=true
7100                 pool_add $pool &> /dev/null ||
7101                         error "pool_add failed"
7102                 echo "done."
7103
7104                 echo -n "Adding target to pool..."
7105                 pool_add_targets $pool 0 0 1 &> /dev/null ||
7106                         error "pool_add_targets failed"
7107                 echo "done."
7108         fi
7109
7110         echo -n "Setting pool using -p option..."
7111         $LFS_MIGRATE -y -q --no-rsync -p $pool $file1 &> /dev/null ||
7112                 error "migrate failed rc = $?"
7113         echo "done."
7114
7115         echo -n "Verifying test file is in pool after migrating..."
7116         [ "$($LFS getstripe -p $file1)" = $pool ] ||
7117                 error "file was not migrated to pool $pool"
7118         echo "done."
7119
7120         echo -n "Removing test file from pool '$pool'..."
7121         # "lfs migrate $file" won't remove the file from the pool
7122         # until some striping information is changed.
7123         $LFS migrate -c 1 $file1 &> /dev/null ||
7124                 error "cannot remove from pool"
7125         [ "$($LFS getstripe -p $file1)" ] &&
7126                 error "pool still set"
7127         echo "done."
7128
7129         echo -n "Setting pool using --pool option..."
7130         $LFS_MIGRATE -y -q --no-rsync --pool $pool $file1 &> /dev/null ||
7131                 error "migrate failed rc = $?"
7132         echo "done."
7133
7134         # Clean up
7135         rm -f $file1
7136         if $create_pool; then
7137                 destroy_test_pools 2> /dev/null ||
7138                         error "destroy test pools failed"
7139         fi
7140 }
7141 run_test 56wb "check lfs_migrate pool support"
7142
7143 test_56wc() {
7144         local file1="$DIR/$tdir/file1"
7145         local parent_ssize
7146         local parent_scount
7147         local cur_ssize
7148         local cur_scount
7149         local orig_ssize
7150
7151         echo -n "Creating test dir..."
7152         test_mkdir $DIR/$tdir &> /dev/null || error "cannot create dir"
7153         $LFS setstripe -S 1M -c 1 "$DIR/$tdir" &> /dev/null ||
7154                 error "cannot set stripe by '-S 1M -c 1'"
7155         echo "done"
7156
7157         echo -n "Setting initial stripe for test file..."
7158         $LFS setstripe -S 512K -c 1 "$file1" &> /dev/null ||
7159                 error "cannot set stripe"
7160         cur_ssize=$($LFS getstripe -S "$file1")
7161         [ $cur_ssize -eq 524288 ] || error "setstripe -S $cur_ssize != 524288"
7162         echo "done."
7163
7164         # File currently set to -S 512K -c 1
7165
7166         # Ensure -c and -S options are rejected when -R is set
7167         echo -n "Verifying incompatible options are detected..."
7168         $LFS_MIGRATE -y -R -c 1 "$file1" &> /dev/null &&
7169                 error "incompatible -c and -R options not detected"
7170         $LFS_MIGRATE -y -R -S 1M "$file1" &> /dev/null &&
7171                 error "incompatible -S and -R options not detected"
7172         echo "done."
7173
7174         # Ensure unrecognized options are passed through to 'lfs migrate'
7175         echo -n "Verifying -S option is passed through to lfs migrate..."
7176         $LFS_MIGRATE -y -S 1M "$file1" &> /dev/null ||
7177                 error "migration failed"
7178         cur_ssize=$($LFS getstripe -S "$file1")
7179         [ $cur_ssize -eq 1048576 ] || error "migrate -S $cur_ssize != 1048576"
7180         echo "done."
7181
7182         # File currently set to -S 1M -c 1
7183
7184         # Ensure long options are supported
7185         echo -n "Verifying long options supported..."
7186         $LFS_MIGRATE -y --non-block "$file1" &> /dev/null ||
7187                 error "long option without argument not supported"
7188         $LFS_MIGRATE -y --stripe-size 512K "$file1" &> /dev/null ||
7189                 error "long option with argument not supported"
7190         cur_ssize=$($LFS getstripe -S "$file1")
7191         [ $cur_ssize -eq 524288 ] ||
7192                 error "migrate --stripe-size $cur_ssize != 524288"
7193         echo "done."
7194
7195         # File currently set to -S 512K -c 1
7196
7197         if [ "$OSTCOUNT" -gt 1 ]; then
7198                 echo -n "Verifying explicit stripe count can be set..."
7199                 $LFS_MIGRATE -y -c 2 "$file1" &> /dev/null ||
7200                         error "migrate failed"
7201                 cur_scount=$($LFS getstripe -c "$file1")
7202                 [ $cur_scount -eq 2 ] || error "migrate -c $cur_scount != 2"
7203                 echo "done."
7204         fi
7205
7206         # File currently set to -S 512K -c 1 or -S 512K -c 2
7207
7208         # Ensure parent striping is used if -R is set, and no stripe
7209         # count or size is specified
7210         echo -n "Setting stripe for parent directory..."
7211         $LFS setstripe -S 2M -c 1 "$DIR/$tdir" &> /dev/null ||
7212                 error "cannot set stripe '-S 2M -c 1'"
7213         echo "done."
7214
7215         echo -n "Verifying restripe option uses parent stripe settings..."
7216         parent_ssize=$($LFS getstripe -S $DIR/$tdir 2>/dev/null)
7217         parent_scount=$($LFS getstripe -c $DIR/$tdir 2>/dev/null)
7218         $LFS_MIGRATE -y -R "$file1" &> /dev/null ||
7219                 error "migrate failed"
7220         cur_ssize=$($LFS getstripe -S "$file1")
7221         [ $cur_ssize -eq $parent_ssize ] ||
7222                 error "migrate -R stripe_size $cur_ssize != $parent_ssize"
7223         cur_scount=$($LFS getstripe -c "$file1")
7224         [ $cur_scount -eq $parent_scount ] ||
7225                 error "migrate -R stripe_count $cur_scount != $parent_scount"
7226         echo "done."
7227
7228         # File currently set to -S 1M -c 1
7229
7230         # Ensure striping is preserved if -R is not set, and no stripe
7231         # count or size is specified
7232         echo -n "Verifying striping size preserved when not specified..."
7233         orig_ssize=$($LFS getstripe -S "$file1" 2>/dev/null)
7234         $LFS setstripe -S 2M -c 1 "$DIR/$tdir" &> /dev/null ||
7235                 error "cannot set stripe on parent directory"
7236         $LFS_MIGRATE -y "$file1" &> /dev/null ||
7237                 error "migrate failed"
7238         cur_ssize=$($LFS getstripe -S "$file1")
7239         [ $cur_ssize -eq $orig_ssize ] ||
7240                 error "migrate by default $cur_ssize != $orig_ssize"
7241         echo "done."
7242
7243         # Ensure file name properly detected when final option has no argument
7244         echo -n "Verifying file name properly detected..."
7245         $LFS_MIGRATE -y "$file1" &> /dev/null ||
7246                 error "file name interpreted as option argument"
7247         echo "done."
7248
7249         # Clean up
7250         rm -f "$file1"
7251 }
7252 run_test 56wc "check unrecognized options for lfs_migrate are passed through"
7253
7254 test_56wd() {
7255         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7256
7257         local file1=$DIR/$tdir/file1
7258
7259         echo -n "Creating test dir..."
7260         test_mkdir $DIR/$tdir || error "cannot create dir"
7261         echo "done."
7262
7263         echo -n "Creating test file..."
7264         touch $file1
7265         echo "done."
7266
7267         # Ensure 'lfs migrate' will fail by using a non-existent option,
7268         # and make sure rsync is not called to recover
7269         echo -n "Make sure --no-rsync option works..."
7270         $LFS_MIGRATE -y --no-rsync --invalid-opt $file1 2>&1 |
7271                 grep -q 'refusing to fall back to rsync' ||
7272                 error "rsync was called with --no-rsync set"
7273         echo "done."
7274
7275         # Ensure rsync is called without trying 'lfs migrate' first
7276         echo -n "Make sure --rsync option works..."
7277         $LFS_MIGRATE -y --rsync --invalid-opt $file1 2>&1 |
7278                 grep -q 'falling back to rsync' &&
7279                 error "lfs migrate was called with --rsync set"
7280         echo "done."
7281
7282         echo -n "Make sure --rsync and --no-rsync options are exclusive..."
7283         $LFS_MIGRATE -y --rsync --no-rsync $file1 2>&1 |
7284                 grep -q 'at the same time' ||
7285                 error "--rsync and --no-rsync accepted concurrently"
7286         echo "done."
7287
7288         # Clean up
7289         rm -f $file1
7290 }
7291 run_test 56wd "check lfs_migrate --rsync and --no-rsync work"
7292
7293 test_56we() {
7294         local td=$DIR/$tdir
7295         local tf=$td/$tfile
7296
7297         test_mkdir $td || error "cannot create $td"
7298         touch $tf || error "cannot touch $tf"
7299
7300         echo -n "Make sure --non-direct|-D works..."
7301         $LFS_MIGRATE -y --non-direct -v $tf 2>&1 |
7302                 grep -q "lfs migrate --non-direct" ||
7303                 error "--non-direct option cannot work correctly"
7304         $LFS_MIGRATE -y -D -v $tf 2>&1 |
7305                 grep -q "lfs migrate -D" ||
7306                 error "-D option cannot work correctly"
7307         echo "done."
7308 }
7309 run_test 56we "check lfs_migrate --non-direct|-D support"
7310
7311 test_56x() {
7312         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7313         check_swap_layouts_support
7314
7315         local dir=$DIR/$tdir
7316         local ref1=/etc/passwd
7317         local file1=$dir/file1
7318
7319         test_mkdir $dir || error "creating dir $dir"
7320         $LFS setstripe -c 2 $file1
7321         cp $ref1 $file1
7322         $LFS migrate -c 1 $file1 || error "migrate failed rc = $?"
7323         stripe=$($LFS getstripe -c $file1)
7324         [[ $stripe == 1 ]] || error "stripe of $file1 is $stripe != 1"
7325         cmp $file1 $ref1 || error "content mismatch $file1 differs from $ref1"
7326
7327         # clean up
7328         rm -f $file1
7329 }
7330 run_test 56x "lfs migration support"
7331
7332 test_56xa() {
7333         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7334         check_swap_layouts_support
7335
7336         local dir=$DIR/$tdir/$testnum
7337
7338         test_mkdir -p $dir
7339
7340         local ref1=/etc/passwd
7341         local file1=$dir/file1
7342
7343         $LFS setstripe -c 2 $file1
7344         cp $ref1 $file1
7345         $LFS migrate --block -c 1 $file1 || error "migrate failed rc = $?"
7346
7347         local stripe=$($LFS getstripe -c $file1)
7348
7349         [[ $stripe == 1 ]] || error "stripe of $file1 is $stripe != 1"
7350         cmp $file1 $ref1 || error "content mismatch $file1 differs from $ref1"
7351
7352         # clean up
7353         rm -f $file1
7354 }
7355 run_test 56xa "lfs migration --block support"
7356
7357 check_migrate_links() {
7358         local dir="$1"
7359         local file1="$dir/file1"
7360         local begin="$2"
7361         local count="$3"
7362         local runas="$4"
7363         local total_count=$(($begin + $count - 1))
7364         local symlink_count=10
7365         local uniq_count=10
7366
7367         if [ ! -f "$file1" ]; then
7368                 echo -n "creating initial file..."
7369                 $LFS setstripe -c 1 -S "512k" "$file1" ||
7370                         error "cannot setstripe initial file"
7371                 echo "done"
7372
7373                 echo -n "creating symlinks..."
7374                 for s in $(seq 1 $symlink_count); do
7375                         ln -s "$file1" "$dir/slink$s" ||
7376                                 error "cannot create symlinks"
7377                 done
7378                 echo "done"
7379
7380                 echo -n "creating nonlinked files..."
7381                 createmany -o "$dir/uniq" 1 10 &> /dev/null ||
7382                         error "cannot create nonlinked files"
7383                 echo "done"
7384         fi
7385
7386         # create hard links
7387         if [ ! -f "$dir/file$total_count" ]; then
7388                 echo -n "creating hard links $begin:$total_count..."
7389                 createmany -l"$file1" "$dir/file" "$begin" "$count" &>  \
7390                         /dev/null || error "cannot create hard links"
7391                 echo "done"
7392         fi
7393
7394         echo -n "checking number of hard links listed in xattrs..."
7395         local fid=$($LFS getstripe -F "$file1")
7396         local paths=($($LFS fid2path "$MOUNT" "$fid" 2> /dev/null))
7397
7398         echo "${#paths[*]}"
7399         if [ ${#paths[*]} -lt $total_count -a "$begin" -eq 2  ]; then
7400                         skip "hard link list has unexpected size, skipping test"
7401         fi
7402         if [ ${#paths[*]} -ge $total_count -a "$begin" -ne 2  ]; then
7403                         error "link names should exceed xattrs size"
7404         fi
7405
7406         echo -n "migrating files..."
7407         local migrate_out=$($runas $LFS_MIGRATE -y -S '1m' $dir)
7408         local rc=$?
7409         [ $rc -eq 0 ] || error "migrate failed rc = $rc"
7410         echo "done"
7411
7412         # make sure all links have been properly migrated
7413         echo -n "verifying files..."
7414         fid=$($LFS getstripe -F "$file1") ||
7415                 error "cannot get fid for file $file1"
7416         for i in $(seq 2 $total_count); do
7417                 local fid2=$($LFS getstripe -F $dir/file$i)
7418
7419                 [ "$fid2" == "$fid" ] ||
7420                         error "migrated hard link has mismatched FID"
7421         done
7422
7423         # make sure hard links were properly detected, and migration was
7424         # performed only once for the entire link set; nonlinked files should
7425         # also be migrated
7426         local actual=$(grep -c 'done' <<< "$migrate_out")
7427         local expected=$(($uniq_count + 1))
7428
7429         [ "$actual" -eq  "$expected" ] ||
7430                 error "hard links individually migrated ($actual != $expected)"
7431
7432         # make sure the correct number of hard links are present
7433         local hardlinks=$(stat -c '%h' "$file1")
7434
7435         [ $hardlinks -eq $total_count ] ||
7436                 error "num hard links $hardlinks != $total_count"
7437         echo "done"
7438
7439         return 0
7440 }
7441
7442 test_56xb() {
7443         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
7444                 skip "Need MDS version at least 2.10.55"
7445
7446         local dir="$DIR/$tdir"
7447
7448         test_mkdir "$dir" || error "cannot create dir $dir"
7449
7450         echo "testing lfs migrate mode when all links fit within xattrs"
7451         LFS_MIGRATE_RSYNC_MODE=false check_migrate_links "$dir" 2 99
7452
7453         echo "testing rsync mode when all links fit within xattrs"
7454         LFS_MIGRATE_RSYNC_MODE=true check_migrate_links "$dir" 2 99
7455
7456         echo "testing lfs migrate mode when all links do not fit within xattrs"
7457         LFS_MIGRATE_RSYNC_MODE=false check_migrate_links "$dir" 101 100
7458
7459         echo "testing rsync mode when all links do not fit within xattrs"
7460         LFS_MIGRATE_RSYNC_MODE=true check_migrate_links "$dir" 101 100
7461
7462         chown -R $RUNAS_ID $dir
7463         echo "testing non-root lfs migrate mode when not all links are in xattr"
7464         LFS_MIGRATE_RSYNC_MODE=false check_migrate_links "$dir" 101 100 "$RUNAS"
7465
7466         # clean up
7467         rm -rf $dir
7468 }
7469 run_test 56xb "lfs migration hard link support"
7470
7471 test_56xc() {
7472         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7473
7474         local dir="$DIR/$tdir"
7475
7476         test_mkdir "$dir" || error "cannot create dir $dir"
7477
7478         # Test 1: ensure file < 1 GB is always migrated with 1 stripe
7479         echo -n "Setting initial stripe for 20MB test file..."
7480         $LFS setstripe -c 2 -i 0 "$dir/20mb" ||
7481                 error "cannot setstripe 20MB file"
7482         echo "done"
7483         echo -n "Sizing 20MB test file..."
7484         $TRUNCATE "$dir/20mb" 20971520 || error "cannot create 20MB test file"
7485         echo "done"
7486         echo -n "Verifying small file autostripe count is 1..."
7487         $LFS_MIGRATE -y -A -C 1 "$dir/20mb" ||
7488                 error "cannot migrate 20MB file"
7489         local stripe_count=$($LFS getstripe -c "$dir/20mb") ||
7490                 error "cannot get stripe for $dir/20mb"
7491         [ $stripe_count -eq 1 ] ||
7492                 error "unexpected stripe count $stripe_count for 20MB file"
7493         rm -f "$dir/20mb"
7494         echo "done"
7495
7496         # Test 2: File is small enough to fit within the available space on
7497         # sqrt(size_in_gb) + 1 OSTs but is larger than 1GB.  The file must
7498         # have at least an additional 1KB for each desired stripe for test 3
7499         echo -n "Setting stripe for 1GB test file..."
7500         $LFS setstripe -c 1 -i 0 "$dir/1gb" || error "cannot setstripe 1GB file"
7501         echo "done"
7502         echo -n "Sizing 1GB test file..."
7503         # File size is 1GB + 3KB
7504         $TRUNCATE "$dir/1gb" 1073744896 || error "cannot create 1GB test file"
7505         echo "done"
7506
7507         # need at least 512MB per OST for 1GB file to fit in 2 stripes
7508         local avail=$($LCTL get_param -n llite.$FSNAME*.kbytesavail)
7509         if (( avail > 524288 * OSTCOUNT )); then
7510                 echo -n "Migrating 1GB file..."
7511                 $LFS_MIGRATE -y -A -C 1 "$dir/1gb" ||
7512                         error "cannot migrate 1GB file"
7513                 echo "done"
7514                 echo -n "Verifying autostripe count is sqrt(n) + 1..."
7515                 stripe_count=$($LFS getstripe -c "$dir/1gb") ||
7516                         error "cannot getstripe for 1GB file"
7517                 [ $stripe_count -eq 2 ] ||
7518                         error "unexpected stripe count $stripe_count != 2"
7519                 echo "done"
7520         fi
7521
7522         # Test 3: File is too large to fit within the available space on
7523         # sqrt(n) + 1 OSTs.  Simulate limited available space with -X
7524         if [ $OSTCOUNT -ge 3 ]; then
7525                 # The required available space is calculated as
7526                 # file size (1GB + 3KB) / OST count (3).
7527                 local kb_per_ost=349526
7528
7529                 echo -n "Migrating 1GB file with limit..."
7530                 $LFS_MIGRATE -y -A -C 1 -X $kb_per_ost "$dir/1gb" ||
7531                         error "cannot migrate 1GB file with limit"
7532                 echo "done"
7533
7534                 stripe_count=$($LFS getstripe -c "$dir/1gb")
7535                 echo -n "Verifying 1GB autostripe count with limited space..."
7536                 [ "$stripe_count" -a $stripe_count -ge 3 ] ||
7537                         error "unexpected stripe count $stripe_count (min 3)"
7538                 echo "done"
7539         fi
7540
7541         # clean up
7542         rm -rf $dir
7543 }
7544 run_test 56xc "lfs migration autostripe"
7545
7546 test_56xd() {
7547         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7548
7549         local dir=$DIR/$tdir
7550         local f_mgrt=$dir/$tfile.mgrt
7551         local f_yaml=$dir/$tfile.yaml
7552         local f_copy=$dir/$tfile.copy
7553         local layout_yaml="-E 1M -S 512K -c 1 -E -1 -S 1M -c 2 -i 0"
7554         local layout_copy="-c 2 -S 2M -i 1"
7555         local yamlfile=$dir/yamlfile
7556         local layout_before;
7557         local layout_after;
7558
7559         test_mkdir "$dir" || error "cannot create dir $dir"
7560         $LFS setstripe $layout_yaml $f_yaml ||
7561                 error "cannot setstripe $f_yaml with layout $layout_yaml"
7562         $LFS getstripe --yaml $f_yaml > $yamlfile
7563         $LFS setstripe $layout_copy $f_copy ||
7564                 error "cannot setstripe $f_copy with layout $layout_copy"
7565         touch $f_mgrt
7566         dd if=/dev/zero of=$f_mgrt bs=1M count=4
7567
7568         # 1. test option --yaml
7569         $LFS_MIGRATE -y --yaml $yamlfile $f_mgrt ||
7570                 error "cannot migrate $f_mgrt with --yaml $yamlfile"
7571         layout_before=$(get_layout_param $f_yaml)
7572         layout_after=$(get_layout_param $f_mgrt)
7573         [ "$layout_after" == "$layout_before" ] ||
7574                 error "lfs_migrate --yaml: $layout_after != $layout_before"
7575
7576         # 2. test option --copy
7577         $LFS_MIGRATE -y --copy $f_copy $f_mgrt ||
7578                 error "cannot migrate $f_mgrt with --copy $f_copy"
7579         layout_before=$(get_layout_param $f_copy)
7580         layout_after=$(get_layout_param $f_mgrt)
7581         [ "$layout_after" == "$layout_before" ] ||
7582                 error "lfs_migrate --copy: $layout_after != $layout_before"
7583 }
7584 run_test 56xd "check lfs_migrate --yaml and --copy support"
7585
7586 test_56xe() {
7587         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7588
7589         local dir=$DIR/$tdir
7590         local f_comp=$dir/$tfile
7591         local layout="-E 1M -S 512K -c 1 -E -1 -S 1M -c 2 -i 0"
7592         local layout_before=""
7593         local layout_after=""
7594
7595         test_mkdir "$dir" || error "cannot create dir $dir"
7596         $LFS setstripe $layout $f_comp ||
7597                 error "cannot setstripe $f_comp with layout $layout"
7598         layout_before=$(get_layout_param $f_comp)
7599         dd if=/dev/zero of=$f_comp bs=1M count=4
7600
7601         # 1. migrate a comp layout file by lfs_migrate
7602         $LFS_MIGRATE -y $f_comp || error "cannot migrate $f_comp by lfs_migrate"
7603         layout_after=$(get_layout_param $f_comp)
7604         [ "$layout_before" == "$layout_after" ] ||
7605                 error "lfs_migrate: $layout_before != $layout_after"
7606
7607         # 2. migrate a comp layout file by lfs migrate
7608         $LFS migrate $f_comp || error "cannot migrate $f_comp by lfs migrate"
7609         layout_after=$(get_layout_param $f_comp)
7610         [ "$layout_before" == "$layout_after" ] ||
7611                 error "lfs migrate: $layout_before != $layout_after"
7612 }
7613 run_test 56xe "migrate a composite layout file"
7614
7615 test_56xf() {
7616         [[ $OSTCOUNT -ge 2 ]] || skip_env "needs >= 2 OSTs"
7617
7618         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
7619                 skip "Need server version at least 2.13.53"
7620
7621         local dir=$DIR/$tdir
7622         local f_comp=$dir/$tfile
7623         local layout="-E 1M -c1 -E -1 -c2"
7624         local fid_before=""
7625         local fid_after=""
7626
7627         test_mkdir "$dir" || error "cannot create dir $dir"
7628         $LFS setstripe $layout $f_comp ||
7629                 error "cannot setstripe $f_comp with layout $layout"
7630         fid_before=$($LFS getstripe --fid $f_comp)
7631         dd if=/dev/zero of=$f_comp bs=1M count=4
7632
7633         # 1. migrate a comp layout file to a comp layout
7634         $LFS migrate $f_comp || error "cannot migrate $f_comp by lfs migrate"
7635         fid_after=$($LFS getstripe --fid $f_comp)
7636         [ "$fid_before" == "$fid_after" ] ||
7637                 error "comp-to-comp migrate: $fid_before != $fid_after"
7638
7639         # 2. migrate a comp layout file to a plain layout
7640         $LFS migrate -c2 $f_comp ||
7641                 error "cannot migrate $f_comp by lfs migrate"
7642         fid_after=$($LFS getstripe --fid $f_comp)
7643         [ "$fid_before" == "$fid_after" ] ||
7644                 error "comp-to-plain migrate: $fid_before != $fid_after"
7645
7646         # 3. migrate a plain layout file to a comp layout
7647         $LFS migrate $layout $f_comp ||
7648                 error "cannot migrate $f_comp by lfs migrate"
7649         fid_after=$($LFS getstripe --fid $f_comp)
7650         [ "$fid_before" == "$fid_after" ] ||
7651                 error "plain-to-comp migrate: $fid_before != $fid_after"
7652 }
7653 run_test 56xf "FID is not lost during migration of a composite layout file"
7654
7655 check_file_ost_range() {
7656         local file="$1"
7657         shift
7658         local range="$*"
7659         local -a file_range
7660         local idx
7661
7662         file_range=($($LFS getstripe -y "$file" |
7663                 awk '/l_ost_idx:/ { print $NF }'))
7664
7665         if [[ "${#file_range[@]}" = 0 ]]; then
7666                 echo "No osts found for $file"
7667                 return 1
7668         fi
7669
7670         for idx in "${file_range[@]}"; do
7671                 [[ " $range " =~ " $idx " ]] ||
7672                         return 1
7673         done
7674
7675         return 0
7676 }
7677
7678 sub_test_56xg() {
7679         local stripe_opt="$1"
7680         local pool="$2"
7681         shift 2
7682         local pool_ostidx="$(seq $* | tr '\n' ' ')"
7683
7684         $LFS migrate $stripe_opt -p $pool $DIR/$tfile ||
7685                 error "Fail to migrate $tfile on $pool"
7686         [[ "$($LFS getstripe -p $DIR/$tfile)" = "$pool" ]] ||
7687                 error "$tfile is not in pool $pool"
7688         check_file_ost_range "$DIR/$tfile" $pool_ostidx ||
7689                 error "$tfile osts mismatch with pool $pool (osts $pool_ostidx)"
7690 }
7691
7692 test_56xg() {
7693         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
7694         [[ $OSTCOUNT -ge 2 ]] || skip "needs >= 2 OSTs"
7695         [[ $MDS1_VERSION -gt $(version_code 2.14.52) ]] ||
7696                 skip "Need MDS version newer than 2.14.52"
7697
7698         local -a pool_names=("${TESTNAME}_0" "${TESTNAME}_1" "${TESTNAME}_2")
7699         local -a pool_ranges=("0 0" "1 1" "0 1")
7700
7701         # init pools
7702         for i in "${!pool_names[@]}"; do
7703                 pool_add ${pool_names[$i]} ||
7704                         error "pool_add failed (pool: ${pool_names[$i]})"
7705                 pool_add_targets ${pool_names[$i]} ${pool_ranges[$i]} ||
7706                         error "pool_add_targets failed (pool: ${pool_names[$i]})"
7707         done
7708
7709         # init the file to migrate
7710         $LFS setstripe -c1 -i1 $DIR/$tfile ||
7711                 error "Unable to create $tfile on OST1"
7712         dd if=/dev/urandom of=$DIR/$tfile bs=1M count=4 status=none ||
7713                 error "Unable to write on $tfile"
7714
7715         echo "1. migrate $tfile on pool ${pool_names[0]}"
7716         sub_test_56xg "-c-1" "${pool_names[0]}" ${pool_ranges[0]}
7717
7718         echo "2. migrate $tfile on pool ${pool_names[2]}"
7719         sub_test_56xg "-c-1 -S2M" "${pool_names[2]}" ${pool_ranges[2]}
7720
7721         echo "3. migrate $tfile on pool ${pool_names[1]}"
7722         sub_test_56xg "-n -c-1" "${pool_names[1]}" ${pool_ranges[1]}
7723
7724         echo "4. migrate $tfile on pool ${pool_names[2]} with default stripe parameters"
7725         sub_test_56xg "" "${pool_names[2]}" ${pool_ranges[2]}
7726         echo
7727
7728         # Clean pools
7729         destroy_test_pools ||
7730                 error "pool_destroy failed"
7731 }
7732 run_test 56xg "lfs migrate pool support"
7733
7734 test_56y() {
7735         [ $MDS1_VERSION -lt $(version_code 2.4.53) ] &&
7736                 skip "No HSM $(lustre_build_version $SINGLEMDS) MDS < 2.4.53"
7737
7738         local res=""
7739         local dir=$DIR/$tdir
7740         local f1=$dir/file1
7741         local f2=$dir/file2
7742
7743         test_mkdir -p $dir || error "creating dir $dir"
7744         touch $f1 || error "creating std file $f1"
7745         $MULTIOP $f2 H2c || error "creating released file $f2"
7746
7747         # a directory can be raid0, so ask only for files
7748         res=$($LFS find $dir -L raid0 -type f | wc -l)
7749         [[ $res == 2 ]] || error "search raid0: found $res files != 2"
7750
7751         res=$($LFS find $dir \! -L raid0 -type f | wc -l)
7752         [[ $res == 0 ]] || error "search !raid0: found $res files != 0"
7753
7754         # only files can be released, so no need to force file search
7755         res=$($LFS find $dir -L released)
7756         [[ $res == $f2 ]] || error "search released: found $res != $f2"
7757
7758         res=$($LFS find $dir -type f \! -L released)
7759         [[ $res == $f1 ]] || error "search !released: found $res != $f1"
7760 }
7761 run_test 56y "lfs find -L raid0|released"
7762
7763 test_56z() { # LU-4824
7764         # This checks to make sure 'lfs find' continues after errors
7765         # There are two classes of errors that should be caught:
7766         # - If multiple paths are provided, all should be searched even if one
7767         #   errors out
7768         # - If errors are encountered during the search, it should not terminate
7769         #   early
7770         local dir=$DIR/$tdir
7771         local i
7772
7773         test_mkdir $dir
7774         for i in d{0..9}; do
7775                 test_mkdir $dir/$i
7776                 touch $dir/$i/$tfile
7777         done
7778         $LFS find $DIR/non_existent_dir $dir &&
7779                 error "$LFS find did not return an error"
7780         # Make a directory unsearchable. This should NOT be the last entry in
7781         # directory order.  Arbitrarily pick the 6th entry
7782         chmod 700 $($LFS find $dir -type d | sed '6!d')
7783
7784         $RUNAS $LFS find $DIR/non_existent $dir
7785         local count=$($RUNAS $LFS find $DIR/non_existent $dir | wc -l)
7786
7787         # The user should be able to see 10 directories and 9 files
7788         (( count == 19 )) ||
7789                 error "$LFS find found $count != 19 entries after error"
7790 }
7791 run_test 56z "lfs find should continue after an error"
7792
7793 test_56aa() { # LU-5937
7794         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
7795
7796         local dir=$DIR/$tdir
7797
7798         mkdir $dir
7799         $LFS setdirstripe -c$MDSCOUNT $dir/striped_dir
7800
7801         createmany -o $dir/striped_dir/${tfile}- 1024
7802         local dirs=$($LFS find --size +8k $dir/)
7803
7804         [ -n "$dirs" ] || error "lfs find --size wrong under striped dir"
7805 }
7806 run_test 56aa "lfs find --size under striped dir"
7807
7808 test_56ab() { # LU-10705
7809         test_mkdir $DIR/$tdir
7810         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=8k count=1 seek=2k
7811         dd if=/dev/zero of=$DIR/$tdir/$tfile.2 bs=4k count=1 seek=4k
7812         dd if=/dev/zero of=$DIR/$tdir/$tfile.3 bs=1M count=2 seek=16
7813         # Flush writes to ensure valid blocks.  Need to be more thorough for
7814         # ZFS, since blocks are not allocated/returned to client immediately.
7815         sync_all_data
7816         wait_zfs_commit ost1 2
7817         cancel_lru_locks osc
7818         ls -ls $DIR/$tdir
7819
7820         local files=$($LFS find --size +16M $DIR/$tdir | wc -l)
7821
7822         [[ $files == 3 ]] || error ">16M size files $files isn't 3 as expected"
7823
7824         files=$($LFS find --blocks +1M $DIR/$tdir | wc -l)
7825         [[ $files == 1 ]] || error ">1M blocks files $files isn't 1 as expected"
7826
7827         rm -f $DIR/$tdir/$tfile.[123]
7828 }
7829 run_test 56ab "lfs find --blocks"
7830
7831 # LU-11188
7832 test_56aca() {
7833         local dir="$DIR/$tdir"
7834         local perms=(001 002 003 004 005 006 007
7835                      010 020 030 040 050 060 070
7836                      100 200 300 400 500 600 700
7837                      111 222 333 444 555 666 777)
7838         local perm_minus=(8 8 4 8 4 4 2
7839                           8 8 4 8 4 4 2
7840                           8 8 4 8 4 4 2
7841                           4 4 2 4 2 2 1)
7842         local perm_slash=(8  8 12  8 12 12 14
7843                           8  8 12  8 12 12 14
7844                           8  8 12  8 12 12 14
7845                          16 16 24 16 24 24 28)
7846
7847         test_mkdir "$dir"
7848         for perm in ${perms[*]}; do
7849                 touch "$dir/$tfile.$perm"
7850                 chmod $perm "$dir/$tfile.$perm"
7851         done
7852
7853         for ((i = 0; i < ${#perms[*]}; i++)); do
7854                 local num=$($LFS find $dir -perm ${perms[i]} | wc -l)
7855                 (( $num == 1 )) ||
7856                         error "lfs find -perm ${perms[i]}:"\
7857                               "$num != 1"
7858
7859                 num=$($LFS find $dir -perm -${perms[i]} -type f| wc -l)
7860                 (( $num == ${perm_minus[i]} )) ||
7861                         error "lfs find -perm -${perms[i]}:"\
7862                               "$num != ${perm_minus[i]}"
7863
7864                 num=$($LFS find $dir -perm /${perms[i]} -type f| wc -l)
7865                 (( $num == ${perm_slash[i]} )) ||
7866                         error "lfs find -perm /${perms[i]}:"\
7867                               "$num != ${perm_slash[i]}"
7868         done
7869 }
7870 run_test 56aca "check lfs find -perm with octal representation"
7871
7872 test_56acb() {
7873         local dir=$DIR/$tdir
7874         # p is the permission of write and execute for user, group and other
7875         # without the umask. It is used to test +wx.
7876         local p=$(printf "%o" "$((0333 & ~$(umask)))")
7877         local perms=(1000 000 2000 4000 $p 644 111 110 100 004)
7878         local symbolic=(+t  a+t u+t g+t o+t
7879                         g+s u+s o+s +s o+sr
7880                         o=r,ug+o,u+w
7881                         u+ g+ o+ a+ ugo+
7882                         u- g- o- a- ugo-
7883                         u= g= o= a= ugo=
7884                         o=r,ug+o,u+w u=r,a+u,u+w
7885                         g=r,ugo=g,u+w u+x,+X +X
7886                         u+x,u+X u+X u+x,g+X o+r,+X
7887                         u+x,go+X +wx +rwx)
7888
7889         test_mkdir $dir
7890         for perm in ${perms[*]}; do
7891                 touch "$dir/$tfile.$perm"
7892                 chmod $perm "$dir/$tfile.$perm"
7893         done
7894
7895         for (( i = 0; i < ${#symbolic[*]}; i++ )); do
7896                 local num=$($LFS find $dir -perm ${symbolic[i]} | wc -l)
7897
7898                 (( $num == 1 )) ||
7899                         error "lfs find $dir -perm ${symbolic[i]}: $num != 1"
7900         done
7901 }
7902 run_test 56acb "check lfs find -perm with symbolic representation"
7903
7904 test_56acc() {
7905         local dir=$DIR/$tdir
7906         local tests="17777 787 789 abcd
7907                 ug=uu ug=a ug=gu uo=ou urw
7908                 u+xg+x a=r,u+x,"
7909
7910         test_mkdir $dir
7911         for err in $tests; do
7912                 if $LFS find $dir -perm $err 2>/dev/null; then
7913                         error "lfs find -perm $err: parsing should have failed"
7914                 fi
7915         done
7916 }
7917 run_test 56acc "check parsing error for lfs find -perm"
7918
7919 test_56ba() {
7920         [ $MDS1_VERSION -lt $(version_code 2.10.50) ] &&
7921                 skip "Need MDS version at least 2.10.50"
7922
7923         # Create composite files with one component
7924         local dir=$DIR/$tdir
7925
7926         setup_56 $dir/1Mfiles 5 1 "-S 1M --component-end 1M"
7927         # Create composite files with three components
7928         setup_56 $dir/2Mfiles 5 2 "-E 2M -S 1M -E 4M -E 6M"
7929         # Create non-composite files
7930         createmany -o $dir/${tfile}- 10
7931
7932         local nfiles=$($LFS find --component-end 1M --type f $dir | wc -l)
7933
7934         [[ $nfiles == 10 ]] ||
7935                 error "lfs find -E 1M found $nfiles != 10 files"
7936
7937         nfiles=$($LFS find ! -E 1M --type f $dir | wc -l)
7938         [[ $nfiles == 25 ]] ||
7939                 error "lfs find ! -E 1M found $nfiles != 25 files"
7940
7941         # All files have a component that starts at 0
7942         nfiles=$($LFS find --component-start 0 --type f $dir | wc -l)
7943         [[ $nfiles == 35 ]] ||
7944                 error "lfs find --component-start 0 - $nfiles != 35 files"
7945
7946         nfiles=$($LFS find --component-start 2M --type f $dir | wc -l)
7947         [[ $nfiles == 15 ]] ||
7948                 error "lfs find --component-start 2M - $nfiles != 15 files"
7949
7950         # All files created here have a componenet that does not starts at 2M
7951         nfiles=$($LFS find ! --component-start 2M --type f $dir | wc -l)
7952         [[ $nfiles == 35 ]] ||
7953                 error "lfs find ! --component-start 2M - $nfiles != 35 files"
7954
7955         # Find files with a specified number of components
7956         local nfiles=$($LFS find --component-count 3 --type f $dir | wc -l)
7957         [[ $nfiles == 15 ]] ||
7958                 error "lfs find --component-count 3 - $nfiles != 15 files"
7959
7960         # Remember non-composite files have a component count of zero
7961         local nfiles=$($LFS find --component-count 0 --type f $dir | wc -l)
7962         [[ $nfiles == 10 ]] ||
7963                 error "lfs find --component-count 0 - $nfiles != 10 files"
7964
7965         nfiles=$($LFS find ! --component-count 3 --type f $dir | wc -l)
7966         [[ $nfiles == 20 ]] ||
7967                 error "lfs find ! --component-count 3 - $nfiles != 20 files"
7968
7969         # All files have a flag called "init"
7970         local nfiles=$($LFS find --component-flags init --type f $dir | wc -l)
7971         [[ $nfiles == 35 ]] ||
7972                 error "lfs find --component-flags init - $nfiles != 35 files"
7973
7974         # Multi-component files will have a component not initialized
7975         local nfiles=$($LFS find ! --component-flags init --type f $dir | wc -l)
7976         [[ $nfiles == 15 ]] ||
7977                 error "lfs find !--component-flags init - $nfiles != 15 files"
7978
7979         rm -rf $dir
7980
7981 }
7982 run_test 56ba "test lfs find --component-end, -start, -count, and -flags"
7983
7984 test_56ca() {
7985         [[ $MDS1_VERSION -ge $(version_code 2.10.57) ]] ||
7986                 skip "Need MDS version at least 2.10.57"
7987
7988         local td=$DIR/$tdir
7989         local tf=$td/$tfile
7990         local dir
7991         local nfiles
7992         local cmd
7993         local i
7994         local j
7995
7996         # create mirrored directories and mirrored files
7997         mkdir $td || error "mkdir $td failed"
7998         $LFS mirror create -N3 $td || error "create mirrored dir $td failed"
7999         createmany -o $tf- 10 || error "create $tf- failed"
8000
8001         for i in $(seq 2); do
8002                 dir=$td/dir$i
8003                 mkdir $dir || error "mkdir $dir failed"
8004                 $LFS mirror create -N$((3 + i)) $dir ||
8005                         error "create mirrored dir $dir failed"
8006                 createmany -o $dir/$tfile- 10 ||
8007                         error "create $dir/$tfile- failed"
8008         done
8009
8010         # change the states of some mirrored files
8011         echo foo > $tf-6
8012         for i in $(seq 2); do
8013                 dir=$td/dir$i
8014                 for j in $(seq 4 9); do
8015                         echo foo > $dir/$tfile-$j
8016                 done
8017         done
8018
8019         # find mirrored files with specific mirror count
8020         cmd="$LFS find --mirror-count 3 --type f $td"
8021         nfiles=$($cmd | wc -l)
8022         [[ $nfiles = 10 ]] || error "$cmd: $nfiles != 10 files"
8023
8024         cmd="$LFS find ! --mirror-count 3 --type f $td"
8025         nfiles=$($cmd | wc -l)
8026         [[ $nfiles = 20 ]] || error "$cmd: $nfiles != 20 files"
8027
8028         cmd="$LFS find --mirror-count +2 --type f $td"
8029         nfiles=$($cmd | wc -l)
8030         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
8031
8032         cmd="$LFS find --mirror-count -6 --type f $td"
8033         nfiles=$($cmd | wc -l)
8034         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
8035
8036         # find mirrored files with specific file state
8037         cmd="$LFS find --maxdepth 1 --mirror-state=^ro --type f $td"
8038         [[ $($cmd) = $tf-6 ]] || error "$cmd: didn't return $tf-6"
8039
8040         cmd="$LFS find --mirror-state=ro --type f $td"
8041         nfiles=$($cmd | wc -l)
8042         [[ $nfiles = 17 ]] || error "$cmd: $nfiles != 17 files"
8043
8044         cmd="$LFS find ! --mirror-state=ro --type f $td"
8045         nfiles=$($cmd | wc -l)
8046         [[ $nfiles = 13 ]] || error "$cmd: $nfiles != 13 files"
8047
8048         cmd="$LFS find --mirror-state=wp --type f $td"
8049         nfiles=$($cmd | wc -l)
8050         [[ $nfiles = 13 ]] || error "$cmd: $nfiles != 13 files"
8051
8052         cmd="$LFS find ! --mirror-state=sp --type f $td"
8053         nfiles=$($cmd | wc -l)
8054         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
8055 }
8056 run_test 56ca "check lfs find --mirror-count|-N and --mirror-state"
8057
8058 test_56da() { # LU-14179
8059         local path=$DIR/$tdir
8060
8061         test_mkdir $path
8062         cd $path
8063
8064         local longdir=$(str_repeat 'a' 255)
8065
8066         for i in {1..15}; do
8067                 path=$path/$longdir
8068                 test_mkdir $longdir
8069                 cd $longdir
8070         done
8071
8072         local len=${#path}
8073         local lastdir=$(str_repeat 'a' $((4096 - 1 - $len - 1)))
8074
8075         test_mkdir $lastdir
8076         cd $lastdir
8077         # PATH_MAX-1
8078         (( ${#PWD} == 4095 )) || error "bad PWD length ${#PWD}, expect 4095"
8079
8080         # NAME_MAX
8081         touch $(str_repeat 'f' 255)
8082
8083         $LFS find $DIR/$tdir --type d |& grep "lfs find: error" &&
8084                 error "lfs find reported an error"
8085
8086         rm -rf $DIR/$tdir
8087 }
8088 run_test 56da "test lfs find with long paths"
8089
8090 test_57a() {
8091         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8092         # note test will not do anything if MDS is not local
8093         if [ "$mds1_FSTYPE" != ldiskfs ]; then
8094                 skip_env "ldiskfs only test"
8095         fi
8096         remote_mds_nodsh && skip "remote MDS with nodsh"
8097
8098         local MNTDEV="osd*.*MDT*.mntdev"
8099         DEV=$(do_facet $SINGLEMDS lctl get_param -n $MNTDEV)
8100         [ -z "$DEV" ] && error "can't access $MNTDEV"
8101         for DEV in $(do_facet $SINGLEMDS lctl get_param -n $MNTDEV); do
8102                 do_facet $SINGLEMDS $DUMPE2FS -h $DEV > $TMP/t57a.dump ||
8103                         error "can't access $DEV"
8104                 DEVISIZE=$(awk '/Inode size:/ { print $3 }' $TMP/t57a.dump)
8105                 [[ $DEVISIZE -gt 128 ]] || error "inode size $DEVISIZE"
8106                 rm $TMP/t57a.dump
8107         done
8108 }
8109 run_test 57a "verify MDS filesystem created with large inodes =="
8110
8111 test_57b() {
8112         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8113         if [ "$mds1_FSTYPE" != ldiskfs ]; then
8114                 skip_env "ldiskfs only test"
8115         fi
8116         remote_mds_nodsh && skip "remote MDS with nodsh"
8117
8118         local dir=$DIR/$tdir
8119         local filecount=100
8120         local file1=$dir/f1
8121         local fileN=$dir/f$filecount
8122
8123         rm -rf $dir || error "removing $dir"
8124         test_mkdir -c1 $dir
8125         local mdtidx=$($LFS getstripe -m $dir)
8126         local mdtname=MDT$(printf %04x $mdtidx)
8127         local facet=mds$((mdtidx + 1))
8128
8129         echo "mcreating $filecount files"
8130         createmany -m $dir/f 1 $filecount || error "creating files in $dir"
8131
8132         # verify that files do not have EAs yet
8133         $LFS getstripe $file1 2>&1 | grep -q "no stripe" ||
8134                 error "$file1 has an EA"
8135         $LFS getstripe $fileN 2>&1 | grep -q "no stripe" ||
8136                 error "$fileN has an EA"
8137
8138         sync
8139         sleep 1
8140         df $dir  #make sure we get new statfs data
8141         local mdsfree=$(do_facet $facet \
8142                         lctl get_param -n osd*.*$mdtname.kbytesfree)
8143         local mdcfree=$(lctl get_param -n mdc.*$mdtname-mdc-*.kbytesfree)
8144         local file
8145
8146         echo "opening files to create objects/EAs"
8147         for file in $(seq -f $dir/f%g 1 $filecount); do
8148                 $OPENFILE -f O_RDWR $file > /dev/null 2>&1 ||
8149                         error "opening $file"
8150         done
8151
8152         # verify that files have EAs now
8153         $LFS getstripe $file1 | grep -q "obdidx" || error "$file1 missing EA"
8154         $LFS getstripe $fileN | grep -q "obdidx" || error "$fileN missing EA"
8155
8156         sleep 1  #make sure we get new statfs data
8157         df $dir
8158         local mdsfree2=$(do_facet $facet \
8159                          lctl get_param -n osd*.*$mdtname.kbytesfree)
8160         local mdcfree2=$(lctl get_param -n mdc.*$mdtname-mdc-*.kbytesfree)
8161
8162         if [[ $mdcfree2 -lt $((mdcfree - 16)) ]]; then
8163                 if [ "$mdsfree" != "$mdsfree2" ]; then
8164                         error "MDC before $mdcfree != after $mdcfree2"
8165                 else
8166                         echo "MDC before $mdcfree != after $mdcfree2"
8167                         echo "unable to confirm if MDS has large inodes"
8168                 fi
8169         fi
8170         rm -rf $dir
8171 }
8172 run_test 57b "default LOV EAs are stored inside large inodes ==="
8173
8174 test_58() {
8175         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8176         [ -z "$(which wiretest 2>/dev/null)" ] &&
8177                         skip_env "could not find wiretest"
8178
8179         wiretest
8180 }
8181 run_test 58 "verify cross-platform wire constants =============="
8182
8183 test_59() {
8184         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8185
8186         echo "touch 130 files"
8187         createmany -o $DIR/f59- 130
8188         echo "rm 130 files"
8189         unlinkmany $DIR/f59- 130
8190         sync
8191         # wait for commitment of removal
8192         wait_delete_completed
8193 }
8194 run_test 59 "verify cancellation of llog records async ========="
8195
8196 TEST60_HEAD="test_60 run $RANDOM"
8197 test_60a() {
8198         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8199         remote_mgs_nodsh && skip "remote MGS with nodsh"
8200         do_facet mgs "! which run-llog.sh &> /dev/null" &&
8201                 do_facet mgs "! ls run-llog.sh &> /dev/null" &&
8202                         skip_env "missing subtest run-llog.sh"
8203
8204         log "$TEST60_HEAD - from kernel mode"
8205         do_facet mgs "$LCTL dk > /dev/null"
8206         do_facet mgs "bash run-llog.sh" || error "run-llog.sh failed"
8207         do_facet mgs $LCTL dk > $TMP/$tfile
8208
8209         # LU-6388: test llog_reader
8210         local llog_reader=$(do_facet mgs "which llog_reader 2> /dev/null")
8211         llog_reader=${llog_reader:-$LUSTRE/utils/llog_reader}
8212         [ -z $(do_facet mgs ls -d $llog_reader 2> /dev/null) ] &&
8213                         skip_env "missing llog_reader"
8214         local fstype=$(facet_fstype mgs)
8215         [ $fstype != ldiskfs -a $fstype != zfs ] &&
8216                 skip_env "Only for ldiskfs or zfs type mgs"
8217
8218         local mntpt=$(facet_mntpt mgs)
8219         local mgsdev=$(mgsdevname 1)
8220         local fid_list
8221         local fid
8222         local rec_list
8223         local rec
8224         local rec_type
8225         local obj_file
8226         local path
8227         local seq
8228         local oid
8229         local pass=true
8230
8231         #get fid and record list
8232         fid_list=($(awk '/9_sub.*record/ { print $NF }' $TMP/$tfile |
8233                 tail -n 4))
8234         rec_list=($(awk '/9_sub.*record/ { print $((NF-3)) }' $TMP/$tfile |
8235                 tail -n 4))
8236         #remount mgs as ldiskfs or zfs type
8237         stop mgs || error "stop mgs failed"
8238         mount_fstype mgs || error "remount mgs failed"
8239         for ((i = 0; i < ${#fid_list[@]}; i++)); do
8240                 fid=${fid_list[i]}
8241                 rec=${rec_list[i]}
8242                 seq=$(echo $fid | awk -F ':' '{ print $1 }' | sed -e "s/^0x//g")
8243                 oid=$(echo $fid | awk -F ':' '{ print $2 }' | sed -e "s/^0x//g")
8244                 oid=$((16#$oid))
8245
8246                 case $fstype in
8247                         ldiskfs )
8248                                 obj_file=$mntpt/O/$seq/d$((oid%32))/$oid ;;
8249                         zfs )
8250                                 obj_file=$mntpt/oi.$(($((16#$seq))&127))/$fid ;;
8251                 esac
8252                 echo "obj_file is $obj_file"
8253                 do_facet mgs $llog_reader $obj_file
8254
8255                 rec_type=$(do_facet mgs $llog_reader $obj_file | grep "type=" |
8256                         awk '{ print $3 }' | sed -e "s/^type=//g")
8257                 if [ $rec_type != $rec ]; then
8258                         echo "FAILED test_60a wrong record type $rec_type," \
8259                               "should be $rec"
8260                         pass=false
8261                         break
8262                 fi
8263
8264                 #check obj path if record type is LLOG_LOGID_MAGIC
8265                 if [ "$rec" == "1064553b" ]; then
8266                         path=$(do_facet mgs $llog_reader $obj_file |
8267                                 grep "path=" | awk '{ print $NF }' |
8268                                 sed -e "s/^path=//g")
8269                         if [ $obj_file != $mntpt/$path ]; then
8270                                 echo "FAILED test_60a wrong obj path" \
8271                                       "$montpt/$path, should be $obj_file"
8272                                 pass=false
8273                                 break
8274                         fi
8275                 fi
8276         done
8277         rm -f $TMP/$tfile
8278         #restart mgs before "error", otherwise it will block the next test
8279         stop mgs || error "stop mgs failed"
8280         start mgs $(mgsdevname) $MGS_MOUNT_OPTS || error "start mgs failed"
8281         $pass || error "test failed, see FAILED test_60a messages for specifics"
8282 }
8283 run_test 60a "llog_test run from kernel module and test llog_reader"
8284
8285 test_60b() { # bug 6411
8286         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8287
8288         dmesg > $DIR/$tfile
8289         LLOG_COUNT=$(do_facet mgs dmesg |
8290                      awk "/$TEST60_HEAD/ { marker = 1; from_marker = 0; }
8291                           /llog_[a-z]*.c:[0-9]/ {
8292                                 if (marker)
8293                                         from_marker++
8294                                 from_begin++
8295                           }
8296                           END {
8297                                 if (marker)
8298                                         print from_marker
8299                                 else
8300                                         print from_begin
8301                           }")
8302
8303         [[ $LLOG_COUNT -gt 120 ]] &&
8304                 error "CDEBUG_LIMIT not limiting messages ($LLOG_COUNT)" || true
8305 }
8306 run_test 60b "limit repeated messages from CERROR/CWARN"
8307
8308 test_60c() {
8309         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8310
8311         echo "create 5000 files"
8312         createmany -o $DIR/f60c- 5000
8313 #define OBD_FAIL_MDS_LLOG_CREATE_FAILED  0x137
8314         lctl set_param fail_loc=0x80000137
8315         unlinkmany $DIR/f60c- 5000
8316         lctl set_param fail_loc=0
8317 }
8318 run_test 60c "unlink file when mds full"
8319
8320 test_60d() {
8321         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8322
8323         SAVEPRINTK=$(lctl get_param -n printk)
8324         # verify "lctl mark" is even working"
8325         MESSAGE="test message ID $RANDOM $$"
8326         $LCTL mark "$MESSAGE" || error "$LCTL mark failed"
8327         dmesg | grep -q "$MESSAGE" || error "didn't find debug marker in log"
8328
8329         lctl set_param printk=0 || error "set lnet.printk failed"
8330         lctl get_param -n printk | grep emerg || error "lnet.printk dropped emerg"
8331         MESSAGE="new test message ID $RANDOM $$"
8332         # Assume here that libcfs_debug_mark_buffer() uses D_WARNING
8333         $LCTL mark "$MESSAGE" || error "$LCTL mark failed"
8334         dmesg | grep -q "$MESSAGE" && error "D_WARNING wasn't masked" || true
8335
8336         lctl set_param -n printk="$SAVEPRINTK"
8337 }
8338 run_test 60d "test printk console message masking"
8339
8340 test_60e() {
8341         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8342         remote_mds_nodsh && skip "remote MDS with nodsh"
8343
8344         touch $DIR/$tfile
8345 #define OBD_FAIL_MDS_LLOG_CREATE_FAILED2  0x15b
8346         do_facet mds1 lctl set_param fail_loc=0x15b
8347         rm $DIR/$tfile
8348 }
8349 run_test 60e "no space while new llog is being created"
8350
8351 test_60f() {
8352         local old_path=$($LCTL get_param -n debug_path)
8353
8354         stack_trap "$LCTL set_param debug_path=$old_path"
8355         stack_trap "rm -f $TMP/$tfile*"
8356         rm -f $TMP/$tfile* 2> /dev/null
8357         #define OBD_FAIL_PTLRPC_DUMP_LOG         0x50e
8358         $LCTL set_param debug_path=$TMP/$tfile fail_loc=0x8000050e
8359         test_mkdir $DIR/$tdir
8360         # retry in case the open is cached and not released
8361         for (( i = 0; i < 100 && $(ls $TMP/$tfile* | wc -l) == 0; i++ )); do
8362                 echo $i > $DIR/$tdir/$tfile.$i && cat $DIR/$tdir/$tfile.$i
8363                 sleep 0.1
8364         done
8365         ls $TMP/$tfile*
8366         (( $(ls $TMP/$tfile* | wc -l) > 0 )) || error "$TMP/$tfile not dumped"
8367 }
8368 run_test 60f "change debug_path works"
8369
8370 test_60g() {
8371         local pid
8372         local i
8373
8374         test_mkdir -c $MDSCOUNT $DIR/$tdir
8375
8376         (
8377                 local index=0
8378                 while true; do
8379                         $LFS setdirstripe -i $(($index % $MDSCOUNT)) \
8380                                 -c $MDSCOUNT $DIR/$tdir/subdir$index \
8381                                 2>/dev/null
8382                         mkdir $DIR/$tdir/subdir$index 2>/dev/null
8383                         rmdir $DIR/$tdir/subdir$index 2>/dev/null
8384                         index=$((index + 1))
8385                 done
8386         ) &
8387
8388         pid=$!
8389
8390         for i in {0..100}; do
8391                 # define OBD_FAIL_OSD_TXN_START    0x19a
8392                 local index=$((i % MDSCOUNT + 1))
8393
8394                 do_facet mds$index $LCTL set_param fail_loc=0x8000019a \
8395                         > /dev/null
8396                 sleep 0.01
8397         done
8398
8399         kill -9 $pid
8400
8401         for i in $(seq $MDSCOUNT); do
8402                 do_facet mds$i $LCTL set_param fail_loc=0 > /dev/null
8403         done
8404
8405         mkdir $DIR/$tdir/new || error "mkdir failed"
8406         rmdir $DIR/$tdir/new || error "rmdir failed"
8407
8408         do_facet mds1 $LCTL lfsck_start -M $(facet_svc mds1) -A -C \
8409                 -t namespace
8410         for i in $(seq $MDSCOUNT); do
8411                 wait_update_facet mds$i "$LCTL get_param -n \
8412                         mdd.$(facet_svc mds$i).lfsck_namespace |
8413                         awk '/^status/ { print \\\$2 }'" "completed"
8414         done
8415
8416         ls -R $DIR/$tdir || error "ls failed"
8417         rm -rf $DIR/$tdir || error "rmdir failed"
8418 }
8419 run_test 60g "transaction abort won't cause MDT hung"
8420
8421 test_60h() {
8422         [ $MDS1_VERSION -le $(version_code 2.12.52) ] &&
8423                 skip "Need MDS version at least 2.12.52"
8424         [ $MDSCOUNT -lt 2 ] && skip "Need at least 2 MDTs"
8425
8426         local f
8427
8428         #define OBD_FAIL_MDS_STRIPE_CREATE       0x188
8429         #define OBD_FAIL_MDS_STRIPE_FID          0x189
8430         for fail_loc in 0x80000188 0x80000189; do
8431                 do_facet mds1 "$LCTL set_param fail_loc=$fail_loc"
8432                 $LFS mkdir -c $MDSCOUNT -i 0 $DIR/$tdir-$fail_loc ||
8433                         error "mkdir $dir-$fail_loc failed"
8434                 for i in {0..10}; do
8435                         # create may fail on missing stripe
8436                         echo $i > $DIR/$tdir-$fail_loc/$i
8437                 done
8438                 $LFS getdirstripe $DIR/$tdir-$fail_loc ||
8439                         error "getdirstripe $tdir-$fail_loc failed"
8440                 $LFS migrate -m 1 $DIR/$tdir-$fail_loc ||
8441                         error "migrate $tdir-$fail_loc failed"
8442                 $LFS getdirstripe $DIR/$tdir-$fail_loc ||
8443                         error "getdirstripe $tdir-$fail_loc failed"
8444                 pushd $DIR/$tdir-$fail_loc
8445                 for f in *; do
8446                         echo $f | cmp $f - || error "$f data mismatch"
8447                 done
8448                 popd
8449                 rm -rf $DIR/$tdir-$fail_loc
8450         done
8451 }
8452 run_test 60h "striped directory with missing stripes can be accessed"
8453
8454 function t60i_load() {
8455         mkdir $DIR/$tdir
8456         #define OBD_FAIL_LLOG_PAUSE_AFTER_PAD               0x131c
8457         $LCTL set_param fail_loc=0x131c fail_val=1
8458         for ((i=0; i<5000; i++)); do
8459                 touch $DIR/$tdir/f$i
8460         done
8461 }
8462
8463 test_60i() {
8464         changelog_register || error "changelog_register failed"
8465         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
8466         changelog_users $SINGLEMDS | grep -q $cl_user ||
8467                 error "User $cl_user not found in changelog_users"
8468         changelog_chmask "ALL"
8469         t60i_load &
8470         local PID=$!
8471         for((i=0; i<100; i++)); do
8472                 changelog_dump >/dev/null ||
8473                         error "can't read changelog"
8474         done
8475         kill $PID
8476         wait $PID
8477         changelog_deregister || error "changelog_deregister failed"
8478         $LCTL set_param fail_loc=0
8479 }
8480 run_test 60i "llog: new record vs reader race"
8481
8482 test_61a() {
8483         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8484
8485         f="$DIR/f61"
8486         dd if=/dev/zero of=$f bs=$PAGE_SIZE count=1 || error "dd $f failed"
8487         cancel_lru_locks osc
8488         $MULTIOP $f OSMWUc || error "$MULTIOP $f failed"
8489         sync
8490 }
8491 run_test 61a "mmap() writes don't make sync hang ================"
8492
8493 test_61b() {
8494         mmap_mknod_test $DIR/$tfile || error "mmap_mknod_test failed"
8495 }
8496 run_test 61b "mmap() of unstriped file is successful"
8497
8498 # bug 2330 - insufficient obd_match error checking causes LBUG
8499 test_62() {
8500         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8501
8502         f="$DIR/f62"
8503         echo foo > $f
8504         cancel_lru_locks osc
8505         lctl set_param fail_loc=0x405
8506         cat $f && error "cat succeeded, expect -EIO"
8507         lctl set_param fail_loc=0
8508 }
8509 # This test is now irrelevant (as of bug 10718 inclusion), we no longer
8510 # match every page all of the time.
8511 #run_test 62 "verify obd_match failure doesn't LBUG (should -EIO)"
8512
8513 # bug 2319 - oig_wait() interrupted causes crash because of invalid waitq.
8514 # Though this test is irrelevant anymore, it helped to reveal some
8515 # other grant bugs (LU-4482), let's keep it.
8516 test_63a() {   # was test_63
8517         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8518
8519         MAX_DIRTY_MB=$(lctl get_param -n osc.*.max_dirty_mb | head -n 1)
8520
8521         for i in `seq 10` ; do
8522                 dd if=/dev/zero of=$DIR/f63 bs=8k &
8523                 sleep 5
8524                 kill $!
8525                 sleep 1
8526         done
8527
8528         rm -f $DIR/f63 || true
8529 }
8530 run_test 63a "Verify oig_wait interruption does not crash ======="
8531
8532 # bug 2248 - async write errors didn't return to application on sync
8533 # bug 3677 - async write errors left page locked
8534 test_63b() {
8535         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8536
8537         debugsave
8538         lctl set_param debug=-1
8539
8540         # ensure we have a grant to do async writes
8541         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1
8542         rm $DIR/$tfile
8543
8544         sync    # sync lest earlier test intercept the fail_loc
8545
8546         #define OBD_FAIL_OSC_BRW_PREP_REQ        0x406
8547         lctl set_param fail_loc=0x80000406
8548         $MULTIOP $DIR/$tfile Owy && \
8549                 error "sync didn't return ENOMEM"
8550         sync; sleep 2; sync     # do a real sync this time to flush page
8551         lctl get_param -n llite.*.dump_page_cache | grep locked && \
8552                 error "locked page left in cache after async error" || true
8553         debugrestore
8554 }
8555 run_test 63b "async write errors should be returned to fsync ==="
8556
8557 test_64a () {
8558         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8559
8560         lfs df $DIR
8561         lctl get_param osc.*[oO][sS][cC][_-]*.cur* | grep "=[1-9]"
8562 }
8563 run_test 64a "verify filter grant calculations (in kernel) ====="
8564
8565 test_64b () {
8566         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8567
8568         sh oos.sh $MOUNT || error "oos.sh failed: $?"
8569 }
8570 run_test 64b "check out-of-space detection on client"
8571
8572 test_64c() {
8573         $LCTL set_param osc.*OST0000-osc-[^mM]*.cur_grant_bytes=0
8574 }
8575 run_test 64c "verify grant shrink"
8576
8577 import_param() {
8578         local tgt=$1
8579         local param=$2
8580
8581         $LCTL get_param osc.$tgt.import | awk "/$param/ { print \$2 }"
8582 }
8583
8584 # this does exactly what osc_request.c:osc_announce_cached() does in
8585 # order to calculate max amount of grants to ask from server
8586 want_grant() {
8587         local tgt=$1
8588
8589         local nrpages=$($LCTL get_param -n osc.$tgt.max_pages_per_rpc)
8590         local rpc_in_flight=$($LCTL get_param -n osc.$tgt.max_rpcs_in_flight)
8591
8592         ((rpc_in_flight++));
8593         nrpages=$((nrpages * rpc_in_flight))
8594
8595         local dirty_max_pages=$($LCTL get_param -n osc.$tgt.max_dirty_mb)
8596
8597         dirty_max_pages=$((dirty_max_pages * 1024 * 1024 / PAGE_SIZE))
8598
8599         [[ $dirty_max_pages -gt $nrpages ]] && nrpages=$dirty_max_pages
8600         local undirty=$((nrpages * PAGE_SIZE))
8601
8602         local max_extent_pages
8603         max_extent_pages=$(import_param $tgt grant_max_extent_size)
8604         max_extent_pages=$((max_extent_pages / PAGE_SIZE))
8605         local nrextents=$(((nrpages + max_extent_pages - 1) / max_extent_pages))
8606         local grant_extent_tax
8607         grant_extent_tax=$(import_param $tgt grant_extent_tax)
8608
8609         undirty=$((undirty + nrextents * grant_extent_tax))
8610
8611         echo $undirty
8612 }
8613
8614 # this is size of unit for grant allocation. It should be equal to
8615 # what tgt_grant.c:tgt_grant_chunk() calculates
8616 grant_chunk() {
8617         local tgt=$1
8618         local max_brw_size
8619         local grant_extent_tax
8620
8621         max_brw_size=$(import_param $tgt max_brw_size)
8622
8623         grant_extent_tax=$(import_param $tgt grant_extent_tax)
8624
8625         echo $(((max_brw_size + grant_extent_tax) * 2))
8626 }
8627
8628 test_64d() {
8629         [ $OST1_VERSION -ge $(version_code 2.10.56) ] ||
8630                 skip "OST < 2.10.55 doesn't limit grants enough"
8631
8632         local tgt=$($LCTL dl | awk '/OST0000-osc-[^mM]/ { print $4 }')
8633
8634         [[ "$($LCTL get_param osc.${tgt}.import)" =~ "grant_param" ]] ||
8635                 skip "no grant_param connect flag"
8636
8637         local olddebug="$($LCTL get_param -n debug 2> /dev/null)"
8638
8639         $LCTL set_param -n -n debug="$OLDDEBUG" || true
8640         stack_trap "$LCTL set_param -n debug='$olddebug'" EXIT
8641
8642
8643         local max_cur_granted=$(($(want_grant $tgt) + $(grant_chunk $tgt)))
8644         stack_trap "rm -f $DIR/$tfile && wait_delete_completed" EXIT
8645
8646         $LFS setstripe $DIR/$tfile -i 0 -c 1
8647         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1000 &
8648         ddpid=$!
8649
8650         while kill -0 $ddpid; do
8651                 local cur_grant=$($LCTL get_param -n osc.$tgt.cur_grant_bytes)
8652
8653                 if [[ $cur_grant -gt $max_cur_granted ]]; then
8654                         kill $ddpid
8655                         error "cur_grant $cur_grant > $max_cur_granted"
8656                 fi
8657
8658                 sleep 1
8659         done
8660 }
8661 run_test 64d "check grant limit exceed"
8662
8663 check_grants() {
8664         local tgt=$1
8665         local expected=$2
8666         local msg=$3
8667         local cur_grants=$($LCTL get_param -n osc.$tgt.cur_grant_bytes)
8668
8669         ((cur_grants == expected)) ||
8670                 error "$msg: grants mismatch: $cur_grants, expected $expected"
8671 }
8672
8673 round_up_p2() {
8674         echo $((($1 + $2 - 1) & ~($2 - 1)))
8675 }
8676
8677 test_64e() {
8678         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8679         [ $OST1_VERSION -ge $(version_code 2.11.56) ] ||
8680                 skip "Need OSS version at least 2.11.56"
8681
8682         # Remount client to reset grant
8683         remount_client $MOUNT || error "failed to remount client"
8684         local osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
8685
8686         local init_grants=$(import_param $osc_tgt initial_grant)
8687
8688         check_grants $osc_tgt $init_grants "init grants"
8689
8690         local extent_tax=$(import_param $osc_tgt grant_extent_tax)
8691         local max_brw_size=$(import_param $osc_tgt max_brw_size)
8692         local gbs=$(import_param $osc_tgt grant_block_size)
8693
8694         # write random number of bytes from max_brw_size / 4 to max_brw_size
8695         local write_bytes=$(shuf -i $((max_brw_size / 4))-$max_brw_size -n 1)
8696         # align for direct io
8697         write_bytes=$(round_up_p2 $write_bytes PAGE_SIZE)
8698         # round to grant consumption unit
8699         local wb_round_up=$(round_up_p2 $write_bytes gbs)
8700
8701         local grants=$((wb_round_up + extent_tax))
8702
8703         $LFS setstripe -c 1 -i 0 $DIR/$tfile  || error "lfs setstripe failed"
8704
8705         # define OBD_FAIL_TGT_NO_GRANT 0x725
8706         # make the server not grant more back
8707         do_facet ost1 $LCTL set_param fail_loc=0x725
8708         dd if=/dev/zero of=$DIR/$tfile bs=$write_bytes count=1 oflag=direct
8709
8710         do_facet ost1 $LCTL set_param fail_loc=0
8711
8712         check_grants $osc_tgt $((init_grants - grants)) "dio w/o grant alloc"
8713
8714         rm -f $DIR/$tfile || error "rm failed"
8715
8716         # Remount client to reset grant
8717         remount_client $MOUNT || error "failed to remount client"
8718         osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
8719
8720         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "lfs setstripe failed"
8721
8722         # define OBD_FAIL_TGT_NO_GRANT 0x725
8723         # make the server not grant more back
8724         do_facet ost1 $LCTL set_param fail_loc=0x725
8725         $MULTIOP $DIR/$tfile "oO_WRONLY:w${write_bytes}yc"
8726         do_facet ost1 $LCTL set_param fail_loc=0
8727
8728         check_grants $osc_tgt $((init_grants - grants)) "buf io w/o grant alloc"
8729 }
8730 run_test 64e "check grant consumption (no grant allocation)"
8731
8732 test_64f() {
8733         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8734
8735         # Remount client to reset grant
8736         remount_client $MOUNT || error "failed to remount client"
8737         local osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
8738
8739         local init_grants=$(import_param $osc_tgt initial_grant)
8740         local extent_tax=$(import_param $osc_tgt grant_extent_tax)
8741         local max_brw_size=$(import_param $osc_tgt max_brw_size)
8742         local gbs=$(import_param $osc_tgt grant_block_size)
8743         local chunk=$(grant_chunk $osc_tgt)
8744
8745         # write random number of bytes from max_brw_size / 4 to max_brw_size
8746         local write_bytes=$(shuf -i $((max_brw_size / 4))-$max_brw_size -n 1)
8747         # align for direct io
8748         write_bytes=$(round_up_p2 $write_bytes PAGE_SIZE)
8749         # round to grant consumption unit
8750         local wb_round_up=$(round_up_p2 $write_bytes gbs)
8751
8752         local grants=$((wb_round_up + extent_tax))
8753
8754         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "lfs setstripe failed"
8755         dd if=/dev/zero of=$DIR/$tfile bs=$write_bytes count=1 oflag=direct ||
8756                 error "error writing to $DIR/$tfile"
8757
8758         check_grants $osc_tgt $((init_grants - grants + chunk)) \
8759                 "direct io with grant allocation"
8760
8761         rm -f $DIR/$tfile || error "rm failed"
8762
8763         # Remount client to reset grant
8764         remount_client $MOUNT || error "failed to remount client"
8765         osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
8766
8767         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "lfs setstripe failed"
8768
8769         local cmd="oO_WRONLY:w${write_bytes}_yc"
8770
8771         $MULTIOP $DIR/$tfile $cmd &
8772         MULTIPID=$!
8773         sleep 1
8774
8775         check_grants $osc_tgt $((init_grants - grants)) \
8776                 "buffered io, not write rpc"
8777
8778         kill -USR1 $MULTIPID
8779         wait
8780
8781         check_grants $osc_tgt $((init_grants - grants + chunk)) \
8782                 "buffered io, one RPC"
8783 }
8784 run_test 64f "check grant consumption (with grant allocation)"
8785
8786 test_64g() {
8787         #[ $MDS1_VERSION -lt $(version_code 2.14.54) ] &&
8788         #       skip "Need MDS version at least 2.14.54"
8789
8790         local mdts=$(comma_list $(mdts_nodes))
8791
8792         local old=$($LCTL get_param mdc.$FSNAME-*.grant_shrink_interval |
8793                         tr '\n' ' ')
8794         stack_trap "$LCTL set_param $old"
8795
8796         # generate dirty pages and increase dirty granted on MDT
8797         stack_trap "rm -f $DIR/$tfile-*"
8798         for (( i = 0; i < 10; i++)); do
8799                 $LFS setstripe -E 1M -L mdt $DIR/$tfile-$i ||
8800                         error "can't set stripe"
8801                 dd if=/dev/zero of=$DIR/$tfile-$i bs=128k count=1 ||
8802                         error "can't dd"
8803                 $LFS getstripe $DIR/$tfile-$i | grep -q pattern.*mdt || {
8804                         $LFS getstripe $DIR/$tfile-$i
8805                         error "not DoM file"
8806                 }
8807         done
8808
8809         # flush dirty pages
8810         sync
8811
8812         # wait until grant shrink reset grant dirty on MDTs
8813         for ((i = 0; i < 120; i++)); do
8814                 grant_dirty=$(do_nodes $mdts $LCTL get_param -n  mdt.*.tot_dirty |
8815                         awk '{sum=sum+$1} END {print sum}')
8816                 vm_dirty=$(awk '/Dirty:/{print $2}' /proc/meminfo)
8817                 echo "$grant_dirty grants, $vm_dirty pages"
8818                 (( grant_dirty + vm_dirty == 0 )) && break
8819                 (( i == 3 )) && sync &&
8820                         $LCTL set_param mdc.$FSNAME-*.grant_shrink_interval=5
8821                 sleep 1
8822         done
8823
8824         grant_dirty=$(do_nodes $mdts $LCTL get_param -n  mdt.*.tot_dirty |
8825                 awk '{sum=sum+$1} END {print sum}')
8826         (( grant_dirty == 0 )) || error "$grant_dirty on MDT"
8827 }
8828 run_test 64g "grant shrink on MDT"
8829
8830 test_64h() {
8831         local instance=$($LFS getname -i $DIR)
8832         local osc_tgt="$FSNAME-OST0000-osc-$instance"
8833         local num_exps=$(do_facet ost1 \
8834             $LCTL get_param -n obdfilter.*OST0000*.num_exports)
8835         local max_brw_size=$(import_param $osc_tgt max_brw_size)
8836         local avail=$($LCTL get_param -n osc.*OST0000-osc-$instance.kbytesavail)
8837         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
8838
8839         # 10MiB is for file to be written, max_brw_size * 16 *
8840         # num_exps is space reserve so that tgt_grant_shrink() decided
8841         # to not shrink
8842         local expect=$((max_brw_size * 16 * num_exps + 10 * 1048576))
8843         (( avail * 1024 < expect )) &&
8844                 skip "need $expect bytes on ost1, have $(( avail * 1024 )) only"
8845
8846         save_lustre_params client "osc.*OST0000*.grant_shrink" > $p
8847         save_lustre_params client "osc.*OST0000*.grant_shrink_interval" >> $p
8848         stack_trap "restore_lustre_params < $p; rm -f $save" EXIT
8849         $LCTL set_param osc.*OST0000*.grant_shrink=1
8850         $LCTL set_param osc.*OST0000*.grant_shrink_interval=10
8851
8852         $LFS setstripe -c 1 -i 0 $DIR/$tfile
8853         dd if=/dev/zero of=$DIR/$tfile bs=1M count=10 oflag=sync
8854
8855         # drop cache so that coming read would do rpc
8856         cancel_lru_locks osc
8857
8858         # shrink interval is set to 10, pause for 7 seconds so that
8859         # grant thread did not wake up yet but coming read entered
8860         # shrink mode for rpc (osc_should_shrink_grant())
8861         sleep 7
8862
8863         declare -a cur_grant_bytes
8864         declare -a tot_granted
8865         cur_grant_bytes[0]=$($LCTL get_param -n osc.*OST0000*.cur_grant_bytes)
8866         tot_granted[0]=$(do_facet ost1 \
8867             $LCTL get_param -n obdfilter.*OST0000*.tot_granted)
8868
8869         dd if=$DIR/$tfile bs=4K count=1 of=/dev/null
8870
8871         cur_grant_bytes[1]=$($LCTL get_param -n osc.*OST0000*.cur_grant_bytes)
8872         tot_granted[1]=$(do_facet ost1 \
8873             $LCTL get_param -n obdfilter.*OST0000*.tot_granted)
8874
8875         # grant change should be equal on both sides
8876         (( cur_grant_bytes[0] - cur_grant_bytes[1] ==
8877                 tot_granted[0] - tot_granted[1])) ||
8878                 error "grant change mismatch, "                                \
8879                         "server: ${tot_granted[0]} to ${tot_granted[1]}, "     \
8880                         "client: ${cur_grant_bytes[0]} to ${cur_grant_bytes[1]}"
8881 }
8882 run_test 64h "grant shrink on read"
8883
8884 test_64i() {
8885         (( $OST1_VERSION >= $(version_code 2.14.55) )) ||
8886                 skip "need OST at least 2.14.55 to avoid grant shrink on replay"
8887
8888         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8889         remote_ost_nodsh && skip "remote OSTs with nodsh"
8890
8891         $LFS setstripe -c 1 -i 0 $DIR/$tfile
8892
8893         dd if=/dev/zero of=$DIR/$tfile bs=1M count=64
8894
8895         # lustre-ffff9fc75e850800 /mnt/lustre -> ffff9fc75e850800
8896         local instance=$($LFS getname -i $DIR)
8897
8898         local osc_tgt="$FSNAME-OST0000-osc-$instance"
8899         local cgb=$($LCTL get_param -n osc.$osc_tgt.cur_grant_bytes)
8900
8901         # shrink grants and simulate rpc loss
8902         #define OBD_FAIL_PTLRPC_DROP_REQ_OPC     0x513
8903         do_facet ost1 "$LCTL set_param fail_loc=0x80000513 fail_val=17"
8904         $LCTL set_param osc.$osc_tgt.cur_grant_bytes=$((cgb/2))B
8905
8906         fail ost1
8907
8908         dd if=/dev/zero of=$DIR/$tfile oflag=append bs=1M count=8 conv=notrunc
8909
8910         local testid=$(echo $TESTNAME | tr '_' ' ')
8911
8912         do_facet ost1 dmesg | tac | sed "/$testid/,$ d" |
8913                 grep "GRANT, real grant" &&
8914                 error "client has more grants then it owns" || true
8915 }
8916 run_test 64i "shrink on reconnect"
8917
8918 # bug 1414 - set/get directories' stripe info
8919 test_65a() {
8920         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8921
8922         test_mkdir $DIR/$tdir
8923         touch $DIR/$tdir/f1
8924         $LVERIFY $DIR/$tdir $DIR/$tdir/f1 || error "lverify failed"
8925 }
8926 run_test 65a "directory with no stripe info"
8927
8928 test_65b() {
8929         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8930
8931         test_mkdir $DIR/$tdir
8932         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
8933
8934         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
8935                                                 error "setstripe"
8936         touch $DIR/$tdir/f2
8937         $LVERIFY $DIR/$tdir $DIR/$tdir/f2 || error "lverify failed"
8938 }
8939 run_test 65b "directory setstripe -S stripe_size*2 -i 0 -c 1"
8940
8941 test_65c() {
8942         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8943         [ $OSTCOUNT -lt 2 ] && skip_env "need at least 2 OSTs"
8944
8945         test_mkdir $DIR/$tdir
8946         local stripesize=$($LFS getstripe -S $DIR/$tdir)
8947
8948         $LFS setstripe -S $((stripesize * 4)) -i 1 \
8949                 -c $((OSTCOUNT - 1)) $DIR/$tdir || error "setstripe"
8950         touch $DIR/$tdir/f3
8951         $LVERIFY $DIR/$tdir $DIR/$tdir/f3 || error "lverify failed"
8952 }
8953 run_test 65c "directory setstripe -S stripe_size*4 -i 1 -c $((OSTCOUNT-1))"
8954
8955 test_65d() {
8956         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8957
8958         test_mkdir $DIR/$tdir
8959         local STRIPECOUNT=$($LFS getstripe -c $DIR/$tdir)
8960         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
8961
8962         if [[ $STRIPECOUNT -le 0 ]]; then
8963                 sc=1
8964         elif [[ $STRIPECOUNT -gt $LOV_MAX_STRIPE_COUNT ]]; then
8965                 [[ $OSTCOUNT -gt $LOV_MAX_STRIPE_COUNT ]] &&
8966                         sc=$LOV_MAX_STRIPE_COUNT || sc=$(($OSTCOUNT - 1))
8967         else
8968                 sc=$(($STRIPECOUNT - 1))
8969         fi
8970         $LFS setstripe -S $STRIPESIZE -c $sc $DIR/$tdir || error "setstripe"
8971         touch $DIR/$tdir/f4 $DIR/$tdir/f5
8972         $LVERIFY $DIR/$tdir $DIR/$tdir/f4 $DIR/$tdir/f5 ||
8973                 error "lverify failed"
8974 }
8975 run_test 65d "directory setstripe -S stripe_size -c stripe_count"
8976
8977 test_65e() {
8978         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8979
8980         test_mkdir $DIR/$tdir
8981
8982         $LFS setstripe $DIR/$tdir || error "setstripe"
8983         $LFS getstripe -v $DIR/$tdir | grep "Default" ||
8984                                         error "no stripe info failed"
8985         touch $DIR/$tdir/f6
8986         $LVERIFY $DIR/$tdir $DIR/$tdir/f6 || error "lverify failed"
8987 }
8988 run_test 65e "directory setstripe defaults"
8989
8990 test_65f() {
8991         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8992
8993         test_mkdir $DIR/${tdir}f
8994         $RUNAS $LFS setstripe $DIR/${tdir}f &&
8995                 error "setstripe succeeded" || true
8996 }
8997 run_test 65f "dir setstripe permission (should return error) ==="
8998
8999 test_65g() {
9000         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9001
9002         test_mkdir $DIR/$tdir
9003         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
9004
9005         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
9006                 error "setstripe -S failed"
9007         $LFS setstripe -d $DIR/$tdir || error "setstripe -d failed"
9008         $LFS getstripe -v $DIR/$tdir | grep "Default" ||
9009                 error "delete default stripe failed"
9010 }
9011 run_test 65g "directory setstripe -d"
9012
9013 test_65h() {
9014         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9015
9016         test_mkdir $DIR/$tdir
9017         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
9018
9019         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
9020                 error "setstripe -S failed"
9021         test_mkdir $DIR/$tdir/dd1
9022         [ $($LFS getstripe -c $DIR/$tdir) = $($LFS getstripe -c $DIR/$tdir/dd1) ] ||
9023                 error "stripe info inherit failed"
9024 }
9025 run_test 65h "directory stripe info inherit ===================="
9026
9027 test_65i() {
9028         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9029
9030         save_layout_restore_at_exit $MOUNT
9031
9032         # bug6367: set non-default striping on root directory
9033         $LFS setstripe -S 65536 -c -1 $MOUNT || error "error setting stripe"
9034
9035         # bug12836: getstripe on -1 default directory striping
9036         $LFS getstripe $MOUNT || error "getstripe $MOUNT failed"
9037
9038         # bug12836: getstripe -v on -1 default directory striping
9039         $LFS getstripe -v $MOUNT || error "getstripe -v $MOUNT failed"
9040
9041         # bug12836: new find on -1 default directory striping
9042         $LFS find -mtime -1 $MOUNT > /dev/null || error "find $MOUNT failed"
9043 }
9044 run_test 65i "various tests to set root directory striping"
9045
9046 test_65j() { # bug6367
9047         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9048
9049         sync; sleep 1
9050
9051         # if we aren't already remounting for each test, do so for this test
9052         if [ "$I_MOUNTED" = "yes" ]; then
9053                 cleanup || error "failed to unmount"
9054                 setup
9055         fi
9056
9057         save_layout_restore_at_exit $MOUNT
9058
9059         $LFS setstripe -d $MOUNT || error "setstripe failed"
9060 }
9061 run_test 65j "set default striping on root directory (bug 6367)="
9062
9063 cleanup_65k() {
9064         rm -rf $DIR/$tdir
9065         wait_delete_completed
9066         do_facet $SINGLEMDS "lctl set_param -n \
9067                 osp.$ost*MDT0000.max_create_count=$max_count"
9068         do_facet $SINGLEMDS "lctl set_param -n \
9069                 osp.$ost*MDT0000.create_count=$count"
9070         do_facet $SINGLEMDS lctl --device  %$INACTIVE_OSC activate
9071         echo $INACTIVE_OSC "is Activate"
9072
9073         wait_osc_import_state mds ost$(( ostnum + 1 )) FULL
9074 }
9075
9076 test_65k() { # bug11679
9077         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9078         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
9079         remote_mds_nodsh && skip "remote MDS with nodsh"
9080
9081         local disable_precreate=true
9082         [ $MDS1_VERSION -le $(version_code 2.8.54) ] &&
9083                 disable_precreate=false
9084
9085         echo "Check OST status: "
9086         local MDS_OSCS=$(do_facet $SINGLEMDS lctl dl |
9087                 awk '/[oO][sS][cC].*md[ts]/ { print $4 }')
9088
9089         for OSC in $MDS_OSCS; do
9090                 echo $OSC "is active"
9091                 do_facet $SINGLEMDS lctl --device %$OSC activate
9092         done
9093
9094         for INACTIVE_OSC in $MDS_OSCS; do
9095                 local ost=$(osc_to_ost $INACTIVE_OSC)
9096                 local ostnum=$(do_facet $SINGLEMDS lctl get_param -n \
9097                                lov.*md*.target_obd |
9098                                awk -F: /$ost/'{ print $1 }' | head -n 1)
9099
9100                 mkdir -p $DIR/$tdir
9101                 $LFS setstripe -i $ostnum -c 1 $DIR/$tdir
9102                 createmany -o $DIR/$tdir/$tfile.$ostnum. 1000
9103
9104                 echo "Deactivate: " $INACTIVE_OSC
9105                 do_facet $SINGLEMDS lctl --device %$INACTIVE_OSC deactivate
9106
9107                 local count=$(do_facet $SINGLEMDS "lctl get_param -n \
9108                               osp.$ost*MDT0000.create_count")
9109                 local max_count=$(do_facet $SINGLEMDS "lctl get_param -n \
9110                                   osp.$ost*MDT0000.max_create_count")
9111                 $disable_precreate &&
9112                         do_facet $SINGLEMDS "lctl set_param -n \
9113                                 osp.$ost*MDT0000.max_create_count=0"
9114
9115                 for idx in $(seq 0 $((OSTCOUNT - 1))); do
9116                         [ -f $DIR/$tdir/$idx ] && continue
9117                         echo "$LFS setstripe -i $idx -c 1 $DIR/$tdir/$idx"
9118                         $LFS setstripe -i $idx -c 1 $DIR/$tdir/$idx ||
9119                                 { cleanup_65k;
9120                                   error "setstripe $idx should succeed"; }
9121                         rm -f $DIR/$tdir/$idx || error "rm $idx failed"
9122                 done
9123                 unlinkmany $DIR/$tdir/$tfile.$ostnum. 1000
9124                 rmdir $DIR/$tdir
9125
9126                 do_facet $SINGLEMDS "lctl set_param -n \
9127                         osp.$ost*MDT0000.max_create_count=$max_count"
9128                 do_facet $SINGLEMDS "lctl set_param -n \
9129                         osp.$ost*MDT0000.create_count=$count"
9130                 do_facet $SINGLEMDS lctl --device  %$INACTIVE_OSC activate
9131                 echo $INACTIVE_OSC "is Activate"
9132
9133                 wait_osc_import_state mds ost$(( ostnum + 1 )) FULL
9134         done
9135 }
9136 run_test 65k "validate manual striping works properly with deactivated OSCs"
9137
9138 test_65l() { # bug 12836
9139         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9140
9141         test_mkdir -p $DIR/$tdir/test_dir
9142         $LFS setstripe -c -1 $DIR/$tdir/test_dir
9143         $LFS find -mtime -1 $DIR/$tdir >/dev/null
9144 }
9145 run_test 65l "lfs find on -1 stripe dir ========================"
9146
9147 test_65m() {
9148         local layout=$(save_layout $MOUNT)
9149         $RUNAS $LFS setstripe -c 2 $MOUNT && {
9150                 restore_layout $MOUNT $layout
9151                 error "setstripe should fail by non-root users"
9152         }
9153         true
9154 }
9155 run_test 65m "normal user can't set filesystem default stripe"
9156
9157 test_65n() {
9158         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
9159         [[ $MDS1_VERSION -ge $(version_code 2.12.50) ]] ||
9160                 skip "Need MDS version at least 2.12.50"
9161         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
9162
9163         [[ $OSTCOUNT -ge 2 ]] || skip_env "needs >= 2 OSTs"
9164         which getfattr > /dev/null 2>&1 || skip_env "no getfattr command"
9165         which setfattr > /dev/null 2>&1 || skip_env "no setfattr command"
9166
9167         save_layout_restore_at_exit $MOUNT
9168
9169         # new subdirectory under root directory should not inherit
9170         # the default layout from root
9171         local dir1=$MOUNT/$tdir-1
9172         mkdir $dir1 || error "mkdir $dir1 failed"
9173         ! getfattr -n trusted.lov $dir1 &> /dev/null ||
9174                 error "$dir1 shouldn't have LOV EA"
9175
9176         # delete the default layout on root directory
9177         $LFS setstripe -d $MOUNT || error "delete root default layout failed"
9178
9179         local dir2=$MOUNT/$tdir-2
9180         mkdir $dir2 || error "mkdir $dir2 failed"
9181         ! getfattr -n trusted.lov $dir2 &> /dev/null ||
9182                 error "$dir2 shouldn't have LOV EA"
9183
9184         # set a new striping pattern on root directory
9185         local def_stripe_size=$($LFS getstripe -S $MOUNT)
9186         local new_def_stripe_size=$((def_stripe_size * 2))
9187         $LFS setstripe -S $new_def_stripe_size $MOUNT ||
9188                 error "set stripe size on $MOUNT failed"
9189
9190         # new file created in $dir2 should inherit the new stripe size from
9191         # the filesystem default
9192         local file2=$dir2/$tfile-2
9193         touch $file2 || error "touch $file2 failed"
9194
9195         local file2_stripe_size=$($LFS getstripe -S $file2)
9196         [[ $file2_stripe_size -eq $new_def_stripe_size ]] ||
9197         {
9198                 echo "file2_stripe_size: '$file2_stripe_size'"
9199                 echo "new_def_stripe_size: '$new_def_stripe_size'"
9200                 error "$file2 didn't inherit stripe size $new_def_stripe_size"
9201         }
9202
9203         local dir3=$MOUNT/$tdir-3
9204         mkdir $dir3 || error "mkdir $dir3 failed"
9205         # $dir3 shouldn't have LOV EA, but "lfs getstripe -d $dir3" should show
9206         # the root layout, which is the actual default layout that will be used
9207         # when new files are created in $dir3.
9208         local dir3_layout=$(get_layout_param $dir3)
9209         local root_dir_layout=$(get_layout_param $MOUNT)
9210         [[ "$dir3_layout" = "$root_dir_layout" ]] ||
9211         {
9212                 echo "dir3_layout: '$dir3_layout'"
9213                 echo "root_dir_layout: '$root_dir_layout'"
9214                 error "$dir3 should show the default layout from $MOUNT"
9215         }
9216
9217         # set OST pool on root directory
9218         local pool=$TESTNAME
9219         pool_add $pool || error "add $pool failed"
9220         pool_add_targets $pool 0 $((OSTCOUNT - 1)) 1 ||
9221                 error "add targets to $pool failed"
9222
9223         $LFS setstripe -p $pool $MOUNT ||
9224                 error "set OST pool on $MOUNT failed"
9225
9226         # new file created in $dir3 should inherit the pool from
9227         # the filesystem default
9228         local file3=$dir3/$tfile-3
9229         touch $file3 || error "touch $file3 failed"
9230
9231         local file3_pool=$($LFS getstripe -p $file3)
9232         [[ "$file3_pool" = "$pool" ]] ||
9233                 error "$file3 ('$file3_pool') didn't inherit OST pool '$pool'"
9234
9235         local dir4=$MOUNT/$tdir-4
9236         mkdir $dir4 || error "mkdir $dir4 failed"
9237         local dir4_layout=$(get_layout_param $dir4)
9238         root_dir_layout=$(get_layout_param $MOUNT)
9239         echo "$LFS getstripe -d $dir4"
9240         $LFS getstripe -d $dir4
9241         echo "$LFS getstripe -d $MOUNT"
9242         $LFS getstripe -d $MOUNT
9243         [[ "$dir4_layout" = "$root_dir_layout" ]] ||
9244         {
9245                 echo "dir4_layout: '$dir4_layout'"
9246                 echo "root_dir_layout: '$root_dir_layout'"
9247                 error "$dir4 should show the default layout from $MOUNT"
9248         }
9249
9250         # new file created in $dir4 should inherit the pool from
9251         # the filesystem default
9252         local file4=$dir4/$tfile-4
9253         touch $file4 || error "touch $file4 failed"
9254
9255         local file4_pool=$($LFS getstripe -p $file4)
9256         [[ "$file4_pool" = "$pool" ]] ||
9257                 error "$file4 ('$file4_pool') didn't inherit OST pool $pool"
9258
9259         # new subdirectory under non-root directory should inherit
9260         # the default layout from its parent directory
9261         $LFS setstripe -S $new_def_stripe_size -p $pool $dir4 ||
9262                 error "set directory layout on $dir4 failed"
9263
9264         local dir5=$dir4/$tdir-5
9265         mkdir $dir5 || error "mkdir $dir5 failed"
9266
9267         dir4_layout=$(get_layout_param $dir4)
9268         local dir5_layout=$(get_layout_param $dir5)
9269         [[ "$dir4_layout" = "$dir5_layout" ]] ||
9270         {
9271                 echo "dir4_layout: '$dir4_layout'"
9272                 echo "dir5_layout: '$dir5_layout'"
9273                 error "$dir5 should inherit the default layout from $dir4"
9274         }
9275
9276         # though subdir under ROOT doesn't inherit default layout, but
9277         # its sub dir/file should be created with default layout.
9278         [[ $MDSCOUNT -ge 2 ]] || skip_env "needs >= 2 MDTs"
9279         [[ $MDS1_VERSION -ge $(version_code 2.12.59) ]] ||
9280                 skip "Need MDS version at least 2.12.59"
9281
9282         local default_lmv_count=$($LFS getdirstripe -D -c $MOUNT)
9283         local default_lmv_index=$($LFS getdirstripe -D -i $MOUNT)
9284         local default_lmv_hash=$($LFS getdirstripe -D -H $MOUNT)
9285
9286         if [ $default_lmv_hash == "none" ]; then
9287                 stack_trap "$LFS setdirstripe -D -d $MOUNT" EXIT
9288         else
9289                 stack_trap "$LFS setdirstripe -D -i $default_lmv_index \
9290                         -c $default_lmv_count -H $default_lmv_hash $MOUNT" EXIT
9291         fi
9292
9293         $LFS setdirstripe -D -c 2 $MOUNT ||
9294                 error "setdirstripe -D -c 2 failed"
9295         mkdir $MOUNT/$tdir-6 || error "mkdir $tdir-6 failed"
9296         local lmv_count=$($LFS getdirstripe -c $MOUNT/$tdir-6)
9297         [ $lmv_count -eq 2 ] || error "$tdir-6 stripe count $lmv_count"
9298 }
9299 run_test 65n "don't inherit default layout from root for new subdirectories"
9300
9301 # bug 2543 - update blocks count on client
9302 test_66() {
9303         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9304
9305         COUNT=${COUNT:-8}
9306         dd if=/dev/zero of=$DIR/f66 bs=1k count=$COUNT
9307         sync; sync_all_data; sync; sync_all_data
9308         cancel_lru_locks osc
9309         BLOCKS=`ls -s $DIR/f66 | awk '{ print $1 }'`
9310         [ $BLOCKS -ge $COUNT ] || error "$DIR/f66 blocks $BLOCKS < $COUNT"
9311 }
9312 run_test 66 "update inode blocks count on client ==============="
9313
9314 meminfo() {
9315         awk '($1 == "'$1':") { print $2 }' /proc/meminfo
9316 }
9317
9318 swap_used() {
9319         swapon -s | awk '($1 == "'$1'") { print $4 }'
9320 }
9321
9322 # bug5265, obdfilter oa2dentry return -ENOENT
9323 # #define OBD_FAIL_SRV_ENOENT 0x217
9324 test_69() {
9325         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9326         remote_ost_nodsh && skip "remote OST with nodsh"
9327
9328         f="$DIR/$tfile"
9329         $LFS setstripe -c 1 -i 0 $f
9330
9331         $DIRECTIO write ${f}.2 0 1 || error "directio write error"
9332
9333         do_facet ost1 lctl set_param fail_loc=0x217
9334         $TRUNCATE $f 1 # vmtruncate() will ignore truncate() error.
9335         $DIRECTIO write $f 0 2 && error "write succeeded, expect -ENOENT"
9336
9337         do_facet ost1 lctl set_param fail_loc=0
9338         $DIRECTIO write $f 0 2 || error "write error"
9339
9340         cancel_lru_locks osc
9341         $DIRECTIO read $f 0 1 || error "read error"
9342
9343         do_facet ost1 lctl set_param fail_loc=0x217
9344         $DIRECTIO read $f 1 1 && error "read succeeded, expect -ENOENT"
9345
9346         do_facet ost1 lctl set_param fail_loc=0
9347         rm -f $f
9348 }
9349 run_test 69 "verify oa2dentry return -ENOENT doesn't LBUG ======"
9350
9351 test_71() {
9352         test_mkdir $DIR/$tdir
9353         $LFS setdirstripe -D -c$MDSCOUNT $DIR/$tdir
9354         sh rundbench -C -D $DIR/$tdir 2 || error "dbench failed!"
9355 }
9356 run_test 71 "Running dbench on lustre (don't segment fault) ===="
9357
9358 test_72a() { # bug 5695 - Test that on 2.6 remove_suid works properly
9359         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9360         [ "$RUNAS_ID" = "$UID" ] &&
9361                 skip_env "RUNAS_ID = UID = $UID -- skipping"
9362         # Check that testing environment is properly set up. Skip if not
9363         FAIL_ON_ERROR=false check_runas_id_ret $RUNAS_ID $RUNAS_GID $RUNAS ||
9364                 skip_env "User $RUNAS_ID does not exist - skipping"
9365
9366         touch $DIR/$tfile
9367         chmod 777 $DIR/$tfile
9368         chmod ug+s $DIR/$tfile
9369         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=512 count=1 ||
9370                 error "$RUNAS dd $DIR/$tfile failed"
9371         # See if we are still setuid/sgid
9372         [ -u $DIR/$tfile ] || [ -g $DIR/$tfile ] &&
9373                 error "S/gid is not dropped on write"
9374         # Now test that MDS is updated too
9375         cancel_lru_locks mdc
9376         [ -u $DIR/$tfile ] || [ -g $DIR/$tfile ] &&
9377                 error "S/gid is not dropped on MDS"
9378         rm -f $DIR/$tfile
9379 }
9380 run_test 72a "Test that remove suid works properly (bug5695) ===="
9381
9382 test_72b() { # bug 24226 -- keep mode setting when size is not changing
9383         local perm
9384
9385         [ "$RUNAS_ID" = "$UID" ] &&
9386                 skip_env "RUNAS_ID = UID = $UID -- skipping"
9387         [ "$RUNAS_ID" -eq 0 ] &&
9388                 skip_env "RUNAS_ID = 0 -- skipping"
9389         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9390         # Check that testing environment is properly set up. Skip if not
9391         FAIL_ON_ERROR=false check_runas_id_ret $RUNAS_ID $RUNAS_ID $RUNAS ||
9392                 skip_env "User $RUNAS_ID does not exist - skipping"
9393
9394         touch $DIR/${tfile}-f{g,u}
9395         test_mkdir $DIR/${tfile}-dg
9396         test_mkdir $DIR/${tfile}-du
9397         chmod 770 $DIR/${tfile}-{f,d}{g,u}
9398         chmod g+s $DIR/${tfile}-{f,d}g
9399         chmod u+s $DIR/${tfile}-{f,d}u
9400         for perm in 777 2777 4777; do
9401                 $RUNAS chmod $perm $DIR/${tfile}-fg && error "S/gid file allowed improper chmod to $perm"
9402                 $RUNAS chmod $perm $DIR/${tfile}-fu && error "S/uid file allowed improper chmod to $perm"
9403                 $RUNAS chmod $perm $DIR/${tfile}-dg && error "S/gid dir allowed improper chmod to $perm"
9404                 $RUNAS chmod $perm $DIR/${tfile}-du && error "S/uid dir allowed improper chmod to $perm"
9405         done
9406         true
9407 }
9408 run_test 72b "Test that we keep mode setting if without file data changed (bug 24226)"
9409
9410 # bug 3462 - multiple simultaneous MDC requests
9411 test_73() {
9412         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9413
9414         test_mkdir $DIR/d73-1
9415         test_mkdir $DIR/d73-2
9416         multiop_bg_pause $DIR/d73-1/f73-1 O_c || return 1
9417         pid1=$!
9418
9419         lctl set_param fail_loc=0x80000129
9420         $MULTIOP $DIR/d73-1/f73-2 Oc &
9421         sleep 1
9422         lctl set_param fail_loc=0
9423
9424         $MULTIOP $DIR/d73-2/f73-3 Oc &
9425         pid3=$!
9426
9427         kill -USR1 $pid1
9428         wait $pid1 || return 1
9429
9430         sleep 25
9431
9432         $CHECKSTAT -t file $DIR/d73-1/f73-1 || return 4
9433         $CHECKSTAT -t file $DIR/d73-1/f73-2 || return 5
9434         $CHECKSTAT -t file $DIR/d73-2/f73-3 || return 6
9435
9436         rm -rf $DIR/d73-*
9437 }
9438 run_test 73 "multiple MDC requests (should not deadlock)"
9439
9440 test_74a() { # bug 6149, 6184
9441         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9442
9443         touch $DIR/f74a
9444         #define OBD_FAIL_LDLM_ENQUEUE_OLD_EXPORT 0x30e
9445         #
9446         # very important to OR with OBD_FAIL_ONCE (0x80000000) -- otherwise it
9447         # will spin in a tight reconnection loop
9448         $LCTL set_param fail_loc=0x8000030e
9449         # get any lock that won't be difficult - lookup works.
9450         ls $DIR/f74a
9451         $LCTL set_param fail_loc=0
9452         rm -f $DIR/f74a
9453         true
9454 }
9455 run_test 74a "ldlm_enqueue freed-export error path, ls (shouldn't LBUG)"
9456
9457 test_74b() { # bug 13310
9458         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9459
9460         #define OBD_FAIL_LDLM_ENQUEUE_OLD_EXPORT 0x30e
9461         #
9462         # very important to OR with OBD_FAIL_ONCE (0x80000000) -- otherwise it
9463         # will spin in a tight reconnection loop
9464         $LCTL set_param fail_loc=0x8000030e
9465         # get a "difficult" lock
9466         touch $DIR/f74b
9467         $LCTL set_param fail_loc=0
9468         rm -f $DIR/f74b
9469         true
9470 }
9471 run_test 74b "ldlm_enqueue freed-export error path, touch (shouldn't LBUG)"
9472
9473 test_74c() {
9474         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9475
9476         #define OBD_FAIL_LDLM_NEW_LOCK
9477         $LCTL set_param fail_loc=0x319
9478         touch $DIR/$tfile && error "touch successful"
9479         $LCTL set_param fail_loc=0
9480         true
9481 }
9482 run_test 74c "ldlm_lock_create error path, (shouldn't LBUG)"
9483
9484 slab_lic=/sys/kernel/slab/lustre_inode_cache
9485 num_objects() {
9486         [ -f $slab_lic/shrink ] && echo 1 > $slab_lic/shrink
9487         [ -f $slab_lic/objects ] && awk '{ print $1 }' $slab_lic/objects ||
9488                 awk '/lustre_inode_cache/ { print $2; exit }' /proc/slabinfo
9489 }
9490
9491 test_76a() { # Now for b=20433, added originally in b=1443
9492         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9493
9494         cancel_lru_locks osc
9495         # there may be some slab objects cached per core
9496         local cpus=$(getconf _NPROCESSORS_ONLN 2>/dev/null)
9497         local before=$(num_objects)
9498         local count=$((512 * cpus))
9499         [ "$SLOW" = "no" ] && count=$((128 * cpus))
9500         local margin=$((count / 10))
9501         if [[ -f $slab_lic/aliases ]]; then
9502                 local aliases=$(cat $slab_lic/aliases)
9503                 (( aliases > 0 )) && margin=$((margin * aliases))
9504         fi
9505
9506         echo "before slab objects: $before"
9507         for i in $(seq $count); do
9508                 touch $DIR/$tfile
9509                 rm -f $DIR/$tfile
9510         done
9511         cancel_lru_locks osc
9512         local after=$(num_objects)
9513         echo "created: $count, after slab objects: $after"
9514         # shared slab counts are not very accurate, allow significant margin
9515         # the main goal is that the cache growth is not permanently > $count
9516         while (( after > before + margin )); do
9517                 sleep 1
9518                 after=$(num_objects)
9519                 wait=$((wait + 1))
9520                 (( wait % 5 == 0 )) && echo "wait $wait seconds objects: $after"
9521                 if (( wait > 60 )); then
9522                         error "inode slab grew from $before+$margin to $after"
9523                 fi
9524         done
9525 }
9526 run_test 76a "confirm clients recycle inodes properly ===="
9527
9528 test_76b() {
9529         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9530         [ $CLIENT_VERSION -ge $(version_code 2.13.55) ] || skip "not supported"
9531
9532         local count=512
9533         local before=$(num_objects)
9534
9535         for i in $(seq $count); do
9536                 mkdir $DIR/$tdir
9537                 rmdir $DIR/$tdir
9538         done
9539
9540         local after=$(num_objects)
9541         local wait=0
9542
9543         while (( after > before )); do
9544                 sleep 1
9545                 after=$(num_objects)
9546                 wait=$((wait + 1))
9547                 (( wait % 5 == 0 )) && echo "wait $wait seconds objects: $after"
9548                 if (( wait > 60 )); then
9549                         error "inode slab grew from $before to $after"
9550                 fi
9551         done
9552
9553         echo "slab objects before: $before, after: $after"
9554 }
9555 run_test 76b "confirm clients recycle directory inodes properly ===="
9556
9557 export ORIG_CSUM=""
9558 set_checksums()
9559 {
9560         # Note: in sptlrpc modes which enable its own bulk checksum, the
9561         # original crc32_le bulk checksum will be automatically disabled,
9562         # and the OBD_FAIL_OSC_CHECKSUM_SEND/OBD_FAIL_OSC_CHECKSUM_RECEIVE
9563         # will be checked by sptlrpc code against sptlrpc bulk checksum.
9564         # In this case set_checksums() will not be no-op, because sptlrpc
9565         # bulk checksum will be enabled all through the test.
9566
9567         [ "$ORIG_CSUM" ] || ORIG_CSUM=`lctl get_param -n osc.*.checksums | head -n1`
9568         lctl set_param -n osc.*.checksums $1
9569         return 0
9570 }
9571
9572 export ORIG_CSUM_TYPE="`lctl get_param -n osc.*osc-[^mM]*.checksum_type |
9573                         sed 's/.*\[\(.*\)\].*/\1/g' | head -n1`"
9574 CKSUM_TYPES=${CKSUM_TYPES:-$(lctl get_param -n osc.*osc-[^mM]*.checksum_type |
9575                              tr -d [] | head -n1)}
9576 set_checksum_type()
9577 {
9578         lctl set_param -n osc.*osc-[^mM]*.checksum_type $1
9579         rc=$?
9580         log "set checksum type to $1, rc = $rc"
9581         return $rc
9582 }
9583
9584 get_osc_checksum_type()
9585 {
9586         # arugment 1: OST name, like OST0000
9587         ost=$1
9588         checksum_type=$(lctl get_param -n osc.*${ost}-osc-[^mM]*.checksum_type |
9589                         sed 's/.*\[\(.*\)\].*/\1/g')
9590         rc=$?
9591         [ $rc -ne 0 ] && error "failed to get checksum type of $ost, rc = $rc, output = $checksum_type"
9592         echo $checksum_type
9593 }
9594
9595 F77_TMP=$TMP/f77-temp
9596 F77SZ=8
9597 setup_f77() {
9598         dd if=/dev/urandom of=$F77_TMP bs=1M count=$F77SZ || \
9599                 error "error writing to $F77_TMP"
9600 }
9601
9602 test_77a() { # bug 10889
9603         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9604         $GSS && skip_env "could not run with gss"
9605
9606         [ ! -f $F77_TMP ] && setup_f77
9607         set_checksums 1
9608         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ || error "dd error"
9609         set_checksums 0
9610         rm -f $DIR/$tfile
9611 }
9612 run_test 77a "normal checksum read/write operation"
9613
9614 test_77b() { # bug 10889
9615         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9616         $GSS && skip_env "could not run with gss"
9617
9618         [ ! -f $F77_TMP ] && setup_f77
9619         #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
9620         $LCTL set_param fail_loc=0x80000409
9621         set_checksums 1
9622
9623         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ conv=sync ||
9624                 error "dd error: $?"
9625         $LCTL set_param fail_loc=0
9626
9627         for algo in $CKSUM_TYPES; do
9628                 cancel_lru_locks osc
9629                 set_checksum_type $algo
9630                 #define OBD_FAIL_OSC_CHECKSUM_RECEIVE    0x408
9631                 $LCTL set_param fail_loc=0x80000408
9632                 cmp $F77_TMP $DIR/$tfile || error "file compare failed"
9633                 $LCTL set_param fail_loc=0
9634         done
9635         set_checksums 0
9636         set_checksum_type $ORIG_CSUM_TYPE
9637         rm -f $DIR/$tfile
9638 }
9639 run_test 77b "checksum error on client write, read"
9640
9641 cleanup_77c() {
9642         trap 0
9643         set_checksums 0
9644         $LCTL set_param osc.*osc-[^mM]*.checksum_dump=0
9645         $check_ost &&
9646                 do_facet ost1 $LCTL set_param obdfilter.*-OST*.checksum_dump=0
9647         [ -n "$osc_file_prefix" ] && rm -f ${osc_file_prefix}*
9648         $check_ost && [ -n "$ost_file_prefix" ] &&
9649                 do_facet ost1 rm -f ${ost_file_prefix}\*
9650 }
9651
9652 test_77c() {
9653         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9654         $GSS && skip_env "could not run with gss"
9655         remote_ost_nodsh && skip "remote OST with nodsh"
9656
9657         local bad1
9658         local osc_file_prefix
9659         local osc_file
9660         local check_ost=false
9661         local ost_file_prefix
9662         local ost_file
9663         local orig_cksum
9664         local dump_cksum
9665         local fid
9666
9667         # ensure corruption will occur on first OSS/OST
9668         $LFS setstripe -i 0 $DIR/$tfile
9669
9670         [ ! -f $F77_TMP ] && setup_f77
9671         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ conv=sync ||
9672                 error "dd write error: $?"
9673         fid=$($LFS path2fid $DIR/$tfile)
9674
9675         if [ $OST1_VERSION -ge $(version_code 2.9.57) ]
9676         then
9677                 check_ost=true
9678                 ost_file_prefix=$(do_facet ost1 $LCTL get_param -n debug_path)
9679                 ost_file_prefix=${ost_file_prefix}-checksum_dump-ost-\\${fid}
9680         else
9681                 echo "OSS do not support bulk pages dump upon error"
9682         fi
9683
9684         osc_file_prefix=$($LCTL get_param -n debug_path)
9685         osc_file_prefix=${osc_file_prefix}-checksum_dump-osc-\\${fid}
9686
9687         trap cleanup_77c EXIT
9688
9689         set_checksums 1
9690         # enable bulk pages dump upon error on Client
9691         $LCTL set_param osc.*osc-[^mM]*.checksum_dump=1
9692         # enable bulk pages dump upon error on OSS
9693         $check_ost &&
9694                 do_facet ost1 $LCTL set_param obdfilter.*-OST*.checksum_dump=1
9695
9696         # flush Client cache to allow next read to reach OSS
9697         cancel_lru_locks osc
9698
9699         #define OBD_FAIL_OSC_CHECKSUM_RECEIVE       0x408
9700         $LCTL set_param fail_loc=0x80000408
9701         dd if=$DIR/$tfile of=/dev/null bs=1M || error "dd read error: $?"
9702         $LCTL set_param fail_loc=0
9703
9704         rm -f $DIR/$tfile
9705
9706         # check cksum dump on Client
9707         osc_file=$(ls ${osc_file_prefix}*)
9708         [ -n "$osc_file" ] || error "no checksum dump file on Client"
9709         # OBD_FAIL_OSC_CHECKSUM_RECEIVE corrupts with "bad1" at start of file
9710         bad1=$(dd if=$osc_file bs=1 count=4 2>/dev/null) || error "dd error: $?"
9711         [ $bad1 == "bad1" ] || error "unexpected corrupt pattern"
9712         orig_cksum=$(dd if=$F77_TMP bs=1 skip=4 count=1048572 2>/dev/null |
9713                      cksum)
9714         dump_cksum=$(dd if=$osc_file bs=1 skip=4 2>/dev/null | cksum)
9715         [[ "$orig_cksum" == "$dump_cksum" ]] ||
9716                 error "dump content does not match on Client"
9717
9718         $check_ost || skip "No need to check cksum dump on OSS"
9719
9720         # check cksum dump on OSS
9721         ost_file=$(do_facet ost1 ls ${ost_file_prefix}\*)
9722         [ -n "$ost_file" ] || error "no checksum dump file on OSS"
9723         orig_cksum=$(dd if=$F77_TMP bs=1048576 count=1 2>/dev/null | cksum)
9724         dump_cksum=$(do_facet ost1 dd if=$ost_file 2>/dev/null \| cksum)
9725         [[ "$orig_cksum" == "$dump_cksum" ]] ||
9726                 error "dump content does not match on OSS"
9727
9728         cleanup_77c
9729 }
9730 run_test 77c "checksum error on client read with debug"
9731
9732 test_77d() { # bug 10889
9733         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9734         $GSS && skip_env "could not run with gss"
9735
9736         stack_trap "rm -f $DIR/$tfile"
9737         #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
9738         $LCTL set_param fail_loc=0x80000409
9739         set_checksums 1
9740         $DIRECTIO write $DIR/$tfile 0 $F77SZ $((1024 * 1024)) ||
9741                 error "direct write: rc=$?"
9742         $LCTL set_param fail_loc=0
9743         set_checksums 0
9744
9745         #define OBD_FAIL_OSC_CHECKSUM_RECEIVE    0x408
9746         $LCTL set_param fail_loc=0x80000408
9747         set_checksums 1
9748         cancel_lru_locks osc
9749         $DIRECTIO read $DIR/$tfile 0 $F77SZ $((1024 * 1024)) ||
9750                 error "direct read: rc=$?"
9751         $LCTL set_param fail_loc=0
9752         set_checksums 0
9753 }
9754 run_test 77d "checksum error on OST direct write, read"
9755
9756 test_77f() { # bug 10889
9757         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9758         $GSS && skip_env "could not run with gss"
9759
9760         set_checksums 1
9761         stack_trap "rm -f $DIR/$tfile"
9762         for algo in $CKSUM_TYPES; do
9763                 cancel_lru_locks osc
9764                 set_checksum_type $algo
9765                 #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
9766                 $LCTL set_param fail_loc=0x409
9767                 $DIRECTIO write $DIR/$tfile 0 $F77SZ $((1024 * 1024)) &&
9768                         error "direct write succeeded"
9769                 $LCTL set_param fail_loc=0
9770         done
9771         set_checksum_type $ORIG_CSUM_TYPE
9772         set_checksums 0
9773 }
9774 run_test 77f "repeat checksum error on write (expect error)"
9775
9776 test_77g() { # bug 10889
9777         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9778         $GSS && skip_env "could not run with gss"
9779         remote_ost_nodsh && skip "remote OST with nodsh"
9780
9781         [ ! -f $F77_TMP ] && setup_f77
9782
9783         local file=$DIR/$tfile
9784         stack_trap "rm -f $file" EXIT
9785
9786         $LFS setstripe -c 1 -i 0 $file
9787         #define OBD_FAIL_OST_CHECKSUM_RECEIVE       0x21a
9788         do_facet ost1 lctl set_param fail_loc=0x8000021a
9789         set_checksums 1
9790         dd if=$F77_TMP of=$file bs=1M count=$F77SZ ||
9791                 error "write error: rc=$?"
9792         do_facet ost1 lctl set_param fail_loc=0
9793         set_checksums 0
9794
9795         cancel_lru_locks osc
9796         #define OBD_FAIL_OST_CHECKSUM_SEND          0x21b
9797         do_facet ost1 lctl set_param fail_loc=0x8000021b
9798         set_checksums 1
9799         cmp $F77_TMP $file || error "file compare failed"
9800         do_facet ost1 lctl set_param fail_loc=0
9801         set_checksums 0
9802 }
9803 run_test 77g "checksum error on OST write, read"
9804
9805 test_77k() { # LU-10906
9806         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9807         $GSS && skip_env "could not run with gss"
9808
9809         local cksum_param="osc.$FSNAME*.checksums"
9810         local get_checksum="$LCTL get_param -n $cksum_param | head -n1"
9811         local checksum
9812         local i
9813
9814         [ "$ORIG_CSUM" ] || ORIG_CSUM=$(eval $get_checksum)
9815         stack_trap "wait_update $HOSTNAME '$get_checksum' $ORIG_CSUM || true"
9816         stack_trap "do_facet mgs $LCTL set_param -P $cksum_param=$ORIG_CSUM"
9817
9818         for i in 0 1; do
9819                 do_facet mgs $LCTL set_param -P $cksum_param=$i ||
9820                         error "failed to set checksum=$i on MGS"
9821                 wait_update $HOSTNAME "$get_checksum" $i
9822                 #remount
9823                 echo "remount client, checksum should be $i"
9824                 remount_client $MOUNT || error "failed to remount client"
9825                 checksum=$(eval $get_checksum)
9826                 [ $checksum -eq $i ] || error "checksum($checksum) != $i"
9827         done
9828         # remove persistent param to avoid races with checksum mountopt below
9829         do_facet mgs $LCTL set_param -P -d $cksum_param ||
9830                 error "failed to delete checksum on MGS"
9831
9832         for opt in "checksum" "nochecksum"; do
9833                 #remount with mount option
9834                 echo "remount client with option $opt, checksum should be $i"
9835                 umount_client $MOUNT || error "failed to umount client"
9836                 mount_client $MOUNT "$MOUNT_OPTS,$opt" ||
9837                         error "failed to mount client with option '$opt'"
9838                 checksum=$(eval $get_checksum)
9839                 [ $checksum -eq $i ] || error "checksum($checksum) != $i"
9840                 i=$((i - 1))
9841         done
9842
9843         remount_client $MOUNT || error "failed to remount client"
9844 }
9845 run_test 77k "enable/disable checksum correctly"
9846
9847 test_77l() {
9848         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9849         $GSS && skip_env "could not run with gss"
9850
9851         set_checksums 1
9852         stack_trap "set_checksums $ORIG_CSUM" EXIT
9853         stack_trap "set_checksum_type $ORIG_CSUM_TYPE" EXIT
9854
9855         set_checksum_type invalid && error "unexpected success of invalid checksum type"
9856
9857         $LFS setstripe -c 1 -i 0 $DIR/$tfile
9858         for algo in $CKSUM_TYPES; do
9859                 set_checksum_type $algo || error "fail to set checksum type $algo"
9860                 osc_algo=$(get_osc_checksum_type OST0000)
9861                 [ "$osc_algo" != "$algo" ] && error "checksum type is $osc_algo after setting it to $algo"
9862
9863                 # no locks, no reqs to let the connection idle
9864                 cancel_lru_locks osc
9865                 lru_resize_disable osc
9866                 wait_osc_import_state client ost1 IDLE
9867
9868                 # ensure ost1 is connected
9869                 stat $DIR/$tfile >/dev/null || error "can't stat"
9870                 wait_osc_import_state client ost1 FULL
9871
9872                 osc_algo=$(get_osc_checksum_type OST0000)
9873                 [ "$osc_algo" != "$algo" ] && error "checksum type changed from $algo to $osc_algo after reconnection"
9874         done
9875         return 0
9876 }
9877 run_test 77l "preferred checksum type is remembered after reconnected"
9878
9879 [ "$ORIG_CSUM" ] && set_checksums $ORIG_CSUM || true
9880 rm -f $F77_TMP
9881 unset F77_TMP
9882
9883 test_77m() {
9884         (( $CLIENT_VERSION >= $(version_code 2.14.52) )) ||
9885                 skip "Need at least version 2.14.52"
9886         local param=checksum_speed
9887
9888         $LCTL get_param $param || error "reading $param failed"
9889
9890         csum_speeds=$($LCTL get_param -n $param)
9891
9892         [[ "$csum_speeds" =~ "adler32" && "$csum_speeds" =~ "crc32" ]] ||
9893                 error "known checksum types are missing"
9894 }
9895 run_test 77m "Verify checksum_speed is correctly read"
9896
9897 check_filefrag_77n() {
9898         local nr_ext=0
9899         local starts=()
9900         local ends=()
9901
9902         while read extidx a b start end rest; do
9903                 if [[ "${extidx}" =~ ^[0-9]+: ]]; then
9904                         nr_ext=$(( $nr_ext + 1 ))
9905                         starts+=( ${start%..} )
9906                         ends+=( ${end%:} )
9907                 fi
9908         done < <( filefrag -sv $1 )
9909
9910         [[ $nr_ext -eq 2 ]] && [[ "${starts[-1]}" == $(( ${ends[0]} + 1 )) ]] && return 0
9911         return 1
9912 }
9913
9914 test_77n() {
9915         [[ "$CKSUM_TYPES" =~ t10 ]] || skip "no T10 checksum support on osc"
9916
9917         touch $DIR/$tfile
9918         $TRUNCATE $DIR/$tfile 0
9919         dd if=/dev/urandom of=$DIR/$tfile bs=4k conv=notrunc count=1 seek=0
9920         dd if=/dev/urandom of=$DIR/$tfile bs=4k conv=notrunc count=1 seek=2
9921         check_filefrag_77n $DIR/$tfile ||
9922                 skip "$tfile blocks not contiguous around hole"
9923
9924         set_checksums 1
9925         stack_trap "set_checksums $ORIG_CSUM" EXIT
9926         stack_trap "set_checksum_type $ORIG_CSUM_TYPE" EXIT
9927         stack_trap "rm -f $DIR/$tfile"
9928
9929         for algo in $CKSUM_TYPES; do
9930                 if [[ "$algo" =~ ^t10 ]]; then
9931                         set_checksum_type $algo ||
9932                                 error "fail to set checksum type $algo"
9933                         dd if=$DIR/$tfile of=/dev/null bs=12k count=1 iflag=direct ||
9934                                 error "fail to read $tfile with $algo"
9935                 fi
9936         done
9937         rm -f $DIR/$tfile
9938         return 0
9939 }
9940 run_test 77n "Verify read from a hole inside contiguous blocks with T10PI"
9941
9942 test_77o() {
9943         (( $CLIENT_VERSION >= $(version_code 2.14.54) )) ||
9944                 skip "Need at least version 2.14.54"
9945         local ofd=obdfilter
9946         local mdt=mdt
9947
9948         # print OST checksum_type
9949         echo "$ofd.$FSNAME-*.checksum_type:"
9950         do_nodes $(comma_list $(osts_nodes)) \
9951                 $LCTL get_param -n $ofd.$FSNAME-*.checksum_type
9952
9953         # print MDT checksum_type
9954         echo "$mdt.$FSNAME-*.checksum_type:"
9955         do_nodes $(comma_list $(mdts_nodes)) \
9956                 $LCTL get_param -n $mdt.$FSNAME-*.checksum_type
9957
9958         local o_count=$(do_nodes $(comma_list $(osts_nodes)) \
9959                    $LCTL get_param -n $ofd.$FSNAME-*.checksum_type | wc -l)
9960
9961         (( $o_count == $OSTCOUNT )) ||
9962                 error "found $o_count checksums, not \$MDSCOUNT=$OSTCOUNT"
9963
9964         local m_count=$(do_nodes $(comma_list $(mdts_nodes)) \
9965                    $LCTL get_param -n $mdt.$FSNAME-*.checksum_type | wc -l)
9966
9967         (( $m_count == $MDSCOUNT )) ||
9968                 error "found $m_count checksums, not \$MDSCOUNT=$MDSCOUNT"
9969 }
9970 run_test 77o "Verify checksum_type for server (mdt and ofd(obdfilter))"
9971
9972 cleanup_test_78() {
9973         trap 0
9974         rm -f $DIR/$tfile
9975 }
9976
9977 test_78() { # bug 10901
9978         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9979         remote_ost || skip_env "local OST"
9980
9981         NSEQ=5
9982         F78SIZE=$(($(awk '/MemFree:/ { print $2 }' /proc/meminfo) / 1024))
9983         echo "MemFree: $F78SIZE, Max file size: $MAXFREE"
9984         MEMTOTAL=$(($(awk '/MemTotal:/ { print $2 }' /proc/meminfo) / 1024))
9985         echo "MemTotal: $MEMTOTAL"
9986
9987         # reserve 256MB of memory for the kernel and other running processes,
9988         # and then take 1/2 of the remaining memory for the read/write buffers.
9989         if [ $MEMTOTAL -gt 512 ] ;then
9990                 MEMTOTAL=$(((MEMTOTAL - 256 ) / 2))
9991         else
9992                 # for those poor memory-starved high-end clusters...
9993                 MEMTOTAL=$((MEMTOTAL / 2))
9994         fi
9995         echo "Mem to use for directio: $MEMTOTAL"
9996
9997         [[ $F78SIZE -gt $MEMTOTAL ]] && F78SIZE=$MEMTOTAL
9998         [[ $F78SIZE -gt 512 ]] && F78SIZE=512
9999         [[ $F78SIZE -gt $((MAXFREE / 1024)) ]] && F78SIZE=$((MAXFREE / 1024))
10000         SMALLESTOST=$($LFS df $DIR | grep OST | awk '{ print $4 }' | sort -n |
10001                 head -n1)
10002         echo "Smallest OST: $SMALLESTOST"
10003         [[ $SMALLESTOST -lt 10240 ]] &&
10004                 skip "too small OSTSIZE, useless to run large O_DIRECT test"
10005
10006         trap cleanup_test_78 EXIT
10007
10008         [[ $F78SIZE -gt $((SMALLESTOST * $OSTCOUNT / 1024 - 80)) ]] &&
10009                 F78SIZE=$((SMALLESTOST * $OSTCOUNT / 1024 - 80))
10010
10011         [ "$SLOW" = "no" ] && NSEQ=1 && [ $F78SIZE -gt 32 ] && F78SIZE=32
10012         echo "File size: $F78SIZE"
10013         $LFS setstripe -c $OSTCOUNT $DIR/$tfile || error "setstripe failed"
10014         for i in $(seq 1 $NSEQ); do
10015                 FSIZE=$(($F78SIZE / ($NSEQ - $i + 1)))
10016                 echo directIO rdwr round $i of $NSEQ
10017                 $DIRECTIO rdwr $DIR/$tfile 0 $FSIZE 1048576||error "rdwr failed"
10018         done
10019
10020         cleanup_test_78
10021 }
10022 run_test 78 "handle large O_DIRECT writes correctly ============"
10023
10024 test_79() { # bug 12743
10025         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10026
10027         wait_delete_completed
10028
10029         BKTOTAL=$(calc_osc_kbytes kbytestotal)
10030         BKFREE=$(calc_osc_kbytes kbytesfree)
10031         BKAVAIL=$(calc_osc_kbytes kbytesavail)
10032
10033         STRING=`df -P $MOUNT | tail -n 1 | awk '{print $2","$3","$4}'`
10034         DFTOTAL=`echo $STRING | cut -d, -f1`
10035         DFUSED=`echo $STRING  | cut -d, -f2`
10036         DFAVAIL=`echo $STRING | cut -d, -f3`
10037         DFFREE=$(($DFTOTAL - $DFUSED))
10038
10039         ALLOWANCE=$((64 * $OSTCOUNT))
10040
10041         if [ $DFTOTAL -lt $(($BKTOTAL - $ALLOWANCE)) ] ||
10042            [ $DFTOTAL -gt $(($BKTOTAL + $ALLOWANCE)) ] ; then
10043                 error "df total($DFTOTAL) mismatch OST total($BKTOTAL)"
10044         fi
10045         if [ $DFFREE -lt $(($BKFREE - $ALLOWANCE)) ] ||
10046            [ $DFFREE -gt $(($BKFREE + $ALLOWANCE)) ] ; then
10047                 error "df free($DFFREE) mismatch OST free($BKFREE)"
10048         fi
10049         if [ $DFAVAIL -lt $(($BKAVAIL - $ALLOWANCE)) ] ||
10050            [ $DFAVAIL -gt $(($BKAVAIL + $ALLOWANCE)) ] ; then
10051                 error "df avail($DFAVAIL) mismatch OST avail($BKAVAIL)"
10052         fi
10053 }
10054 run_test 79 "df report consistency check ======================="
10055
10056 test_80() { # bug 10718
10057         remote_ost_nodsh && skip "remote OST with nodsh"
10058         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10059
10060         # relax strong synchronous semantics for slow backends like ZFS
10061         if [ "$ost1_FSTYPE" != "ldiskfs" ]; then
10062                 local soc="obdfilter.*.sync_lock_cancel"
10063                 local save=$(do_facet ost1 $LCTL get_param -n $soc | head -n1)
10064
10065                 # "sync_on_lock_cancel" was broken by v2_11_55_0-26-g7059644e9a
10066                 if [ -z "$save" ]; then
10067                         soc="obdfilter.*.sync_on_lock_cancel"
10068                         save=$(do_facet ost1 $LCTL get_param -n $soc | head -n1)
10069                 fi
10070
10071                 if [ "$save" != "never" ]; then
10072                         local hosts=$(comma_list $(osts_nodes))
10073
10074                         do_nodes $hosts $LCTL set_param $soc=never
10075                         stack_trap "do_nodes $hosts $LCTL set_param $soc=$save"
10076                 fi
10077         fi
10078
10079         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=1M
10080         sync; sleep 1; sync
10081         local before=$(date +%s)
10082         cancel_lru_locks osc
10083         local after=$(date +%s)
10084         local diff=$((after - before))
10085         [ $diff -le 1 ] || error "elapsed for 1M@1T = $diff"
10086
10087         rm -f $DIR/$tfile
10088 }
10089 run_test 80 "Page eviction is equally fast at high offsets too"
10090
10091 test_81a() { # LU-456
10092         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10093         remote_ost_nodsh && skip "remote OST with nodsh"
10094
10095         # define OBD_FAIL_OST_MAPBLK_ENOSPC    0x228
10096         # MUST OR with the OBD_FAIL_ONCE (0x80000000)
10097         do_facet ost1 lctl set_param fail_loc=0x80000228
10098
10099         # write should trigger a retry and success
10100         $LFS setstripe -i 0 -c 1 $DIR/$tfile
10101         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
10102         RC=$?
10103         if [ $RC -ne 0 ] ; then
10104                 error "write should success, but failed for $RC"
10105         fi
10106 }
10107 run_test 81a "OST should retry write when get -ENOSPC ==============="
10108
10109 test_81b() { # LU-456
10110         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10111         remote_ost_nodsh && skip "remote OST with nodsh"
10112
10113         # define OBD_FAIL_OST_MAPBLK_ENOSPC    0x228
10114         # Don't OR with the OBD_FAIL_ONCE (0x80000000)
10115         do_facet ost1 lctl set_param fail_loc=0x228
10116
10117         # write should retry several times and return -ENOSPC finally
10118         $LFS setstripe -i 0 -c 1 $DIR/$tfile
10119         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
10120         RC=$?
10121         ENOSPC=28
10122         if [ $RC -ne $ENOSPC ] ; then
10123                 error "dd should fail for -ENOSPC, but succeed."
10124         fi
10125 }
10126 run_test 81b "OST should return -ENOSPC when retry still fails ======="
10127
10128 test_99() {
10129         [ -z "$(which cvs 2>/dev/null)" ] && skip_env "could not find cvs"
10130
10131         test_mkdir $DIR/$tdir.cvsroot
10132         chown $RUNAS_ID $DIR/$tdir.cvsroot
10133
10134         cd $TMP
10135         $RUNAS cvs -d $DIR/$tdir.cvsroot init || error "cvs init failed"
10136
10137         cd /etc/init.d
10138         # some versions of cvs import exit(1) when asked to import links or
10139         # files they can't read.  ignore those files.
10140         local toignore=$(find . -type l -printf '-I %f\n' -o \
10141                          ! -perm /4 -printf '-I %f\n')
10142         $RUNAS cvs -d $DIR/$tdir.cvsroot import -m "nomesg" $toignore \
10143                 $tdir.reposname vtag rtag
10144
10145         cd $DIR
10146         test_mkdir $DIR/$tdir.reposname
10147         chown $RUNAS_ID $DIR/$tdir.reposname
10148         $RUNAS cvs -d $DIR/$tdir.cvsroot co $tdir.reposname
10149
10150         cd $DIR/$tdir.reposname
10151         $RUNAS touch foo99
10152         $RUNAS cvs add -m 'addmsg' foo99
10153         $RUNAS cvs update
10154         $RUNAS cvs commit -m 'nomsg' foo99
10155         rm -fr $DIR/$tdir.cvsroot
10156 }
10157 run_test 99 "cvs strange file/directory operations"
10158
10159 test_100() {
10160         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10161         [[ "$NETTYPE" =~ tcp ]] ||
10162                 skip_env "TCP secure port test, not useful for NETTYPE=$NETTYPE"
10163         remote_ost_nodsh && skip "remote OST with nodsh"
10164         remote_mds_nodsh && skip "remote MDS with nodsh"
10165         remote_servers ||
10166                 skip "useless for local single node setup"
10167
10168         netstat -tna | ( rc=1; while read PROT SND RCV LOCAL REMOTE STAT; do
10169                 [ "$PROT" != "tcp" ] && continue
10170                 RPORT=$(echo $REMOTE | cut -d: -f2)
10171                 [ "$RPORT" != "$ACCEPTOR_PORT" ] && continue
10172
10173                 rc=0
10174                 LPORT=`echo $LOCAL | cut -d: -f2`
10175                 if [ $LPORT -ge 1024 ]; then
10176                         echo "bad: $PROT $SND $RCV $LOCAL $REMOTE $STAT"
10177                         netstat -tna
10178                         error_exit "local: $LPORT > 1024, remote: $RPORT"
10179                 fi
10180         done
10181         [ "$rc" = 0 ] || error_exit "privileged port not found" )
10182 }
10183 run_test 100 "check local port using privileged port ==========="
10184
10185 function get_named_value()
10186 {
10187     local tag=$1
10188
10189     grep -w "$tag" | sed "s/^$tag  *\([0-9]*\)  *.*/\1/"
10190 }
10191
10192 export CACHE_MAX=$($LCTL get_param -n llite.*.max_cached_mb |
10193                    awk '/^max_cached_mb/ { print $2 }')
10194
10195 cleanup_101a() {
10196         $LCTL set_param -n llite.*.max_cached_mb $CACHE_MAX
10197         trap 0
10198 }
10199
10200 test_101a() {
10201         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10202
10203         local s
10204         local discard
10205         local nreads=10000
10206         local cache_limit=32
10207
10208         $LCTL set_param -n osc.*-osc*.rpc_stats=0
10209         trap cleanup_101a EXIT
10210         $LCTL set_param -n llite.*.read_ahead_stats=0
10211         $LCTL set_param -n llite.*.max_cached_mb=$cache_limit
10212
10213         #
10214         # randomly read 10000 of 64K chunks from file 3x 32MB in size
10215         #
10216         echo "nreads: $nreads file size: $((cache_limit * 3))MB"
10217         $READS -f $DIR/$tfile -s$((cache_limit * 3192 * 1024)) -b65536 -C -n$nreads -t 180
10218
10219         discard=0
10220         for s in $($LCTL get_param -n llite.*.read_ahead_stats |
10221                    get_named_value 'read.but.discarded'); do
10222                         discard=$(($discard + $s))
10223         done
10224         cleanup_101a
10225
10226         $LCTL get_param osc.*-osc*.rpc_stats
10227         $LCTL get_param llite.*.read_ahead_stats
10228
10229         # Discard is generally zero, but sometimes a few random reads line up
10230         # and trigger larger readahead, which is wasted & leads to discards.
10231         if [[ $(($discard)) -gt $nreads ]]; then
10232                 error "too many ($discard) discarded pages"
10233         fi
10234         rm -f $DIR/$tfile || true
10235 }
10236 run_test 101a "check read-ahead for random reads"
10237
10238 setup_test101bc() {
10239         test_mkdir $DIR/$tdir
10240         local ssize=$1
10241         local FILE_LENGTH=$2
10242         STRIPE_OFFSET=0
10243
10244         local FILE_SIZE_MB=$((FILE_LENGTH / ssize))
10245
10246         local list=$(comma_list $(osts_nodes))
10247         set_osd_param $list '' read_cache_enable 0
10248         set_osd_param $list '' writethrough_cache_enable 0
10249
10250         trap cleanup_test101bc EXIT
10251         # prepare the read-ahead file
10252         $LFS setstripe -S $ssize -i $STRIPE_OFFSET -c $OSTCOUNT $DIR/$tfile
10253
10254         dd if=/dev/zero of=$DIR/$tfile bs=$ssize \
10255                                 count=$FILE_SIZE_MB 2> /dev/null
10256
10257 }
10258
10259 cleanup_test101bc() {
10260         trap 0
10261         rm -rf $DIR/$tdir
10262         rm -f $DIR/$tfile
10263
10264         local list=$(comma_list $(osts_nodes))
10265         set_osd_param $list '' read_cache_enable 1
10266         set_osd_param $list '' writethrough_cache_enable 1
10267 }
10268
10269 calc_total() {
10270         awk 'BEGIN{total=0}; {total+=$1}; END{print total}'
10271 }
10272
10273 ra_check_101() {
10274         local READ_SIZE=$1
10275         local STRIPE_SIZE=$2
10276         local FILE_LENGTH=$3
10277         local RA_INC=1048576
10278         local STRIDE_LENGTH=$((STRIPE_SIZE/READ_SIZE))
10279         local discard_limit=$((((STRIDE_LENGTH - 1)*3/(STRIDE_LENGTH*OSTCOUNT))* \
10280                              (STRIDE_LENGTH*OSTCOUNT - STRIDE_LENGTH)))
10281         DISCARD=$($LCTL get_param -n llite.*.read_ahead_stats |
10282                   get_named_value 'read.but.discarded' | calc_total)
10283         if [[ $DISCARD -gt $discard_limit ]]; then
10284                 $LCTL get_param llite.*.read_ahead_stats
10285                 error "Too many ($DISCARD) discarded pages with size (${READ_SIZE})"
10286         else
10287                 echo "Read-ahead success for size ${READ_SIZE}"
10288         fi
10289 }
10290
10291 test_101b() {
10292         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10293         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
10294
10295         local STRIPE_SIZE=1048576
10296         local STRIDE_SIZE=$((STRIPE_SIZE*OSTCOUNT))
10297
10298         if [ $SLOW == "yes" ]; then
10299                 local FILE_LENGTH=$((STRIDE_SIZE * 64))
10300         else
10301                 local FILE_LENGTH=$((STRIDE_SIZE * 8))
10302         fi
10303
10304         local ITERATION=$((FILE_LENGTH / STRIDE_SIZE))
10305
10306         # prepare the read-ahead file
10307         setup_test101bc $STRIPE_SIZE $FILE_LENGTH
10308         cancel_lru_locks osc
10309         for BIDX in 2 4 8 16 32 64 128 256
10310         do
10311                 local BSIZE=$((BIDX*4096))
10312                 local READ_COUNT=$((STRIPE_SIZE/BSIZE))
10313                 local STRIDE_LENGTH=$((STRIDE_SIZE/BSIZE))
10314                 local OFFSET=$((STRIPE_SIZE/BSIZE*(OSTCOUNT - 1)))
10315                 $LCTL set_param -n llite.*.read_ahead_stats=0
10316                 $READS -f $DIR/$tfile  -l $STRIDE_LENGTH -o $OFFSET \
10317                               -s $FILE_LENGTH -b $STRIPE_SIZE -a $READ_COUNT -n $ITERATION
10318                 cancel_lru_locks osc
10319                 ra_check_101 $BSIZE $STRIPE_SIZE $FILE_LENGTH
10320         done
10321         cleanup_test101bc
10322         true
10323 }
10324 run_test 101b "check stride-io mode read-ahead ================="
10325
10326 test_101c() {
10327         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10328
10329         local STRIPE_SIZE=1048576
10330         local FILE_LENGTH=$((STRIPE_SIZE*100))
10331         local nreads=10000
10332         local rsize=65536
10333         local osc_rpc_stats
10334
10335         setup_test101bc $STRIPE_SIZE $FILE_LENGTH
10336
10337         cancel_lru_locks osc
10338         $LCTL set_param osc.*.rpc_stats=0
10339         $READS -f $DIR/$tfile -s$FILE_LENGTH -b$rsize -n$nreads -t 180
10340         $LCTL get_param osc.*.rpc_stats
10341         for osc_rpc_stats in $($LCTL get_param -N osc.*.rpc_stats); do
10342                 local stats=$($LCTL get_param -n $osc_rpc_stats)
10343                 local lines=$(echo "$stats" | awk 'END {print NR;}')
10344                 local size
10345
10346                 if [ $lines -le 20 ]; then
10347                         echo "continue debug"
10348                         continue
10349                 fi
10350                 for size in 1 2 4 8; do
10351                         local rpc=$(echo "$stats" |
10352                                     awk '($1 == "'$size':") {print $2; exit; }')
10353                         [ $rpc != 0 ] && ((size * PAGE_SIZE < rsize)) &&
10354                                 error "Small $((size*PAGE_SIZE)) read IO $rpc!"
10355                 done
10356                 echo "$osc_rpc_stats check passed!"
10357         done
10358         cleanup_test101bc
10359         true
10360 }
10361 run_test 101c "check stripe_size aligned read-ahead"
10362
10363 test_101d() {
10364         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10365
10366         local file=$DIR/$tfile
10367         local sz_MB=${FILESIZE_101d:-80}
10368         local ra_MB=${READAHEAD_MB:-40}
10369
10370         local free_MB=$(($(df -P $DIR | tail -n 1 | awk '{ print $4 }') / 1024))
10371         [ $free_MB -lt $sz_MB ] &&
10372                 skip "Need free space ${sz_MB}M, have ${free_MB}M"
10373
10374         echo "Create test file $file size ${sz_MB}M, ${free_MB}M free"
10375         $LFS setstripe -c -1 $file || error "setstripe failed"
10376
10377         dd if=/dev/zero of=$file bs=1M count=$sz_MB || error "dd failed"
10378         echo Cancel LRU locks on lustre client to flush the client cache
10379         cancel_lru_locks osc
10380
10381         echo Disable read-ahead
10382         local old_RA=$($LCTL get_param -n llite.*.max_read_ahead_mb | head -n 1)
10383         $LCTL set_param -n llite.*.max_read_ahead_mb=0
10384         stack_trap "$LCTL set_param -n llite.*.max_read_ahead_mb=$old_RA" EXIT
10385         $LCTL get_param -n llite.*.max_read_ahead_mb
10386
10387         echo "Reading the test file $file with read-ahead disabled"
10388         local sz_KB=$((sz_MB * 1024 / 4))
10389         # 10485760 bytes transferred in 0.000938 secs (11179579337 bytes/sec)
10390         # 104857600 bytes (105 MB) copied, 0.00876352 s, 12.0 GB/s
10391         local raOFF=$(LANG=C dd if=$file of=/dev/null bs=4k count=$sz_KB |&
10392                       sed -e '/records/d' -e 's/.* \([0-9]*\.[0-9]*\) *s.*/\1/')
10393
10394         echo "Cancel LRU locks on lustre client to flush the client cache"
10395         cancel_lru_locks osc
10396         echo Enable read-ahead with ${ra_MB}MB
10397         $LCTL set_param -n llite.*.max_read_ahead_mb=$ra_MB
10398
10399         echo "Reading the test file $file with read-ahead enabled"
10400         local raON=$(LANG=C dd if=$file of=/dev/null bs=4k count=$sz_KB |&
10401                      sed -e '/records/d' -e 's/.* \([0-9]*\.[0-9]*\) *s.*/\1/')
10402
10403         echo "read-ahead disabled time read $raOFF"
10404         echo "read-ahead enabled time read $raON"
10405
10406         rm -f $file
10407         wait_delete_completed
10408
10409         # use awk for this check instead of bash because it handles decimals
10410         awk "{ exit !($raOFF < 1.0 || $raOFF > $raON) }" <<<"ignore_me" ||
10411                 error "readahead ${raON}s > no-readahead ${raOFF}s ${sz_MB}M"
10412 }
10413 run_test 101d "file read with and without read-ahead enabled"
10414
10415 test_101e() {
10416         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10417
10418         local file=$DIR/$tfile
10419         local size_KB=500  #KB
10420         local count=100
10421         local bsize=1024
10422
10423         local free_KB=$(df -P $DIR | tail -n 1 | awk '{ print $4 }')
10424         local need_KB=$((count * size_KB))
10425         [[ $free_KB -le $need_KB ]] &&
10426                 skip_env "Need free space $need_KB, have $free_KB"
10427
10428         echo "Creating $count ${size_KB}K test files"
10429         for ((i = 0; i < $count; i++)); do
10430                 dd if=/dev/zero of=$file.$i bs=$bsize count=$size_KB 2>/dev/null
10431         done
10432
10433         echo "Cancel LRU locks on lustre client to flush the client cache"
10434         cancel_lru_locks $OSC
10435
10436         echo "Reset readahead stats"
10437         $LCTL set_param -n llite.*.read_ahead_stats=0
10438
10439         for ((i = 0; i < $count; i++)); do
10440                 dd if=$file.$i of=/dev/null bs=$bsize count=$size_KB 2>/dev/null
10441         done
10442
10443         $LCTL get_param llite.*.max_cached_mb
10444         $LCTL get_param llite.*.read_ahead_stats
10445         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
10446                      get_named_value 'misses' | calc_total)
10447
10448         for ((i = 0; i < $count; i++)); do
10449                 rm -rf $file.$i 2>/dev/null
10450         done
10451
10452         #10000 means 20% reads are missing in readahead
10453         [[ $miss -lt 10000 ]] ||  error "misses too much for small reads"
10454 }
10455 run_test 101e "check read-ahead for small read(1k) for small files(500k)"
10456
10457 test_101f() {
10458         which iozone || skip_env "no iozone installed"
10459
10460         local old_debug=$($LCTL get_param debug)
10461         old_debug=${old_debug#*=}
10462         $LCTL set_param debug="reada mmap"
10463
10464         # create a test file
10465         iozone -i 0 -+n -r 1m -s 128m -w -f $DIR/$tfile > /dev/null 2>&1
10466
10467         echo Cancel LRU locks on lustre client to flush the client cache
10468         cancel_lru_locks osc
10469
10470         echo Reset readahead stats
10471         $LCTL set_param -n llite.*.read_ahead_stats=0
10472
10473         echo mmap read the file with small block size
10474         iozone -i 1 -u 1 -l 1 -+n -r 32k -s 128m -B -f $DIR/$tfile \
10475                 > /dev/null 2>&1
10476
10477         echo checking missing pages
10478         $LCTL get_param llite.*.read_ahead_stats
10479         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
10480                         get_named_value 'misses' | calc_total)
10481
10482         $LCTL set_param debug="$old_debug"
10483         [ $miss -lt 3 ] || error "misses too much pages ('$miss')!"
10484         rm -f $DIR/$tfile
10485 }
10486 run_test 101f "check mmap read performance"
10487
10488 test_101g_brw_size_test() {
10489         local mb=$1
10490         local pages=$((mb * 1048576 / PAGE_SIZE))
10491         local file=$DIR/$tfile
10492
10493         $LCTL set_param osc.*.max_pages_per_rpc=${mb}M ||
10494                 { error "unable to set max_pages_per_rpc=${mb}M"; return 1; }
10495         for mp in $($LCTL get_param -n osc.*.max_pages_per_rpc); do
10496                 [ $mp -ne $pages ] && error "max_pages_per_rpc $mp != $pages" &&
10497                         return 2
10498         done
10499
10500         stack_trap "rm -f $file" EXIT
10501         $LCTL set_param -n osc.*.rpc_stats=0
10502
10503         # 10 RPCs should be enough for the test
10504         local count=10
10505         dd if=/dev/zero of=$file bs=${mb}M count=$count ||
10506                 { error "dd write ${mb} MB blocks failed"; return 3; }
10507         cancel_lru_locks osc
10508         dd of=/dev/null if=$file bs=${mb}M count=$count ||
10509                 { error "dd write ${mb} MB blocks failed"; return 4; }
10510
10511         # calculate number of full-sized read and write RPCs
10512         rpcs=($($LCTL get_param -n 'osc.*.rpc_stats' |
10513                 sed -n '/pages per rpc/,/^$/p' |
10514                 awk '/'$pages':/ { reads += $2; writes += $6 }; \
10515                 END { print reads,writes }'))
10516         # allow one extra full-sized read RPC for async readahead
10517         [[ ${rpcs[0]} == $count || ${rpcs[0]} == $((count + 1)) ]] ||
10518                 { error "${rpcs[0]} != $count read RPCs"; return 5; }
10519         [[ ${rpcs[1]} == $count ]] ||
10520                 { error "${rpcs[1]} != $count write RPCs"; return 6; }
10521 }
10522
10523 test_101g() {
10524         remote_ost_nodsh && skip "remote OST with nodsh"
10525
10526         local rpcs
10527         local osts=$(get_facets OST)
10528         local list=$(comma_list $(osts_nodes))
10529         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
10530         local brw_size="obdfilter.*.brw_size"
10531
10532         $LFS setstripe -i 0 -c 1 $DIR/$tfile
10533
10534         local orig_mb=$(do_facet ost1 $LCTL get_param -n $brw_size | head -n 1)
10535
10536         if { [ $OST1_VERSION -ge $(version_code 2.8.52) ] ||
10537                 { [ $OST1_VERSION -ge $(version_code 2.7.17) ] &&
10538                   [ $OST1_VERSION -lt $(version_code 2.7.50) ]; }; } &&
10539            { [ $CLIENT_VERSION -ge $(version_code 2.8.52) ] ||
10540                 { [ $CLIENT_VERSION -ge $(version_code 2.7.17) ] &&
10541                   [ $CLIENT_VERSION -lt $(version_code 2.7.50) ]; }; }; then
10542
10543                 [ $OST1_VERSION -ge $(version_code 2.9.52) ] &&
10544                         suffix="M"
10545
10546                 if [[ $orig_mb -lt 16 ]]; then
10547                         save_lustre_params $osts "$brw_size" > $p
10548                         do_nodes $list $LCTL set_param -n $brw_size=16$suffix ||
10549                                 error "set 16MB RPC size failed"
10550
10551                         echo "remount client to enable new RPC size"
10552                         remount_client $MOUNT || error "remount_client failed"
10553                 fi
10554
10555                 test_101g_brw_size_test 16 || error "16MB RPC test failed"
10556                 # should be able to set brw_size=12, but no rpc_stats for that
10557                 test_101g_brw_size_test 8 || error "8MB RPC test failed"
10558         fi
10559
10560         test_101g_brw_size_test 4 || error "4MB RPC test failed"
10561
10562         if [[ $orig_mb -lt 16 ]]; then
10563                 restore_lustre_params < $p
10564                 remount_client $MOUNT || error "remount_client restore failed"
10565         fi
10566
10567         rm -f $p $DIR/$tfile
10568 }
10569 run_test 101g "Big bulk(4/16 MiB) readahead"
10570
10571 test_101h() {
10572         $LFS setstripe -i 0 -c 1 $DIR/$tfile
10573
10574         dd if=/dev/zero of=$DIR/$tfile bs=1M count=70 ||
10575                 error "dd 70M file failed"
10576         echo Cancel LRU locks on lustre client to flush the client cache
10577         cancel_lru_locks osc
10578
10579         echo "Reset readahead stats"
10580         $LCTL set_param -n llite.*.read_ahead_stats 0
10581
10582         echo "Read 10M of data but cross 64M bundary"
10583         dd if=$DIR/$tfile of=/dev/null bs=10M skip=6 count=1
10584         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
10585                      get_named_value 'misses' | calc_total)
10586         [ $miss -eq 1 ] || error "expected miss 1 but got $miss"
10587         rm -f $p $DIR/$tfile
10588 }
10589 run_test 101h "Readahead should cover current read window"
10590
10591 test_101i() {
10592         dd if=/dev/zero of=$DIR/$tfile bs=1M count=10 ||
10593                 error "dd 10M file failed"
10594
10595         local max_per_file_mb=$($LCTL get_param -n \
10596                 llite.*.max_read_ahead_per_file_mb 2>/dev/null)
10597         cancel_lru_locks osc
10598         stack_trap "$LCTL set_param llite.*.max_read_ahead_per_file_mb=$max_per_file_mb"
10599         $LCTL set_param llite.*.max_read_ahead_per_file_mb=1 ||
10600                 error "set max_read_ahead_per_file_mb to 1 failed"
10601
10602         echo "Reset readahead stats"
10603         $LCTL set_param llite.*.read_ahead_stats=0
10604
10605         dd if=$DIR/$tfile of=/dev/null bs=2M
10606
10607         $LCTL get_param llite.*.read_ahead_stats
10608         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
10609                      awk '/misses/ { print $2 }')
10610         [ $miss -eq 5 ] || error "expected misses 5 but got $miss"
10611         rm -f $DIR/$tfile
10612 }
10613 run_test 101i "allow current readahead to exceed reservation"
10614
10615 test_101j() {
10616         $LFS setstripe -i 0 -c 1 $DIR/$tfile ||
10617                 error "setstripe $DIR/$tfile failed"
10618         local file_size=$((1048576 * 16))
10619         local old_ra=$($LCTL get_param -n llite.*.max_read_ahead_mb | head -n 1)
10620         stack_trap "$LCTL set_param -n llite.*.max_read_ahead_mb $old_ra" EXIT
10621
10622         echo Disable read-ahead
10623         $LCTL set_param -n llite.*.max_read_ahead_mb=0
10624
10625         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$(($file_size / 1048576))
10626         for blk in $PAGE_SIZE 1048576 $file_size; do
10627                 cancel_lru_locks osc
10628                 echo "Reset readahead stats"
10629                 $LCTL set_param -n llite.*.read_ahead_stats=0
10630                 local count=$(($file_size / $blk))
10631                 dd if=$DIR/$tfile bs=$blk count=$count of=/dev/null
10632                 local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
10633                              get_named_value 'failed.to.fast.read' | calc_total)
10634                 $LCTL get_param -n llite.*.read_ahead_stats
10635                 [ $miss -eq $count ] || error "expected $count got $miss"
10636         done
10637
10638         rm -f $p $DIR/$tfile
10639 }
10640 run_test 101j "A complete read block should be submitted when no RA"
10641
10642 setup_test102() {
10643         test_mkdir $DIR/$tdir
10644         chown $RUNAS_ID $DIR/$tdir
10645         STRIPE_SIZE=65536
10646         STRIPE_OFFSET=1
10647         STRIPE_COUNT=$OSTCOUNT
10648         [[ $OSTCOUNT -gt 4 ]] && STRIPE_COUNT=4
10649
10650         trap cleanup_test102 EXIT
10651         cd $DIR
10652         $1 $LFS setstripe -S $STRIPE_SIZE -i $STRIPE_OFFSET -c $STRIPE_COUNT $tdir
10653         cd $DIR/$tdir
10654         for num in 1 2 3 4; do
10655                 for count in $(seq 1 $STRIPE_COUNT); do
10656                         for idx in $(seq 0 $[$STRIPE_COUNT - 1]); do
10657                                 local size=`expr $STRIPE_SIZE \* $num`
10658                                 local file=file"$num-$idx-$count"
10659                                 $1 $LFS setstripe -S $size -i $idx -c $count $file
10660                         done
10661                 done
10662         done
10663
10664         cd $DIR
10665         $1 tar cf $TMP/f102.tar $tdir --xattrs
10666 }
10667
10668 cleanup_test102() {
10669         trap 0
10670         rm -f $TMP/f102.tar
10671         rm -rf $DIR/d0.sanity/d102
10672 }
10673
10674 test_102a() {
10675         [ "$UID" != 0 ] && skip "must run as root"
10676         [ -z "$(lctl get_param -n mdc.*-mdc-*.connect_flags | grep xattr)" ] &&
10677                 skip_env "must have user_xattr"
10678
10679         [ -z "$(which setfattr 2>/dev/null)" ] &&
10680                 skip_env "could not find setfattr"
10681
10682         local testfile=$DIR/$tfile
10683
10684         touch $testfile
10685         echo "set/get xattr..."
10686         setfattr -n trusted.name1 -v value1 $testfile ||
10687                 error "setfattr -n trusted.name1=value1 $testfile failed"
10688         getfattr -n trusted.name1 $testfile 2> /dev/null |
10689           grep "trusted.name1=.value1" ||
10690                 error "$testfile missing trusted.name1=value1"
10691
10692         setfattr -n user.author1 -v author1 $testfile ||
10693                 error "setfattr -n user.author1=author1 $testfile failed"
10694         getfattr -n user.author1 $testfile 2> /dev/null |
10695           grep "user.author1=.author1" ||
10696                 error "$testfile missing trusted.author1=author1"
10697
10698         echo "listxattr..."
10699         setfattr -n trusted.name2 -v value2 $testfile ||
10700                 error "$testfile unable to set trusted.name2"
10701         setfattr -n trusted.name3 -v value3 $testfile ||
10702                 error "$testfile unable to set trusted.name3"
10703         [ $(getfattr -d -m "^trusted" $testfile 2> /dev/null |
10704             grep "trusted.name" | wc -l) -eq 3 ] ||
10705                 error "$testfile missing 3 trusted.name xattrs"
10706
10707         setfattr -n user.author2 -v author2 $testfile ||
10708                 error "$testfile unable to set user.author2"
10709         setfattr -n user.author3 -v author3 $testfile ||
10710                 error "$testfile unable to set user.author3"
10711         [ $(getfattr -d -m "^user" $testfile 2> /dev/null |
10712             grep "user.author" | wc -l) -eq 3 ] ||
10713                 error "$testfile missing 3 user.author xattrs"
10714
10715         echo "remove xattr..."
10716         setfattr -x trusted.name1 $testfile ||
10717                 error "$testfile error deleting trusted.name1"
10718         getfattr -d -m trusted $testfile 2> /dev/null | grep "trusted.name1" &&
10719                 error "$testfile did not delete trusted.name1 xattr"
10720
10721         setfattr -x user.author1 $testfile ||
10722                 error "$testfile error deleting user.author1"
10723         echo "set lustre special xattr ..."
10724         $LFS setstripe -c1 $testfile
10725         local lovea=$(getfattr -n "trusted.lov" -e hex $testfile |
10726                 awk -F "=" '/trusted.lov/ { print $2 }' )
10727         setfattr -n "trusted.lov" -v $lovea $testfile ||
10728                 error "$testfile doesn't ignore setting trusted.lov again"
10729         setfattr -n "trusted.lov" -v "invalid_value" $testfile &&
10730                 error "$testfile allow setting invalid trusted.lov"
10731         rm -f $testfile
10732 }
10733 run_test 102a "user xattr test =================================="
10734
10735 check_102b_layout() {
10736         local layout="$*"
10737         local testfile=$DIR/$tfile
10738
10739         echo "test layout '$layout'"
10740         $LFS setstripe $layout $testfile || error "setstripe failed"
10741         $LFS getstripe -y $testfile
10742
10743         echo "get/set/list trusted.lov xattr ..." # b=10930
10744         local value=$(getfattr -n trusted.lov -e hex $testfile | grep trusted)
10745         [[ "$value" =~ "trusted.lov" ]] ||
10746                 error "can't get trusted.lov from $testfile"
10747         local stripe_count_orig=$($LFS getstripe -c $testfile) ||
10748                 error "getstripe failed"
10749
10750         $MCREATE $testfile.2 || error "mcreate $testfile.2 failed"
10751
10752         value=$(cut -d= -f2 <<<$value)
10753         # LU-13168: truncated xattr should fail if short lov_user_md header
10754         [ $CLIENT_VERSION -lt $(version_code 2.13.53) ] &&
10755                 lens="${#value}" || lens="$(seq 4 2 ${#value})"
10756         for len in $lens; do
10757                 echo "setfattr $len $testfile.2"
10758                 setfattr -n trusted.lov -v ${value:0:$len} $testfile.2 &&
10759                         [ $len -lt 66 ] && error "short xattr len=$len worked"
10760         done
10761         local stripe_size=$($LFS getstripe -S $testfile.2)
10762         local stripe_count=$($LFS getstripe -c $testfile.2)
10763         [[ $stripe_size -eq 65536 ]] ||
10764                 error "stripe size $stripe_size != 65536"
10765         [[ $stripe_count -eq $stripe_count_orig ]] ||
10766                 error "stripe count $stripe_count != $stripe_count_orig"
10767         rm $testfile $testfile.2
10768 }
10769
10770 test_102b() {
10771         [ -z "$(which setfattr 2>/dev/null)" ] &&
10772                 skip_env "could not find setfattr"
10773         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
10774
10775         # check plain layout
10776         check_102b_layout -S 65536 -i 1 -c $OSTCOUNT
10777
10778         # and also check composite layout
10779         check_102b_layout -E 1M -S 65536 -i 1 -c $OSTCOUNT -Eeof -S4M
10780
10781 }
10782 run_test 102b "getfattr/setfattr for trusted.lov EAs"
10783
10784 test_102c() {
10785         [ -z "$(which setfattr 2>/dev/null)" ] &&
10786                 skip_env "could not find setfattr"
10787         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
10788
10789         # b10930: get/set/list lustre.lov xattr
10790         echo "get/set/list lustre.lov xattr ..."
10791         test_mkdir $DIR/$tdir
10792         chown $RUNAS_ID $DIR/$tdir
10793         local testfile=$DIR/$tdir/$tfile
10794         $RUNAS $LFS setstripe -S 65536 -i 1 -c $OSTCOUNT $testfile ||
10795                 error "setstripe failed"
10796         local STRIPECOUNT=$($RUNAS $LFS getstripe -c $testfile) ||
10797                 error "getstripe failed"
10798         $RUNAS getfattr -d -m "^lustre" $testfile 2> /dev/null | \
10799         grep "lustre.lov" || error "can't get lustre.lov from $testfile"
10800
10801         local testfile2=${testfile}2
10802         local value=`getfattr -n lustre.lov $testfile 2> /dev/null | \
10803                      grep "lustre.lov" |sed -e 's/[^=]\+=//'  `
10804
10805         $RUNAS $MCREATE $testfile2
10806         $RUNAS setfattr -n lustre.lov -v $value $testfile2
10807         local stripe_size=$($RUNAS $LFS getstripe -S $testfile2)
10808         local stripe_count=$($RUNAS $LFS getstripe -c $testfile2)
10809         [ $stripe_size -eq 65536 ] || error "stripe size $stripe_size != 65536"
10810         [ $stripe_count -eq $STRIPECOUNT ] ||
10811                 error "stripe count $stripe_count != $STRIPECOUNT"
10812 }
10813 run_test 102c "non-root getfattr/setfattr for lustre.lov EAs ==========="
10814
10815 compare_stripe_info1() {
10816         local stripe_index_all_zero=true
10817
10818         for num in 1 2 3 4; do
10819                 for count in $(seq 1 $STRIPE_COUNT); do
10820                         for offset in $(seq 0 $[$STRIPE_COUNT - 1]); do
10821                                 local size=$((STRIPE_SIZE * num))
10822                                 local file=file"$num-$offset-$count"
10823                                 stripe_size=$($LFS getstripe -S $PWD/$file)
10824                                 [[ $stripe_size -ne $size ]] &&
10825                                     error "$file: size $stripe_size != $size"
10826                                 stripe_count=$($LFS getstripe -c $PWD/$file)
10827                                 # allow fewer stripes to be created, ORI-601
10828                                 [[ $stripe_count -lt $(((3 * count + 3) / 4)) ]] &&
10829                                     error "$file: count $stripe_count != $count"
10830                                 stripe_index=$($LFS getstripe -i $PWD/$file)
10831                                 [[ $stripe_index -ne 0 ]] &&
10832                                         stripe_index_all_zero=false
10833                         done
10834                 done
10835         done
10836         $stripe_index_all_zero &&
10837                 error "all files are being extracted starting from OST index 0"
10838         return 0
10839 }
10840
10841 have_xattrs_include() {
10842         tar --help | grep -q xattrs-include &&
10843                 echo --xattrs-include="lustre.*"
10844 }
10845
10846 test_102d() {
10847         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10848         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
10849
10850         XINC=$(have_xattrs_include)
10851         setup_test102
10852         tar xf $TMP/f102.tar -C $DIR/$tdir --xattrs $XINC
10853         cd $DIR/$tdir/$tdir
10854         compare_stripe_info1
10855 }
10856 run_test 102d "tar restore stripe info from tarfile,not keep osts"
10857
10858 test_102f() {
10859         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10860         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
10861
10862         XINC=$(have_xattrs_include)
10863         setup_test102
10864         test_mkdir $DIR/$tdir.restore
10865         cd $DIR
10866         tar cf - --xattrs $tdir | tar xf - \
10867                 -C $DIR/$tdir.restore --xattrs $XINC
10868         cd $DIR/$tdir.restore/$tdir
10869         compare_stripe_info1
10870 }
10871 run_test 102f "tar copy files, not keep osts"
10872
10873 grow_xattr() {
10874         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep xattr)" ] &&
10875                 skip "must have user_xattr"
10876         [ -z "$(which setfattr 2>/dev/null)" ] &&
10877                 skip_env "could not find setfattr"
10878         [ -z "$(which getfattr 2>/dev/null)" ] &&
10879                 skip_env "could not find getfattr"
10880
10881         local xsize=${1:-1024}  # in bytes
10882         local file=$DIR/$tfile
10883         local value="$(generate_string $xsize)"
10884         local xbig=trusted.big
10885         local toobig=$2
10886
10887         touch $file
10888         log "save $xbig on $file"
10889         if [ -z "$toobig" ]
10890         then
10891                 setfattr -n $xbig -v $value $file ||
10892                         error "saving $xbig on $file failed"
10893         else
10894                 setfattr -n $xbig -v $value $file &&
10895                         error "saving $xbig on $file succeeded"
10896                 return 0
10897         fi
10898
10899         local orig=$(get_xattr_value $xbig $file)
10900         [[ "$orig" != "$value" ]] && error "$xbig different after saving $xbig"
10901
10902         local xsml=trusted.sml
10903         log "save $xsml on $file"
10904         setfattr -n $xsml -v val $file || error "saving $xsml on $file failed"
10905
10906         local new=$(get_xattr_value $xbig $file)
10907         [[ "$new" != "$orig" ]] && error "$xbig different after saving $xsml"
10908
10909         log "grow $xsml on $file"
10910         setfattr -n $xsml -v "$value" $file ||
10911                 error "growing $xsml on $file failed"
10912
10913         new=$(get_xattr_value $xbig $file)
10914         [[ "$new" != "$orig" ]] && error "$xbig different after growing $xsml"
10915         log "$xbig still valid after growing $xsml"
10916
10917         rm -f $file
10918 }
10919
10920 test_102h() { # bug 15777
10921         grow_xattr 1024
10922 }
10923 run_test 102h "grow xattr from inside inode to external block"
10924
10925 test_102ha() {
10926         large_xattr_enabled || skip_env "ea_inode feature disabled"
10927
10928         echo "setting xattr of max xattr size: $(max_xattr_size)"
10929         grow_xattr $(max_xattr_size)
10930
10931         echo "setting xattr of > max xattr size: $(max_xattr_size) + 10"
10932         echo "This should fail:"
10933         grow_xattr $(($(max_xattr_size) + 10)) 1
10934 }
10935 run_test 102ha "grow xattr from inside inode to external inode"
10936
10937 test_102i() { # bug 17038
10938         [ -z "$(which getfattr 2>/dev/null)" ] &&
10939                 skip "could not find getfattr"
10940
10941         touch $DIR/$tfile
10942         ln -s $DIR/$tfile $DIR/${tfile}link
10943         getfattr -n trusted.lov $DIR/$tfile ||
10944                 error "lgetxattr on $DIR/$tfile failed"
10945         getfattr -h -n trusted.lov $DIR/${tfile}link 2>&1 |
10946                 grep -i "no such attr" ||
10947                 error "error for lgetxattr on $DIR/${tfile}link is not ENODATA"
10948         rm -f $DIR/$tfile $DIR/${tfile}link
10949 }
10950 run_test 102i "lgetxattr test on symbolic link ============"
10951
10952 test_102j() {
10953         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10954         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
10955
10956         XINC=$(have_xattrs_include)
10957         setup_test102 "$RUNAS"
10958         chown $RUNAS_ID $DIR/$tdir
10959         $RUNAS tar xf $TMP/f102.tar -C $DIR/$tdir --xattrs $XINC
10960         cd $DIR/$tdir/$tdir
10961         compare_stripe_info1 "$RUNAS"
10962 }
10963 run_test 102j "non-root tar restore stripe info from tarfile, not keep osts ==="
10964
10965 test_102k() {
10966         [ -z "$(which setfattr 2>/dev/null)" ] &&
10967                 skip "could not find setfattr"
10968
10969         touch $DIR/$tfile
10970         # b22187 just check that does not crash for regular file.
10971         setfattr -n trusted.lov $DIR/$tfile
10972         # b22187 'setfattr -n trusted.lov' should remove LOV EA for directories
10973         local test_kdir=$DIR/$tdir
10974         test_mkdir $test_kdir
10975         local default_size=$($LFS getstripe -S $test_kdir)
10976         local default_count=$($LFS getstripe -c $test_kdir)
10977         local default_offset=$($LFS getstripe -i $test_kdir)
10978         $LFS setstripe -S 65536 -i 0 -c $OSTCOUNT $test_kdir ||
10979                 error 'dir setstripe failed'
10980         setfattr -n trusted.lov $test_kdir
10981         local stripe_size=$($LFS getstripe -S $test_kdir)
10982         local stripe_count=$($LFS getstripe -c $test_kdir)
10983         local stripe_offset=$($LFS getstripe -i $test_kdir)
10984         [ $stripe_size -eq $default_size ] ||
10985                 error "stripe size $stripe_size != $default_size"
10986         [ $stripe_count -eq $default_count ] ||
10987                 error "stripe count $stripe_count != $default_count"
10988         [ $stripe_offset -eq $default_offset ] ||
10989                 error "stripe offset $stripe_offset != $default_offset"
10990         rm -rf $DIR/$tfile $test_kdir
10991 }
10992 run_test 102k "setfattr without parameter of value shouldn't cause a crash"
10993
10994 test_102l() {
10995         [ -z "$(which getfattr 2>/dev/null)" ] &&
10996                 skip "could not find getfattr"
10997
10998         # LU-532 trusted. xattr is invisible to non-root
10999         local testfile=$DIR/$tfile
11000
11001         touch $testfile
11002
11003         echo "listxattr as user..."
11004         chown $RUNAS_ID $testfile
11005         $RUNAS getfattr -d -m '.*' $testfile 2>&1 |
11006             grep -q "trusted" &&
11007                 error "$testfile trusted xattrs are user visible"
11008
11009         return 0;
11010 }
11011 run_test 102l "listxattr size test =================================="
11012
11013 test_102m() { # LU-3403 llite: error of listxattr when buffer is small
11014         local path=$DIR/$tfile
11015         touch $path
11016
11017         listxattr_size_check $path || error "listattr_size_check $path failed"
11018 }
11019 run_test 102m "Ensure listxattr fails on small bufffer ========"
11020
11021 cleanup_test102
11022
11023 getxattr() { # getxattr path name
11024         # Return the base64 encoding of the value of xattr name on path.
11025         local path=$1
11026         local name=$2
11027
11028         # # getfattr --absolute-names --encoding=base64 --name=trusted.lov $path
11029         # file: $path
11030         # trusted.lov=0s0AvRCwEAAAAGAAAAAAAAAAAEAAACAAAAAAAQAAEAA...AAAAAAAAA=
11031         #
11032         # We print just 0s0AvRCwEAAAAGAAAAAAAAAAAEAAACAAAAAAAQAAEAA...AAAAAAAAA=
11033
11034         getfattr --absolute-names --encoding=base64 --name=$name $path |
11035                 awk -F= -v name=$name '$1 == name {
11036                         print substr($0, index($0, "=") + 1);
11037         }'
11038 }
11039
11040 test_102n() { # LU-4101 mdt: protect internal xattrs
11041         [ -z "$(which setfattr 2>/dev/null)" ] &&
11042                 skip "could not find setfattr"
11043         if [ $MDS1_VERSION -lt $(version_code 2.5.50) ]
11044         then
11045                 skip "MDT < 2.5.50 allows setxattr on internal trusted xattrs"
11046         fi
11047
11048         local file0=$DIR/$tfile.0
11049         local file1=$DIR/$tfile.1
11050         local xattr0=$TMP/$tfile.0
11051         local xattr1=$TMP/$tfile.1
11052         local namelist="lov lma lmv link fid version som hsm"
11053         local name
11054         local value
11055
11056         rm -rf $file0 $file1 $xattr0 $xattr1
11057         touch $file0 $file1
11058
11059         # Get 'before' xattrs of $file1.
11060         getfattr --absolute-names --dump --match=- $file1 > $xattr0
11061
11062         [ $MDS1_VERSION -lt $(version_code 2.8.53) ] &&
11063                 namelist+=" lfsck_namespace"
11064         for name in $namelist; do
11065                 # Try to copy xattr from $file0 to $file1.
11066                 value=$(getxattr $file0 trusted.$name 2> /dev/null)
11067
11068                 setfattr --name=trusted.$name --value="$value" $file1 ||
11069                         error "setxattr 'trusted.$name' failed"
11070
11071                 # Try to set a garbage xattr.
11072                 value=0sVGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIGl0c2VsZi4=
11073
11074                 if [[ x$name == "xlov" ]]; then
11075                         setfattr --name=trusted.lov --value="$value" $file1 &&
11076                         error "setxattr invalid 'trusted.lov' success"
11077                 else
11078                         setfattr --name=trusted.$name --value="$value" $file1 ||
11079                                 error "setxattr invalid 'trusted.$name' failed"
11080                 fi
11081
11082                 # Try to remove the xattr from $file1. We don't care if this
11083                 # appears to succeed or fail, we just don't want there to be
11084                 # any changes or crashes.
11085                 setfattr --remove=$trusted.$name $file1 2> /dev/null
11086         done
11087
11088         if [ $MDS1_VERSION -gt $(version_code 2.6.50) ]
11089         then
11090                 name="lfsck_ns"
11091                 # Try to copy xattr from $file0 to $file1.
11092                 value=$(getxattr $file0 trusted.$name 2> /dev/null)
11093
11094                 setfattr --name=trusted.$name --value="$value" $file1 ||
11095                         error "setxattr 'trusted.$name' failed"
11096
11097                 # Try to set a garbage xattr.
11098                 value=0sVGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIGl0c2VsZi4=
11099
11100                 setfattr --name=trusted.$name --value="$value" $file1 ||
11101                         error "setxattr 'trusted.$name' failed"
11102
11103                 # Try to remove the xattr from $file1. We don't care if this
11104                 # appears to succeed or fail, we just don't want there to be
11105                 # any changes or crashes.
11106                 setfattr --remove=$trusted.$name $file1 2> /dev/null
11107         fi
11108
11109         # Get 'after' xattrs of file1.
11110         getfattr --absolute-names --dump --match=- $file1 > $xattr1
11111
11112         if ! diff $xattr0 $xattr1; then
11113                 error "before and after xattrs of '$file1' differ"
11114         fi
11115
11116         rm -rf $file0 $file1 $xattr0 $xattr1
11117
11118         return 0
11119 }
11120 run_test 102n "silently ignore setxattr on internal trusted xattrs"
11121
11122 test_102p() { # LU-4703 setxattr did not check ownership
11123         [ $MDS1_VERSION -lt $(version_code 2.5.56) ] &&
11124                 skip "MDS needs to be at least 2.5.56"
11125
11126         local testfile=$DIR/$tfile
11127
11128         touch $testfile
11129
11130         echo "setfacl as user..."
11131         $RUNAS setfacl -m "u:$RUNAS_ID:rwx" $testfile
11132         [ $? -ne 0 ] || error "setfacl by $RUNAS_ID was allowed on $testfile"
11133
11134         echo "setfattr as user..."
11135         setfacl -m "u:$RUNAS_ID:---" $testfile
11136         $RUNAS setfattr -x system.posix_acl_access $testfile
11137         [ $? -ne 0 ] || error "setfattr by $RUNAS_ID was allowed on $testfile"
11138 }
11139 run_test 102p "check setxattr(2) correctly fails without permission"
11140
11141 test_102q() {
11142         [ $MDS1_VERSION -lt $(version_code 2.6.92) ] &&
11143                 skip "MDS needs to be at least 2.6.92"
11144
11145         orphan_linkea_check $DIR/$tfile || error "orphan_linkea_check"
11146 }
11147 run_test 102q "flistxattr should not return trusted.link EAs for orphans"
11148
11149 test_102r() {
11150         [ $MDS1_VERSION -lt $(version_code 2.6.93) ] &&
11151                 skip "MDS needs to be at least 2.6.93"
11152
11153         touch $DIR/$tfile || error "touch"
11154         setfattr -n user.$(basename $tfile) $DIR/$tfile || error "setfattr"
11155         getfattr -n user.$(basename $tfile) $DIR/$tfile || error "getfattr"
11156         rm $DIR/$tfile || error "rm"
11157
11158         #normal directory
11159         mkdir -p $DIR/$tdir || error "mkdir"
11160         setfattr -n user.$(basename $tdir) $DIR/$tdir || error "setfattr dir"
11161         getfattr -n user.$(basename $tdir) $DIR/$tdir || error "getfattr dir"
11162         setfattr -x user.$(basename $tdir) $DIR/$tdir ||
11163                 error "$testfile error deleting user.author1"
11164         getfattr -d -m user.$(basename $tdir) 2> /dev/null |
11165                 grep "user.$(basename $tdir)" &&
11166                 error "$tdir did not delete user.$(basename $tdir)"
11167         rmdir $DIR/$tdir || error "rmdir"
11168
11169         #striped directory
11170         test_mkdir $DIR/$tdir
11171         setfattr -n user.$(basename $tdir) $DIR/$tdir || error "setfattr dir"
11172         getfattr -n user.$(basename $tdir) $DIR/$tdir || error "getfattr dir"
11173         setfattr -x user.$(basename $tdir) $DIR/$tdir ||
11174                 error "$testfile error deleting user.author1"
11175         getfattr -d -m user.$(basename $tdir) 2> /dev/null |
11176                 grep "user.$(basename $tdir)" &&
11177                 error "$tdir did not delete user.$(basename $tdir)"
11178         rmdir $DIR/$tdir || error "rm striped dir"
11179 }
11180 run_test 102r "set EAs with empty values"
11181
11182 test_102s() {
11183         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
11184                 skip "MDS needs to be at least 2.11.52"
11185
11186         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
11187
11188         save_lustre_params client "llite.*.xattr_cache" > $save
11189
11190         for cache in 0 1; do
11191                 lctl set_param llite.*.xattr_cache=$cache
11192
11193                 rm -f $DIR/$tfile
11194                 touch $DIR/$tfile || error "touch"
11195                 for prefix in lustre security system trusted user; do
11196                         # Note getxattr() may fail with 'Operation not
11197                         # supported' or 'No such attribute' depending
11198                         # on prefix and cache.
11199                         getfattr -n $prefix.n102s $DIR/$tfile &&
11200                                 error "getxattr '$prefix.n102s' should fail (cache = $cache)"
11201                 done
11202         done
11203
11204         restore_lustre_params < $save
11205 }
11206 run_test 102s "getting nonexistent xattrs should fail"
11207
11208 test_102t() {
11209         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
11210                 skip "MDS needs to be at least 2.11.52"
11211
11212         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
11213
11214         save_lustre_params client "llite.*.xattr_cache" > $save
11215
11216         for cache in 0 1; do
11217                 lctl set_param llite.*.xattr_cache=$cache
11218
11219                 for buf_size in 0 256; do
11220                         rm -f $DIR/$tfile
11221                         touch $DIR/$tfile || error "touch"
11222                         setfattr -n user.multiop $DIR/$tfile
11223                         $MULTIOP $DIR/$tfile oa$buf_size ||
11224                                 error "cannot get zero length xattr value (buf_size = $buf_size)"
11225                 done
11226         done
11227
11228         restore_lustre_params < $save
11229 }
11230 run_test 102t "zero length xattr values handled correctly"
11231
11232 run_acl_subtest()
11233 {
11234     $LUSTRE/tests/acl/run $LUSTRE/tests/acl/$1.test
11235     return $?
11236 }
11237
11238 test_103a() {
11239         [ "$UID" != 0 ] && skip "must run as root"
11240         $GSS && skip_env "could not run under gss"
11241         [ -z "$(lctl get_param -n mdc.*-mdc-*.connect_flags | grep acl)" ] &&
11242                 skip_env "must have acl enabled"
11243         [ -z "$(which setfacl 2>/dev/null)" ] &&
11244                 skip_env "could not find setfacl"
11245         remote_mds_nodsh && skip "remote MDS with nodsh"
11246
11247         gpasswd -a daemon bin                           # LU-5641
11248         do_facet $SINGLEMDS gpasswd -a daemon bin       # LU-5641
11249
11250         declare -a identity_old
11251
11252         for num in $(seq $MDSCOUNT); do
11253                 switch_identity $num true || identity_old[$num]=$?
11254         done
11255
11256         SAVE_UMASK=$(umask)
11257         umask 0022
11258         mkdir -p $DIR/$tdir
11259         cd $DIR/$tdir
11260
11261         echo "performing cp ..."
11262         run_acl_subtest cp || error "run_acl_subtest cp failed"
11263         echo "performing getfacl-noacl..."
11264         run_acl_subtest getfacl-noacl || error "getfacl-noacl test failed"
11265         echo "performing misc..."
11266         run_acl_subtest misc || error  "misc test failed"
11267         echo "performing permissions..."
11268         run_acl_subtest permissions || error "permissions failed"
11269         # LU-1482 mdd: Setting xattr are properly checked with and without ACLs
11270         if [ $MDS1_VERSION -gt $(version_code 2.8.55) ] ||
11271                 { [ $MDS1_VERSION -lt $(version_code 2.6) ] &&
11272                         [ $MDS1_VERSION -ge $(version_code 2.5.29) ]; }
11273         then
11274                 echo "performing permissions xattr..."
11275                 run_acl_subtest permissions_xattr ||
11276                         error "permissions_xattr failed"
11277         fi
11278         echo "performing setfacl..."
11279         run_acl_subtest setfacl || error  "setfacl test failed"
11280
11281         # inheritance test got from HP
11282         echo "performing inheritance..."
11283         cp $LUSTRE/tests/acl/make-tree . || error "cannot copy make-tree"
11284         chmod +x make-tree || error "chmod +x failed"
11285         run_acl_subtest inheritance || error "inheritance test failed"
11286         rm -f make-tree
11287
11288         echo "LU-974 ignore umask when acl is enabled..."
11289         run_acl_subtest 974 || error "LU-974 umask test failed"
11290         if [ $MDSCOUNT -ge 2 ]; then
11291                 run_acl_subtest 974_remote ||
11292                         error "LU-974 umask test failed under remote dir"
11293         fi
11294
11295         echo "LU-2561 newly created file is same size as directory..."
11296         if [ "$mds1_FSTYPE" != "zfs" ]; then
11297                 run_acl_subtest 2561 || error "LU-2561 test failed"
11298         else
11299                 run_acl_subtest 2561_zfs || error "LU-2561 zfs test failed"
11300         fi
11301
11302         run_acl_subtest 4924 || error "LU-4924 test failed"
11303
11304         cd $SAVE_PWD
11305         umask $SAVE_UMASK
11306
11307         for num in $(seq $MDSCOUNT); do
11308                 if [ "${identity_old[$num]}" = 1 ]; then
11309                         switch_identity $num false || identity_old[$num]=$?
11310                 fi
11311         done
11312 }
11313 run_test 103a "acl test"
11314
11315 test_103b() {
11316         declare -a pids
11317         local U
11318
11319         for U in {0..511}; do
11320                 {
11321                 local O=$(printf "%04o" $U)
11322
11323                 umask $(printf "%04o" $((511 ^ $O)))
11324                 $LFS setstripe -c 1 $DIR/$tfile.s$O
11325                 local S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.s$O))
11326
11327                 (( $S == ($O & 0666) )) ||
11328                         error "lfs setstripe $DIR/$tfile.s$O '$S' != '$O'"
11329
11330                 $LFS setstripe -E16M -c 1 -E1G -S4M $DIR/$tfile.p$O
11331                 S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.p$O))
11332                 (( $S == ($O & 0666) )) ||
11333                         error "lfs setstripe -E $DIR/$tfile.p$O '$S' != '$O'"
11334
11335                 $LFS setstripe -N2 -c 1 $DIR/$tfile.m$O
11336                 S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.m$O))
11337                 (( $S == ($O & 0666) )) ||
11338                         error "lfs setstripe -N2 $DIR/$tfile.m$O '$S' != '$O'"
11339                 rm -f $DIR/$tfile.[smp]$0
11340                 } &
11341                 local pid=$!
11342
11343                 # limit the concurrently running threads to 64. LU-11878
11344                 local idx=$((U % 64))
11345                 [ -z "${pids[idx]}" ] || wait ${pids[idx]}
11346                 pids[idx]=$pid
11347         done
11348         wait
11349 }
11350 run_test 103b "umask lfs setstripe"
11351
11352 test_103c() {
11353         mkdir -p $DIR/$tdir
11354         cp -rp $DIR/$tdir $DIR/$tdir.bak
11355
11356         [ -n "$(getfattr -d -m. $DIR/$tdir | grep posix_acl_default)" ] &&
11357                 error "$DIR/$tdir shouldn't contain default ACL"
11358         [ -n "$(getfattr -d -m. $DIR/$tdir.bak | grep posix_acl_default)" ] &&
11359                 error "$DIR/$tdir.bak shouldn't contain default ACL"
11360         true
11361 }
11362 run_test 103c "'cp -rp' won't set empty acl"
11363
11364 test_103e() {
11365         local numacl
11366         local fileacl
11367         local saved_debug=$($LCTL get_param -n debug)
11368
11369         (( $MDS1_VERSION >= $(version_code 2.14.0) )) ||
11370                 skip "MDS needs to be at least 2.14.0"
11371
11372         large_xattr_enabled || skip_env "ea_inode feature disabled"
11373
11374         mkdir -p $DIR/$tdir
11375         # add big LOV EA to cause reply buffer overflow earlier
11376         $LFS setstripe -C 1000 $DIR/$tdir
11377         lctl set_param mdc.*-mdc*.stats=clear
11378
11379         $LCTL set_param debug=0
11380         stack_trap "$LCTL set_param debug=\"$saved_debug\"" EXIT
11381         stack_trap "$LCTL get_param mdc.*-mdc*.stats" EXIT
11382
11383         # add a large number of default ACLs (expect 8000+ for 2.13+)
11384         for U in {2..7000}; do
11385                 setfacl -d -m user:$U:rwx $DIR/$tdir ||
11386                         error "Able to add just $U default ACLs"
11387         done
11388         numacl=$(getfacl $DIR/$tdir |& grep -c "default:user")
11389         echo "$numacl default ACLs created"
11390
11391         stat $DIR/$tdir || error "Cannot stat directory"
11392         # check file creation
11393         touch $DIR/$tdir/$tfile ||
11394                 error "failed to create $tfile with $numacl default ACLs"
11395         stat $DIR/$tdir/$tfile  || error "Cannot stat file"
11396         fileacl=$(getfacl $DIR/$tdir/$tfile |& grep -c "user:")
11397         echo "$fileacl ACLs were inherited"
11398         (( $fileacl == $numacl )) ||
11399                 error "Not all default ACLs were inherited: $numacl != $fileacl"
11400         # check that new ACLs creation adds new ACLs to inherited ACLs
11401         setfacl -m user:19000:rwx $DIR/$tdir/$tfile ||
11402                 error "Cannot set new ACL"
11403         numacl=$((numacl + 1))
11404         fileacl=$(getfacl $DIR/$tdir/$tfile |& grep -c "user:")
11405         (( $fileacl == $numacl )) ||
11406                 error "failed to add new ACL: $fileacl != $numacl as expected"
11407         # adds more ACLs to a file to reach their maximum at 8000+
11408         numacl=0
11409         for U in {20000..25000}; do
11410                 setfacl -m user:$U:rwx $DIR/$tdir/$tfile || break
11411                 numacl=$((numacl + 1))
11412         done
11413         echo "Added $numacl more ACLs to the file"
11414         fileacl=$(getfacl $DIR/$tdir/$tfile |& grep -c "user:")
11415         echo "Total $fileacl ACLs in file"
11416         stat $DIR/$tdir/$tfile > /dev/null || error "Cannot stat file"
11417         rm -f $DIR/$tdir/$tfile || error "Cannot remove file"
11418         rmdir $DIR/$tdir || error "Cannot remove directory"
11419 }
11420 run_test 103e "inheritance of big amount of default ACLs"
11421
11422 test_103f() {
11423         (( $MDS1_VERSION >= $(version_code 2.14.51) )) ||
11424                 skip "MDS needs to be at least 2.14.51"
11425
11426         large_xattr_enabled || skip_env "ea_inode feature disabled"
11427
11428         # enable changelog to consume more internal MDD buffers
11429         changelog_register
11430
11431         mkdir -p $DIR/$tdir
11432         # add big LOV EA
11433         $LFS setstripe -C 1000 $DIR/$tdir
11434         setfacl -d -m user:$U:rwx $DIR/$tdir || error "Cannot add default ACLs"
11435         mkdir $DIR/$tdir/inherited || error "failed to create subdirectory"
11436         rmdir $DIR/$tdir/inherited || error "Cannot remove subdirectory"
11437         rmdir $DIR/$tdir || error "Cannot remove directory"
11438 }
11439 run_test 103f "changelog doesn't interfere with default ACLs buffers"
11440
11441 test_104a() {
11442         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11443
11444         touch $DIR/$tfile
11445         lfs df || error "lfs df failed"
11446         lfs df -ih || error "lfs df -ih failed"
11447         lfs df -h $DIR || error "lfs df -h $DIR failed"
11448         lfs df -i $DIR || error "lfs df -i $DIR failed"
11449         lfs df $DIR/$tfile || error "lfs df $DIR/$tfile failed"
11450         lfs df -ih $DIR/$tfile || error "lfs df -ih $DIR/$tfile failed"
11451
11452         local OSC=$(lctl dl | grep OST0000-osc-[^M] | awk '{ print $4 }')
11453         lctl --device %$OSC deactivate
11454         lfs df || error "lfs df with deactivated OSC failed"
11455         lctl --device %$OSC activate
11456         # wait the osc back to normal
11457         wait_osc_import_ready client ost
11458
11459         lfs df || error "lfs df with reactivated OSC failed"
11460         rm -f $DIR/$tfile
11461 }
11462 run_test 104a "lfs df [-ih] [path] test ========================="
11463
11464 test_104b() {
11465         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11466         [ $RUNAS_ID -eq $UID ] &&
11467                 skip_env "RUNAS_ID = UID = $UID -- skipping"
11468
11469         denied_cnt=$(($($RUNAS $LFS check servers 2>&1 |
11470                         grep "Permission denied" | wc -l)))
11471         if [ $denied_cnt -ne 0 ]; then
11472                 error "lfs check servers test failed"
11473         fi
11474 }
11475 run_test 104b "$RUNAS lfs check servers test ===================="
11476
11477 #
11478 # Verify $1 is within range of $2.
11479 # Success when $1 is within range. That is, when $1 is >= 2% of $2 and
11480 # $1 is <= 2% of $2. Else Fail.
11481 #
11482 value_in_range() {
11483         # Strip all units (M, G, T)
11484         actual=$(echo $1 | tr -d A-Z)
11485         expect=$(echo $2 | tr -d A-Z)
11486
11487         expect_lo=$(($expect * 98 / 100)) # 2% below
11488         expect_hi=$(($expect * 102 / 100)) # 2% above
11489
11490         # permit 2% drift above and below
11491         (( $actual >= $expect_lo && $actual <= $expect_hi ))
11492 }
11493
11494 test_104c() {
11495         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11496         [ "$ost1_FSTYPE" == "zfs" ] || skip "zfs only test"
11497
11498         local ost_param="osd-zfs.$FSNAME-OST0000."
11499         local mdt_param="osd-zfs.$FSNAME-MDT0000."
11500         local ofacets=$(get_facets OST)
11501         local mfacets=$(get_facets MDS)
11502         local saved_ost_blocks=
11503         local saved_mdt_blocks=
11504
11505         echo "Before recordsize change"
11506         lfs_df=($($LFS df -h | grep "filesystem_summary:"))
11507         df=($(df -h | grep "/mnt/lustre"$))
11508
11509         # For checking.
11510         echo "lfs output : ${lfs_df[*]}"
11511         echo "df  output : ${df[*]}"
11512
11513         for facet in ${ofacets//,/ }; do
11514                 if [ -z $saved_ost_blocks ]; then
11515                         saved_ost_blocks=$(do_facet $facet \
11516                                 lctl get_param -n $ost_param.blocksize)
11517                         echo "OST Blocksize: $saved_ost_blocks"
11518                 fi
11519                 ost=$(do_facet $facet lctl get_param -n $ost_param.mntdev)
11520                 do_facet $facet zfs set recordsize=32768 $ost
11521         done
11522
11523         # BS too small. Sufficient for functional testing.
11524         for facet in ${mfacets//,/ }; do
11525                 if [ -z $saved_mdt_blocks ]; then
11526                         saved_mdt_blocks=$(do_facet $facet \
11527                                 lctl get_param -n $mdt_param.blocksize)
11528                         echo "MDT Blocksize: $saved_mdt_blocks"
11529                 fi
11530                 mdt=$(do_facet $facet lctl get_param -n $mdt_param.mntdev)
11531                 do_facet $facet zfs set recordsize=32768 $mdt
11532         done
11533
11534         # Give new values chance to reflect change
11535         sleep 2
11536
11537         echo "After recordsize change"
11538         lfs_df_after=($($LFS df -h | grep "filesystem_summary:"))
11539         df_after=($(df -h | grep "/mnt/lustre"$))
11540
11541         # For checking.
11542         echo "lfs output : ${lfs_df_after[*]}"
11543         echo "df  output : ${df_after[*]}"
11544
11545         # Verify lfs df
11546         value_in_range ${lfs_df_after[1]%.*} ${lfs_df[1]%.*} ||
11547                 error "lfs_df bytes: ${lfs_df_after[1]%.*} != ${lfs_df[1]%.*}"
11548         value_in_range ${lfs_df_after[2]%.*} ${lfs_df[2]%.*} ||
11549                 error "lfs_df used: ${lfs_df_after[2]%.*} != ${lfs_df[2]%.*}"
11550         value_in_range ${lfs_df_after[3]%.*} ${lfs_df[3]%.*} ||
11551                 error "lfs_df avail: ${lfs_df_after[3]%.*} != ${lfs_df[3]%.*}"
11552
11553         # Verify df
11554         value_in_range ${df_after[1]%.*} ${df[1]%.*} ||
11555                 error "df bytes: ${df_after[1]%.*} != ${df[1]%.*}"
11556         value_in_range ${df_after[2]%.*} ${df[2]%.*} ||
11557                 error "df used: ${df_after[2]%.*} != ${df[2]%.*}"
11558         value_in_range ${df_after[3]%.*} ${df[3]%.*} ||
11559                 error "df avail: ${df_after[3]%.*} != ${df[3]%.*}"
11560
11561         # Restore MDT recordize back to original
11562         for facet in ${mfacets//,/ }; do
11563                 mdt=$(do_facet $facet lctl get_param -n $mdt_param.mntdev)
11564                 do_facet $facet zfs set recordsize=$saved_mdt_blocks $mdt
11565         done
11566
11567         # Restore OST recordize back to original
11568         for facet in ${ofacets//,/ }; do
11569                 ost=$(do_facet $facet lctl get_param -n $ost_param.mntdev)
11570                 do_facet $facet zfs set recordsize=$saved_ost_blocks $ost
11571         done
11572
11573         return 0
11574 }
11575 run_test 104c "Verify df vs lfs_df stays same after recordsize change"
11576
11577 test_105a() {
11578         # doesn't work on 2.4 kernels
11579         touch $DIR/$tfile
11580         if $(flock_is_enabled); then
11581                 flocks_test 1 on -f $DIR/$tfile || error "fail flock on"
11582         else
11583                 flocks_test 1 off -f $DIR/$tfile || error "fail flock off"
11584         fi
11585         rm -f $DIR/$tfile
11586 }
11587 run_test 105a "flock when mounted without -o flock test ========"
11588
11589 test_105b() {
11590         touch $DIR/$tfile
11591         if $(flock_is_enabled); then
11592                 flocks_test 1 on -c $DIR/$tfile || error "fail flock on"
11593         else
11594                 flocks_test 1 off -c $DIR/$tfile || error "fail flock off"
11595         fi
11596         rm -f $DIR/$tfile
11597 }
11598 run_test 105b "fcntl when mounted without -o flock test ========"
11599
11600 test_105c() {
11601         touch $DIR/$tfile
11602         if $(flock_is_enabled); then
11603                 flocks_test 1 on -l $DIR/$tfile || error "fail flock on"
11604         else
11605                 flocks_test 1 off -l $DIR/$tfile || error "fail flock off"
11606         fi
11607         rm -f $DIR/$tfile
11608 }
11609 run_test 105c "lockf when mounted without -o flock test"
11610
11611 test_105d() { # bug 15924
11612         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11613
11614         test_mkdir $DIR/$tdir
11615         flock_is_enabled || skip_env "mount w/o flock enabled"
11616         #define OBD_FAIL_LDLM_CP_CB_WAIT  0x315
11617         $LCTL set_param fail_loc=0x80000315
11618         flocks_test 2 $DIR/$tdir
11619 }
11620 run_test 105d "flock race (should not freeze) ========"
11621
11622 test_105e() { # bug 22660 && 22040
11623         flock_is_enabled || skip_env "mount w/o flock enabled"
11624
11625         touch $DIR/$tfile
11626         flocks_test 3 $DIR/$tfile
11627 }
11628 run_test 105e "Two conflicting flocks from same process"
11629
11630 test_106() { #bug 10921
11631         test_mkdir $DIR/$tdir
11632         $DIR/$tdir && error "exec $DIR/$tdir succeeded"
11633         chmod 777 $DIR/$tdir || error "chmod $DIR/$tdir failed"
11634 }
11635 run_test 106 "attempt exec of dir followed by chown of that dir"
11636
11637 test_107() {
11638         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11639
11640         CDIR=`pwd`
11641         local file=core
11642
11643         cd $DIR
11644         rm -f $file
11645
11646         local save_pattern=$(sysctl -n kernel.core_pattern)
11647         local save_uses_pid=$(sysctl -n kernel.core_uses_pid)
11648         sysctl -w kernel.core_pattern=$file
11649         sysctl -w kernel.core_uses_pid=0
11650
11651         ulimit -c unlimited
11652         sleep 60 &
11653         SLEEPPID=$!
11654
11655         sleep 1
11656
11657         kill -s 11 $SLEEPPID
11658         wait $SLEEPPID
11659         if [ -e $file ]; then
11660                 size=`stat -c%s $file`
11661                 [ $size -eq 0 ] && error "Fail to create core file $file"
11662         else
11663                 error "Fail to create core file $file"
11664         fi
11665         rm -f $file
11666         sysctl -w kernel.core_pattern=$save_pattern
11667         sysctl -w kernel.core_uses_pid=$save_uses_pid
11668         cd $CDIR
11669 }
11670 run_test 107 "Coredump on SIG"
11671
11672 test_110() {
11673         test_mkdir $DIR/$tdir
11674         test_mkdir $DIR/$tdir/$(str_repeat 'a' 255)
11675         $LFS mkdir -c $MDSCOUNT $DIR/$tdir/$(str_repeat 'b' 256) &&
11676                 error "mkdir with 256 char should fail, but did not"
11677         touch $DIR/$tdir/$(str_repeat 'x' 255) ||
11678                 error "create with 255 char failed"
11679         touch $DIR/$tdir/$(str_repeat 'y' 256) &&
11680                 error "create with 256 char should fail, but did not"
11681
11682         ls -l $DIR/$tdir
11683         rm -rf $DIR/$tdir
11684 }
11685 run_test 110 "filename length checking"
11686
11687 #
11688 # Purpose: To verify dynamic thread (OSS) creation.
11689 #
11690 test_115() {
11691         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11692         remote_ost_nodsh && skip "remote OST with nodsh"
11693
11694         # Lustre does not stop service threads once they are started.
11695         # Reset number of running threads to default.
11696         stopall
11697         setupall
11698
11699         local OSTIO_pre
11700         local save_params="$TMP/sanity-$TESTNAME.parameters"
11701
11702         # Get ll_ost_io count before I/O
11703         OSTIO_pre=$(do_facet ost1 \
11704                 "$LCTL get_param ost.OSS.ost_io.threads_started | cut -d= -f2")
11705         # Exit if lustre is not running (ll_ost_io not running).
11706         [ -z "$OSTIO_pre" ] && error "no OSS threads"
11707
11708         echo "Starting with $OSTIO_pre threads"
11709         local thread_max=$((OSTIO_pre * 2))
11710         local rpc_in_flight=$((thread_max * 2))
11711         # Number of I/O Process proposed to be started.
11712         local nfiles
11713         local facets=$(get_facets OST)
11714
11715         save_lustre_params client "osc.*OST*.max_rpcs_in_flight" > $save_params
11716         save_lustre_params $facets "ost.OSS.ost_io.threads_max" >> $save_params
11717
11718         # Set in_flight to $rpc_in_flight
11719         $LCTL set_param osc.*OST*.max_rpcs_in_flight=$rpc_in_flight ||
11720                 error "Failed to set max_rpcs_in_flight to $rpc_in_flight"
11721         nfiles=${rpc_in_flight}
11722         # Set ost thread_max to $thread_max
11723         do_facet ost1 "$LCTL set_param ost.OSS.ost_io.threads_max=$thread_max"
11724
11725         # 5 Minutes should be sufficient for max number of OSS
11726         # threads(thread_max) to be created.
11727         local timeout=300
11728
11729         # Start I/O.
11730         local WTL=${WTL:-"$LUSTRE/tests/write_time_limit"}
11731         test_mkdir $DIR/$tdir
11732         for i in $(seq $nfiles); do
11733                 local file=$DIR/$tdir/${tfile}-$i
11734                 $LFS setstripe -c -1 -i 0 $file
11735                 ($WTL $file $timeout)&
11736         done
11737
11738         # I/O Started - Wait for thread_started to reach thread_max or report
11739         # error if thread_started is more than thread_max.
11740         echo "Waiting for thread_started to reach thread_max"
11741         local thread_started=0
11742         local end_time=$((SECONDS + timeout))
11743
11744         while [ $SECONDS -le $end_time ] ; do
11745                 echo -n "."
11746                 # Get ost i/o thread_started count.
11747                 thread_started=$(do_facet ost1 \
11748                         "$LCTL get_param \
11749                         ost.OSS.ost_io.threads_started | cut -d= -f2")
11750                 # Break out if thread_started is equal/greater than thread_max
11751                 if [[ $thread_started -ge $thread_max ]]; then
11752                         echo ll_ost_io thread_started $thread_started, \
11753                                 equal/greater than thread_max $thread_max
11754                         break
11755                 fi
11756                 sleep 1
11757         done
11758
11759         # Cleanup - We have the numbers, Kill i/o jobs if running.
11760         jobcount=($(jobs -p))
11761         for i in $(seq 0 $((${#jobcount[@]}-1)))
11762         do
11763                 kill -9 ${jobcount[$i]}
11764                 if [ $? -ne 0 ] ; then
11765                         echo Warning: \
11766                         Failed to Kill \'WTL\(I/O\)\' with pid ${jobcount[$i]}
11767                 fi
11768         done
11769
11770         # Cleanup files left by WTL binary.
11771         for i in $(seq $nfiles); do
11772                 local file=$DIR/$tdir/${tfile}-$i
11773                 rm -rf $file
11774                 if [ $? -ne 0 ] ; then
11775                         echo "Warning: Failed to delete file $file"
11776                 fi
11777         done
11778
11779         restore_lustre_params <$save_params
11780         rm -f $save_params || echo "Warning: delete file '$save_params' failed"
11781
11782         # Error out if no new thread has started or Thread started is greater
11783         # than thread max.
11784         if [[ $thread_started -le $OSTIO_pre ||
11785                         $thread_started -gt $thread_max ]]; then
11786                 error "ll_ost_io: thread_started $thread_started" \
11787                       "OSTIO_pre $OSTIO_pre, thread_max $thread_max." \
11788                       "No new thread started or thread started greater " \
11789                       "than thread_max."
11790         fi
11791 }
11792 run_test 115 "verify dynamic thread creation===================="
11793
11794 free_min_max () {
11795         wait_delete_completed
11796         AVAIL=($(lctl get_param -n osc.*[oO][sS][cC]-[^M]*.kbytesavail))
11797         echo "OST kbytes available: ${AVAIL[@]}"
11798         MAXV=${AVAIL[0]}
11799         MAXI=0
11800         MINV=${AVAIL[0]}
11801         MINI=0
11802         for ((i = 0; i < ${#AVAIL[@]}; i++)); do
11803                 #echo OST $i: ${AVAIL[i]}kb
11804                 if [[ ${AVAIL[i]} -gt $MAXV ]]; then
11805                         MAXV=${AVAIL[i]}
11806                         MAXI=$i
11807                 fi
11808                 if [[ ${AVAIL[i]} -lt $MINV ]]; then
11809                         MINV=${AVAIL[i]}
11810                         MINI=$i
11811                 fi
11812         done
11813         echo "Min free space: OST $MINI: $MINV"
11814         echo "Max free space: OST $MAXI: $MAXV"
11815 }
11816
11817 test_116a() { # was previously test_116()
11818         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11819         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11820         remote_mds_nodsh && skip "remote MDS with nodsh"
11821
11822         echo -n "Free space priority "
11823         do_facet $SINGLEMDS lctl get_param -n lo[vd].*-mdtlov.qos_prio_free |
11824                 head -n1
11825         declare -a AVAIL
11826         free_min_max
11827
11828         [ $MINV -eq 0 ] && skip "no free space in OST$MINI, skip"
11829         [ $MINV -gt 10000000 ] && skip "too much free space in OST$MINI, skip"
11830         trap simple_cleanup_common EXIT
11831
11832         # Check if we need to generate uneven OSTs
11833         test_mkdir -p $DIR/$tdir/OST${MINI}
11834         local FILL=$((MINV / 4))
11835         local DIFF=$((MAXV - MINV))
11836         local DIFF2=$((DIFF * 100 / MINV))
11837
11838         local threshold=$(do_facet $SINGLEMDS \
11839                 lctl get_param -n *.*MDT0000-mdtlov.qos_threshold_rr | head -n1)
11840         threshold=${threshold%%%}
11841         echo -n "Check for uneven OSTs: "
11842         echo -n "diff=${DIFF}KB (${DIFF2}%) must be > ${threshold}% ..."
11843
11844         if [[ $DIFF2 -gt $threshold ]]; then
11845                 echo "ok"
11846                 echo "Don't need to fill OST$MINI"
11847         else
11848                 # generate uneven OSTs. Write 2% over the QOS threshold value
11849                 echo "no"
11850                 DIFF=$((threshold - DIFF2 + 2))
11851                 DIFF2=$((MINV * DIFF / 100))
11852                 echo "Fill $DIFF% remaining space in OST$MINI with ${DIFF2}KB"
11853                 $LFS setstripe -i $MINI -c 1 $DIR/$tdir/OST${MINI} ||
11854                         error "setstripe failed"
11855                 DIFF=$((DIFF2 / 2048))
11856                 i=0
11857                 while [ $i -lt $DIFF ]; do
11858                         i=$((i + 1))
11859                         dd if=/dev/zero of=$DIR/$tdir/OST${MINI}/$tfile-$i \
11860                                 bs=2M count=1 2>/dev/null
11861                         echo -n .
11862                 done
11863                 echo .
11864                 sync
11865                 sleep_maxage
11866                 free_min_max
11867         fi
11868
11869         DIFF=$((MAXV - MINV))
11870         DIFF2=$((DIFF * 100 / MINV))
11871         echo -n "diff=$DIFF=$DIFF2% must be > $threshold% for QOS mode..."
11872         if [ $DIFF2 -gt $threshold ]; then
11873                 echo "ok"
11874         else
11875                 echo "failed - QOS mode won't be used"
11876                 simple_cleanup_common
11877                 skip "QOS imbalance criteria not met"
11878         fi
11879
11880         MINI1=$MINI
11881         MINV1=$MINV
11882         MAXI1=$MAXI
11883         MAXV1=$MAXV
11884
11885         # now fill using QOS
11886         $LFS setstripe -c 1 $DIR/$tdir
11887         FILL=$((FILL / 200))
11888         if [ $FILL -gt 600 ]; then
11889                 FILL=600
11890         fi
11891         echo "writing $FILL files to QOS-assigned OSTs"
11892         i=0
11893         while [ $i -lt $FILL ]; do
11894                 i=$((i + 1))
11895                 dd if=/dev/zero of=$DIR/$tdir/$tfile-$i bs=200k \
11896                         count=1 2>/dev/null
11897                 echo -n .
11898         done
11899         echo "wrote $i 200k files"
11900         sync
11901         sleep_maxage
11902
11903         echo "Note: free space may not be updated, so measurements might be off"
11904         free_min_max
11905         DIFF2=$((MAXV - MINV))
11906         echo "free space delta: orig $DIFF final $DIFF2"
11907         [ $DIFF2 -gt $DIFF ] && echo "delta got worse!"
11908         DIFF=$((MINV1 - ${AVAIL[$MINI1]}))
11909         echo "Wrote ${DIFF}KB to smaller OST $MINI1"
11910         DIFF2=$((MAXV1 - ${AVAIL[$MAXI1]}))
11911         echo "Wrote ${DIFF2}KB to larger OST $MAXI1"
11912         if [[ $DIFF -gt 0 ]]; then
11913                 FILL=$((DIFF2 * 100 / DIFF - 100))
11914                 echo "Wrote ${FILL}% more data to larger OST $MAXI1"
11915         fi
11916
11917         # Figure out which files were written where
11918         UUID=$(lctl get_param -n lov.${FSNAME}-clilov-*.target_obd |
11919                awk '/'$MINI1': / {print $2; exit}')
11920         echo $UUID
11921         MINC=$($LFS getstripe --ost $UUID $DIR/$tdir | grep $DIR | wc -l)
11922         echo "$MINC files created on smaller OST $MINI1"
11923         UUID=$(lctl get_param -n lov.${FSNAME}-clilov-*.target_obd |
11924                awk '/'$MAXI1': / {print $2; exit}')
11925         echo $UUID
11926         MAXC=$($LFS getstripe --ost $UUID $DIR/$tdir | grep $DIR | wc -l)
11927         echo "$MAXC files created on larger OST $MAXI1"
11928         if [[ $MINC -gt 0 ]]; then
11929                 FILL=$((MAXC * 100 / MINC - 100))
11930                 echo "Wrote ${FILL}% more files to larger OST $MAXI1"
11931         fi
11932         [[ $MAXC -gt $MINC ]] ||
11933                 error_ignore LU-9 "stripe QOS didn't balance free space"
11934         simple_cleanup_common
11935 }
11936 run_test 116a "stripe QOS: free space balance ==================="
11937
11938 test_116b() { # LU-2093
11939         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11940         remote_mds_nodsh && skip "remote MDS with nodsh"
11941
11942 #define OBD_FAIL_MDS_OSC_CREATE_FAIL     0x147
11943         local old_rr=$(do_facet $SINGLEMDS lctl get_param -n \
11944                        lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr | head -1)
11945         [ -z "$old_rr" ] && skip "no QOS"
11946         do_facet $SINGLEMDS lctl set_param \
11947                 lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr=0
11948         mkdir -p $DIR/$tdir
11949         do_facet $SINGLEMDS lctl set_param fail_loc=0x147
11950         createmany -o $DIR/$tdir/f- 20 || error "can't create"
11951         do_facet $SINGLEMDS lctl set_param fail_loc=0
11952         rm -rf $DIR/$tdir
11953         do_facet $SINGLEMDS lctl set_param \
11954                 lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr=$old_rr
11955 }
11956 run_test 116b "QoS shouldn't LBUG if not enough OSTs found on the 2nd pass"
11957
11958 test_117() # bug 10891
11959 {
11960         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11961
11962         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
11963         #define OBD_FAIL_OST_SETATTR_CREDITS 0x21e
11964         lctl set_param fail_loc=0x21e
11965         > $DIR/$tfile || error "truncate failed"
11966         lctl set_param fail_loc=0
11967         echo "Truncate succeeded."
11968         rm -f $DIR/$tfile
11969 }
11970 run_test 117 "verify osd extend =========="
11971
11972 NO_SLOW_RESENDCOUNT=4
11973 export OLD_RESENDCOUNT=""
11974 set_resend_count () {
11975         local PROC_RESENDCOUNT="osc.${FSNAME}-OST*-osc-*.resend_count"
11976         OLD_RESENDCOUNT=$(lctl get_param -n $PROC_RESENDCOUNT | head -n1)
11977         lctl set_param -n $PROC_RESENDCOUNT $1
11978         echo resend_count is set to $(lctl get_param -n $PROC_RESENDCOUNT)
11979 }
11980
11981 # for reduce test_118* time (b=14842)
11982 [ "$SLOW" = "no" ] && set_resend_count $NO_SLOW_RESENDCOUNT
11983
11984 # Reset async IO behavior after error case
11985 reset_async() {
11986         FILE=$DIR/reset_async
11987
11988         # Ensure all OSCs are cleared
11989         $LFS setstripe -c -1 $FILE
11990         dd if=/dev/zero of=$FILE bs=64k count=$OSTCOUNT
11991         sync
11992         rm $FILE
11993 }
11994
11995 test_118a() #bug 11710
11996 {
11997         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11998
11999         reset_async
12000
12001         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
12002         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12003         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
12004
12005         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12006                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12007                 return 1;
12008         fi
12009         rm -f $DIR/$tfile
12010 }
12011 run_test 118a "verify O_SYNC works =========="
12012
12013 test_118b()
12014 {
12015         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12016         remote_ost_nodsh && skip "remote OST with nodsh"
12017
12018         reset_async
12019
12020         #define OBD_FAIL_SRV_ENOENT 0x217
12021         set_nodes_failloc "$(osts_nodes)" 0x217
12022         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
12023         RC=$?
12024         set_nodes_failloc "$(osts_nodes)" 0
12025         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12026         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12027                     grep -c writeback)
12028
12029         if [[ $RC -eq 0 ]]; then
12030                 error "Must return error due to dropped pages, rc=$RC"
12031                 return 1;
12032         fi
12033
12034         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12035                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12036                 return 1;
12037         fi
12038
12039         echo "Dirty pages not leaked on ENOENT"
12040
12041         # Due to the above error the OSC will issue all RPCs syncronously
12042         # until a subsequent RPC completes successfully without error.
12043         $MULTIOP $DIR/$tfile Ow4096yc
12044         rm -f $DIR/$tfile
12045
12046         return 0
12047 }
12048 run_test 118b "Reclaim dirty pages on fatal error =========="
12049
12050 test_118c()
12051 {
12052         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12053
12054         # for 118c, restore the original resend count, LU-1940
12055         [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] &&
12056                                 set_resend_count $OLD_RESENDCOUNT
12057         remote_ost_nodsh && skip "remote OST with nodsh"
12058
12059         reset_async
12060
12061         #define OBD_FAIL_OST_EROFS               0x216
12062         set_nodes_failloc "$(osts_nodes)" 0x216
12063
12064         # multiop should block due to fsync until pages are written
12065         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
12066         MULTIPID=$!
12067         sleep 1
12068
12069         if [[ `ps h -o comm -p $MULTIPID` != "multiop" ]]; then
12070                 error "Multiop failed to block on fsync, pid=$MULTIPID"
12071         fi
12072
12073         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12074                     grep -c writeback)
12075         if [[ $WRITEBACK -eq 0 ]]; then
12076                 error "No page in writeback, writeback=$WRITEBACK"
12077         fi
12078
12079         set_nodes_failloc "$(osts_nodes)" 0
12080         wait $MULTIPID
12081         RC=$?
12082         if [[ $RC -ne 0 ]]; then
12083                 error "Multiop fsync failed, rc=$RC"
12084         fi
12085
12086         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12087         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12088                     grep -c writeback)
12089         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12090                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12091         fi
12092
12093         rm -f $DIR/$tfile
12094         echo "Dirty pages flushed via fsync on EROFS"
12095         return 0
12096 }
12097 run_test 118c "Fsync blocks on EROFS until dirty pages are flushed =========="
12098
12099 # continue to use small resend count to reduce test_118* time (b=14842)
12100 [ "$SLOW" = "no" ] && set_resend_count $NO_SLOW_RESENDCOUNT
12101
12102 test_118d()
12103 {
12104         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12105         remote_ost_nodsh && skip "remote OST with nodsh"
12106
12107         reset_async
12108
12109         #define OBD_FAIL_OST_BRW_PAUSE_BULK
12110         set_nodes_failloc "$(osts_nodes)" 0x214
12111         # multiop should block due to fsync until pages are written
12112         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
12113         MULTIPID=$!
12114         sleep 1
12115
12116         if [[ `ps h -o comm -p $MULTIPID` != "multiop" ]]; then
12117                 error "Multiop failed to block on fsync, pid=$MULTIPID"
12118         fi
12119
12120         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12121                     grep -c writeback)
12122         if [[ $WRITEBACK -eq 0 ]]; then
12123                 error "No page in writeback, writeback=$WRITEBACK"
12124         fi
12125
12126         wait $MULTIPID || error "Multiop fsync failed, rc=$?"
12127         set_nodes_failloc "$(osts_nodes)" 0
12128
12129         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12130         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12131                     grep -c writeback)
12132         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12133                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12134         fi
12135
12136         rm -f $DIR/$tfile
12137         echo "Dirty pages gaurenteed flushed via fsync"
12138         return 0
12139 }
12140 run_test 118d "Fsync validation inject a delay of the bulk =========="
12141
12142 test_118f() {
12143         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12144
12145         reset_async
12146
12147         #define OBD_FAIL_OSC_BRW_PREP_REQ2        0x40a
12148         lctl set_param fail_loc=0x8000040a
12149
12150         # Should simulate EINVAL error which is fatal
12151         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
12152         RC=$?
12153         if [[ $RC -eq 0 ]]; then
12154                 error "Must return error due to dropped pages, rc=$RC"
12155         fi
12156
12157         lctl set_param fail_loc=0x0
12158
12159         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
12160         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12161         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12162                     grep -c writeback)
12163         if [[ $LOCKED -ne 0 ]]; then
12164                 error "Locked pages remain in cache, locked=$LOCKED"
12165         fi
12166
12167         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12168                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12169         fi
12170
12171         rm -f $DIR/$tfile
12172         echo "No pages locked after fsync"
12173
12174         reset_async
12175         return 0
12176 }
12177 run_test 118f "Simulate unrecoverable OSC side error =========="
12178
12179 test_118g() {
12180         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12181
12182         reset_async
12183
12184         #define OBD_FAIL_OSC_BRW_PREP_REQ        0x406
12185         lctl set_param fail_loc=0x406
12186
12187         # simulate local -ENOMEM
12188         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
12189         RC=$?
12190
12191         lctl set_param fail_loc=0
12192         if [[ $RC -eq 0 ]]; then
12193                 error "Must return error due to dropped pages, rc=$RC"
12194         fi
12195
12196         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
12197         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12198         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12199                         grep -c writeback)
12200         if [[ $LOCKED -ne 0 ]]; then
12201                 error "Locked pages remain in cache, locked=$LOCKED"
12202         fi
12203
12204         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12205                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12206         fi
12207
12208         rm -f $DIR/$tfile
12209         echo "No pages locked after fsync"
12210
12211         reset_async
12212         return 0
12213 }
12214 run_test 118g "Don't stay in wait if we got local -ENOMEM  =========="
12215
12216 test_118h() {
12217         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12218         remote_ost_nodsh && skip "remote OST with nodsh"
12219
12220         reset_async
12221
12222         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
12223         set_nodes_failloc "$(osts_nodes)" 0x20e
12224         # Should simulate ENOMEM error which is recoverable and should be handled by timeout
12225         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
12226         RC=$?
12227
12228         set_nodes_failloc "$(osts_nodes)" 0
12229         if [[ $RC -eq 0 ]]; then
12230                 error "Must return error due to dropped pages, rc=$RC"
12231         fi
12232
12233         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
12234         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12235         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12236                     grep -c writeback)
12237         if [[ $LOCKED -ne 0 ]]; then
12238                 error "Locked pages remain in cache, locked=$LOCKED"
12239         fi
12240
12241         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12242                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12243         fi
12244
12245         rm -f $DIR/$tfile
12246         echo "No pages locked after fsync"
12247
12248         return 0
12249 }
12250 run_test 118h "Verify timeout in handling recoverables errors  =========="
12251
12252 [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] && set_resend_count $OLD_RESENDCOUNT
12253
12254 test_118i() {
12255         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12256         remote_ost_nodsh && skip "remote OST with nodsh"
12257
12258         reset_async
12259
12260         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
12261         set_nodes_failloc "$(osts_nodes)" 0x20e
12262
12263         # Should simulate ENOMEM error which is recoverable and should be handled by timeout
12264         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
12265         PID=$!
12266         sleep 5
12267         set_nodes_failloc "$(osts_nodes)" 0
12268
12269         wait $PID
12270         RC=$?
12271         if [[ $RC -ne 0 ]]; then
12272                 error "got error, but should be not, rc=$RC"
12273         fi
12274
12275         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
12276         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12277         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
12278         if [[ $LOCKED -ne 0 ]]; then
12279                 error "Locked pages remain in cache, locked=$LOCKED"
12280         fi
12281
12282         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12283                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12284         fi
12285
12286         rm -f $DIR/$tfile
12287         echo "No pages locked after fsync"
12288
12289         return 0
12290 }
12291 run_test 118i "Fix error before timeout in recoverable error  =========="
12292
12293 [ "$SLOW" = "no" ] && set_resend_count 4
12294
12295 test_118j() {
12296         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12297         remote_ost_nodsh && skip "remote OST with nodsh"
12298
12299         reset_async
12300
12301         #define OBD_FAIL_OST_BRW_WRITE_BULK2     0x220
12302         set_nodes_failloc "$(osts_nodes)" 0x220
12303
12304         # return -EIO from OST
12305         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
12306         RC=$?
12307         set_nodes_failloc "$(osts_nodes)" 0x0
12308         if [[ $RC -eq 0 ]]; then
12309                 error "Must return error due to dropped pages, rc=$RC"
12310         fi
12311
12312         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
12313         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12314         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
12315         if [[ $LOCKED -ne 0 ]]; then
12316                 error "Locked pages remain in cache, locked=$LOCKED"
12317         fi
12318
12319         # in recoverable error on OST we want resend and stay until it finished
12320         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12321                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12322         fi
12323
12324         rm -f $DIR/$tfile
12325         echo "No pages locked after fsync"
12326
12327         return 0
12328 }
12329 run_test 118j "Simulate unrecoverable OST side error =========="
12330
12331 test_118k()
12332 {
12333         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12334         remote_ost_nodsh && skip "remote OSTs with nodsh"
12335
12336         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
12337         set_nodes_failloc "$(osts_nodes)" 0x20e
12338         test_mkdir $DIR/$tdir
12339
12340         for ((i=0;i<10;i++)); do
12341                 (dd if=/dev/zero of=$DIR/$tdir/$tfile-$i bs=1M count=10 || \
12342                         error "dd to $DIR/$tdir/$tfile-$i failed" )&
12343                 SLEEPPID=$!
12344                 sleep 0.500s
12345                 kill $SLEEPPID
12346                 wait $SLEEPPID
12347         done
12348
12349         set_nodes_failloc "$(osts_nodes)" 0
12350         rm -rf $DIR/$tdir
12351 }
12352 run_test 118k "bio alloc -ENOMEM and IO TERM handling ========="
12353
12354 test_118l() # LU-646
12355 {
12356         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12357
12358         test_mkdir $DIR/$tdir
12359         $MULTIOP $DIR/$tdir Dy || error "fsync dir failed"
12360         rm -rf $DIR/$tdir
12361 }
12362 run_test 118l "fsync dir"
12363
12364 test_118m() # LU-3066
12365 {
12366         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12367
12368         test_mkdir $DIR/$tdir
12369         $MULTIOP $DIR/$tdir DY || error "fdatasync dir failed"
12370         rm -rf $DIR/$tdir
12371 }
12372 run_test 118m "fdatasync dir ========="
12373
12374 [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] && set_resend_count $OLD_RESENDCOUNT
12375
12376 test_118n()
12377 {
12378         local begin
12379         local end
12380
12381         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12382         remote_ost_nodsh && skip "remote OSTs with nodsh"
12383
12384         # Sleep to avoid a cached response.
12385         #define OBD_STATFS_CACHE_SECONDS 1
12386         sleep 2
12387
12388         # Inject a 10 second delay in the OST_STATFS handler.
12389         #define OBD_FAIL_OST_STATFS_DELAY 0x242
12390         set_nodes_failloc "$(osts_nodes)" 0x242
12391
12392         begin=$SECONDS
12393         stat --file-system $MOUNT > /dev/null
12394         end=$SECONDS
12395
12396         set_nodes_failloc "$(osts_nodes)" 0
12397
12398         if ((end - begin > 20)); then
12399             error "statfs took $((end - begin)) seconds, expected 10"
12400         fi
12401 }
12402 run_test 118n "statfs() sends OST_STATFS requests in parallel"
12403
12404 test_119a() # bug 11737
12405 {
12406         BSIZE=$((512 * 1024))
12407         directio write $DIR/$tfile 0 1 $BSIZE
12408         # We ask to read two blocks, which is more than a file size.
12409         # directio will indicate an error when requested and actual
12410         # sizes aren't equeal (a normal situation in this case) and
12411         # print actual read amount.
12412         NOB=`directio read $DIR/$tfile 0 2 $BSIZE | awk '/error/ {print $6}'`
12413         if [ "$NOB" != "$BSIZE" ]; then
12414                 error "read $NOB bytes instead of $BSIZE"
12415         fi
12416         rm -f $DIR/$tfile
12417 }
12418 run_test 119a "Short directIO read must return actual read amount"
12419
12420 test_119b() # bug 11737
12421 {
12422         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
12423
12424         $LFS setstripe -c 2 $DIR/$tfile || error "setstripe failed"
12425         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=1 || error "dd failed"
12426         sync
12427         $MULTIOP $DIR/$tfile oO_RDONLY:O_DIRECT:r$((2048 * 1024)) ||
12428                 error "direct read failed"
12429         rm -f $DIR/$tfile
12430 }
12431 run_test 119b "Sparse directIO read must return actual read amount"
12432
12433 test_119c() # bug 13099
12434 {
12435         BSIZE=1048576
12436         directio write $DIR/$tfile 3 1 $BSIZE || error "direct write failed"
12437         directio readhole $DIR/$tfile 0 2 $BSIZE || error "reading hole failed"
12438         rm -f $DIR/$tfile
12439 }
12440 run_test 119c "Testing for direct read hitting hole"
12441
12442 test_119d() # bug 15950
12443 {
12444         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12445
12446         MAX_RPCS_IN_FLIGHT=`$LCTL get_param -n osc.*OST0000-osc-[^mM]*.max_rpcs_in_flight`
12447         $LCTL set_param -n osc.*OST0000-osc-[^mM]*.max_rpcs_in_flight 1
12448         BSIZE=1048576
12449         $LFS setstripe $DIR/$tfile -i 0 -c 1 || error "setstripe failed"
12450         $DIRECTIO write $DIR/$tfile 0 1 $BSIZE || error "first directio failed"
12451         #define OBD_FAIL_OSC_DIO_PAUSE           0x40d
12452         lctl set_param fail_loc=0x40d
12453         $DIRECTIO write $DIR/$tfile 1 4 $BSIZE &
12454         pid_dio=$!
12455         sleep 1
12456         cat $DIR/$tfile > /dev/null &
12457         lctl set_param fail_loc=0
12458         pid_reads=$!
12459         wait $pid_dio
12460         log "the DIO writes have completed, now wait for the reads (should not block very long)"
12461         sleep 2
12462         [ -n "`ps h -p $pid_reads -o comm`" ] && \
12463         error "the read rpcs have not completed in 2s"
12464         rm -f $DIR/$tfile
12465         $LCTL set_param -n osc.*OST0000-osc-[^mM]*.max_rpcs_in_flight $MAX_RPCS_IN_FLIGHT
12466 }
12467 run_test 119d "The DIO path should try to send a new rpc once one is completed"
12468
12469 test_120a() {
12470         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12471         remote_mds_nodsh && skip "remote MDS with nodsh"
12472         test_mkdir -i0 -c1 $DIR/$tdir
12473         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
12474                 skip_env "no early lock cancel on server"
12475
12476         lru_resize_disable mdc
12477         lru_resize_disable osc
12478         cancel_lru_locks mdc
12479         # asynchronous object destroy at MDT could cause bl ast to client
12480         cancel_lru_locks osc
12481
12482         stat $DIR/$tdir > /dev/null
12483         can1=$(do_facet mds1 \
12484                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12485                awk '/ldlm_cancel/ {print $2}')
12486         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12487                awk '/ldlm_bl_callback/ {print $2}')
12488         test_mkdir -i0 -c1 $DIR/$tdir/d1
12489         can2=$(do_facet mds1 \
12490                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12491                awk '/ldlm_cancel/ {print $2}')
12492         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12493                awk '/ldlm_bl_callback/ {print $2}')
12494         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
12495         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
12496         lru_resize_enable mdc
12497         lru_resize_enable osc
12498 }
12499 run_test 120a "Early Lock Cancel: mkdir test"
12500
12501 test_120b() {
12502         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12503         remote_mds_nodsh && skip "remote MDS with nodsh"
12504         test_mkdir $DIR/$tdir
12505         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
12506                 skip_env "no early lock cancel on server"
12507
12508         lru_resize_disable mdc
12509         lru_resize_disable osc
12510         cancel_lru_locks mdc
12511         stat $DIR/$tdir > /dev/null
12512         can1=$(do_facet $SINGLEMDS \
12513                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12514                awk '/ldlm_cancel/ {print $2}')
12515         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12516                awk '/ldlm_bl_callback/ {print $2}')
12517         touch $DIR/$tdir/f1
12518         can2=$(do_facet $SINGLEMDS \
12519                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12520                awk '/ldlm_cancel/ {print $2}')
12521         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12522                awk '/ldlm_bl_callback/ {print $2}')
12523         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
12524         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
12525         lru_resize_enable mdc
12526         lru_resize_enable osc
12527 }
12528 run_test 120b "Early Lock Cancel: create test"
12529
12530 test_120c() {
12531         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12532         remote_mds_nodsh && skip "remote MDS with nodsh"
12533         test_mkdir -i0 -c1 $DIR/$tdir
12534         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
12535                 skip "no early lock cancel on server"
12536
12537         lru_resize_disable mdc
12538         lru_resize_disable osc
12539         test_mkdir -i0 -c1 $DIR/$tdir/d1
12540         test_mkdir -i0 -c1 $DIR/$tdir/d2
12541         touch $DIR/$tdir/d1/f1
12542         cancel_lru_locks mdc
12543         stat $DIR/$tdir/d1 $DIR/$tdir/d2 $DIR/$tdir/d1/f1 > /dev/null
12544         can1=$(do_facet mds1 \
12545                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12546                awk '/ldlm_cancel/ {print $2}')
12547         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12548                awk '/ldlm_bl_callback/ {print $2}')
12549         ln $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2
12550         can2=$(do_facet mds1 \
12551                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12552                awk '/ldlm_cancel/ {print $2}')
12553         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12554                awk '/ldlm_bl_callback/ {print $2}')
12555         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
12556         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
12557         lru_resize_enable mdc
12558         lru_resize_enable osc
12559 }
12560 run_test 120c "Early Lock Cancel: link test"
12561
12562 test_120d() {
12563         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12564         remote_mds_nodsh && skip "remote MDS with nodsh"
12565         test_mkdir -i0 -c1 $DIR/$tdir
12566         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
12567                 skip_env "no early lock cancel on server"
12568
12569         lru_resize_disable mdc
12570         lru_resize_disable osc
12571         touch $DIR/$tdir
12572         cancel_lru_locks mdc
12573         stat $DIR/$tdir > /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         chmod a+x $DIR/$tdir
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 120d "Early Lock Cancel: setattr test"
12591
12592 test_120e() {
12593         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12594         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
12595                 skip_env "no early lock cancel on server"
12596         remote_mds_nodsh && skip "remote MDS with nodsh"
12597
12598         local dlmtrace_set=false
12599
12600         test_mkdir -i0 -c1 $DIR/$tdir
12601         lru_resize_disable mdc
12602         lru_resize_disable osc
12603         ! $LCTL get_param debug | grep -q dlmtrace &&
12604                 $LCTL set_param debug=+dlmtrace && dlmtrace_set=true
12605         dd if=/dev/zero of=$DIR/$tdir/f1 count=1
12606         cancel_lru_locks mdc
12607         cancel_lru_locks osc
12608         dd if=$DIR/$tdir/f1 of=/dev/null
12609         stat $DIR/$tdir $DIR/$tdir/f1 > /dev/null
12610         # XXX client can not do early lock cancel of OST lock
12611         # during unlink (LU-4206), so cancel osc lock now.
12612         sleep 2
12613         cancel_lru_locks osc
12614         can1=$(do_facet mds1 \
12615                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12616                awk '/ldlm_cancel/ {print $2}')
12617         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12618                awk '/ldlm_bl_callback/ {print $2}')
12619         unlink $DIR/$tdir/f1
12620         sleep 5
12621         can2=$(do_facet mds1 \
12622                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12623                awk '/ldlm_cancel/ {print $2}')
12624         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12625                awk '/ldlm_bl_callback/ {print $2}')
12626         [ $can1 -ne $can2 ] && error "$((can2 - can1)) cancel RPC occured" &&
12627                 $LCTL dk $TMP/cancel.debug.txt
12628         [ $blk1 -ne $blk2 ] && error "$((blk2 - blk1)) blocking RPC occured" &&
12629                 $LCTL dk $TMP/blocking.debug.txt
12630         $dlmtrace_set && $LCTL set_param debug=-dlmtrace
12631         lru_resize_enable mdc
12632         lru_resize_enable osc
12633 }
12634 run_test 120e "Early Lock Cancel: unlink test"
12635
12636 test_120f() {
12637         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12638         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
12639                 skip_env "no early lock cancel on server"
12640         remote_mds_nodsh && skip "remote MDS with nodsh"
12641
12642         test_mkdir -i0 -c1 $DIR/$tdir
12643         lru_resize_disable mdc
12644         lru_resize_disable osc
12645         test_mkdir -i0 -c1 $DIR/$tdir/d1
12646         test_mkdir -i0 -c1 $DIR/$tdir/d2
12647         dd if=/dev/zero of=$DIR/$tdir/d1/f1 count=1
12648         dd if=/dev/zero of=$DIR/$tdir/d2/f2 count=1
12649         cancel_lru_locks mdc
12650         cancel_lru_locks osc
12651         dd if=$DIR/$tdir/d1/f1 of=/dev/null
12652         dd if=$DIR/$tdir/d2/f2 of=/dev/null
12653         stat $DIR/$tdir/d1 $DIR/$tdir/d2 $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2 > /dev/null
12654         # XXX client can not do early lock cancel of OST lock
12655         # during rename (LU-4206), so cancel osc lock now.
12656         sleep 2
12657         cancel_lru_locks osc
12658         can1=$(do_facet mds1 \
12659                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12660                awk '/ldlm_cancel/ {print $2}')
12661         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12662                awk '/ldlm_bl_callback/ {print $2}')
12663         mrename $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2
12664         sleep 5
12665         can2=$(do_facet mds1 \
12666                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12667                awk '/ldlm_cancel/ {print $2}')
12668         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12669                awk '/ldlm_bl_callback/ {print $2}')
12670         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
12671         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
12672         lru_resize_enable mdc
12673         lru_resize_enable osc
12674 }
12675 run_test 120f "Early Lock Cancel: rename test"
12676
12677 test_120g() {
12678         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12679         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
12680                 skip_env "no early lock cancel on server"
12681         remote_mds_nodsh && skip "remote MDS with nodsh"
12682
12683         lru_resize_disable mdc
12684         lru_resize_disable osc
12685         count=10000
12686         echo create $count files
12687         test_mkdir $DIR/$tdir
12688         cancel_lru_locks mdc
12689         cancel_lru_locks osc
12690         t0=$(date +%s)
12691
12692         can0=$(do_facet $SINGLEMDS \
12693                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12694                awk '/ldlm_cancel/ {print $2}')
12695         blk0=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12696                awk '/ldlm_bl_callback/ {print $2}')
12697         createmany -o $DIR/$tdir/f $count
12698         sync
12699         can1=$(do_facet $SINGLEMDS \
12700                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12701                awk '/ldlm_cancel/ {print $2}')
12702         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12703                awk '/ldlm_bl_callback/ {print $2}')
12704         t1=$(date +%s)
12705         echo total: $((can1-can0)) cancels, $((blk1-blk0)) blockings
12706         echo rm $count files
12707         rm -r $DIR/$tdir
12708         sync
12709         can2=$(do_facet $SINGLEMDS \
12710                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
12711                awk '/ldlm_cancel/ {print $2}')
12712         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
12713                awk '/ldlm_bl_callback/ {print $2}')
12714         t2=$(date +%s)
12715         echo total: $count removes in $((t2-t1))
12716         echo total: $((can2-can1)) cancels, $((blk2-blk1)) blockings
12717         sleep 2
12718         # wait for commitment of removal
12719         lru_resize_enable mdc
12720         lru_resize_enable osc
12721 }
12722 run_test 120g "Early Lock Cancel: performance test"
12723
12724 test_121() { #bug #10589
12725         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12726
12727         rm -rf $DIR/$tfile
12728         writes=$(LANG=C dd if=/dev/zero of=$DIR/$tfile count=1 2>&1 | awk -F '+' '/out$/ {print $1}')
12729 #define OBD_FAIL_LDLM_CANCEL_RACE        0x310
12730         lctl set_param fail_loc=0x310
12731         cancel_lru_locks osc > /dev/null
12732         reads=$(LANG=C dd if=$DIR/$tfile of=/dev/null 2>&1 | awk -F '+' '/in$/ {print $1}')
12733         lctl set_param fail_loc=0
12734         [[ $reads -eq $writes ]] ||
12735                 error "read $reads blocks, must be $writes blocks"
12736 }
12737 run_test 121 "read cancel race ========="
12738
12739 test_123a_base() { # was test 123, statahead(bug 11401)
12740         local lsx="$1"
12741
12742         SLOWOK=0
12743         if ! grep -q "processor.*: 1" /proc/cpuinfo; then
12744                 log "testing UP system. Performance may be lower than expected."
12745                 SLOWOK=1
12746         fi
12747
12748         rm -rf $DIR/$tdir
12749         test_mkdir $DIR/$tdir
12750         NUMFREE=$(df -i -P $DIR | tail -n 1 | awk '{ print $4 }')
12751         [[ $NUMFREE -gt 100000 ]] && NUMFREE=100000 || NUMFREE=$((NUMFREE-1000))
12752         MULT=10
12753         for ((i=100, j=0; i<=$NUMFREE; j=$i, i=$((i * MULT)) )); do
12754                 createmany -o $DIR/$tdir/$tfile $j $((i - j))
12755
12756                 max=$(lctl get_param -n llite.*.statahead_max | head -n 1)
12757                 lctl set_param -n llite.*.statahead_max 0
12758                 lctl get_param llite.*.statahead_max
12759                 cancel_lru_locks mdc
12760                 cancel_lru_locks osc
12761                 stime=$(date +%s)
12762                 time $lsx $DIR/$tdir | wc -l
12763                 etime=$(date +%s)
12764                 delta=$((etime - stime))
12765                 log "$lsx $i files without statahead: $delta sec"
12766                 lctl set_param llite.*.statahead_max=$max
12767
12768                 swrong=$(lctl get_param -n llite.*.statahead_stats |
12769                         grep "statahead wrong:" | awk '{print $3}')
12770                 lctl get_param -n llite.*.statahead_max | grep '[0-9]'
12771                 cancel_lru_locks mdc
12772                 cancel_lru_locks osc
12773                 stime=$(date +%s)
12774                 time $lsx $DIR/$tdir | wc -l
12775                 etime=$(date +%s)
12776                 delta_sa=$((etime - stime))
12777                 log "$lsx $i files with statahead: $delta_sa sec"
12778                 lctl get_param -n llite.*.statahead_stats
12779                 ewrong=$(lctl get_param -n llite.*.statahead_stats |
12780                         grep "statahead wrong:" | awk '{print $3}')
12781
12782                 [[ $swrong -lt $ewrong ]] &&
12783                         log "statahead was stopped, maybe too many locks held!"
12784                 [[ $delta -eq 0 || $delta_sa -eq 0 ]] && continue
12785
12786                 if [ $((delta_sa * 100)) -gt $((delta * 105)) -a $delta_sa -gt $((delta + 2)) ]; then
12787                         max=$(lctl get_param -n llite.*.statahead_max |
12788                                 head -n 1)
12789                         lctl set_param -n llite.*.statahead_max 0
12790                         lctl get_param llite.*.statahead_max
12791                         cancel_lru_locks mdc
12792                         cancel_lru_locks osc
12793                         stime=$(date +%s)
12794                         time $lsx $DIR/$tdir | wc -l
12795                         etime=$(date +%s)
12796                         delta=$((etime - stime))
12797                         log "$lsx $i files again without statahead: $delta sec"
12798                         lctl set_param llite.*.statahead_max=$max
12799                         if [ $((delta_sa * 100 > delta * 105 && delta_sa > delta + 2)) ]; then
12800                                 if [  $SLOWOK -eq 0 ]; then
12801                                         error "$lsx $i files is slower with statahead!"
12802                                 else
12803                                         log "$lsx $i files is slower with statahead!"
12804                                 fi
12805                                 break
12806                         fi
12807                 fi
12808
12809                 [ $delta -gt 20 ] && break
12810                 [ $delta -gt 8 ] && MULT=$((50 / delta))
12811                 [ "$SLOW" = "no" -a $delta -gt 5 ] && break
12812         done
12813         log "$lsx done"
12814
12815         stime=$(date +%s)
12816         rm -r $DIR/$tdir
12817         sync
12818         etime=$(date +%s)
12819         delta=$((etime - stime))
12820         log "rm -r $DIR/$tdir/: $delta seconds"
12821         log "rm done"
12822         lctl get_param -n llite.*.statahead_stats
12823 }
12824
12825 test_123aa() {
12826         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12827
12828         test_123a_base "ls -l"
12829 }
12830 run_test 123aa "verify statahead work"
12831
12832 test_123ab() {
12833         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12834
12835         statx_supported || skip_env "Test must be statx() syscall supported"
12836
12837         test_123a_base "$STATX -l"
12838 }
12839 run_test 123ab "verify statahead work by using statx"
12840
12841 test_123ac() {
12842         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12843
12844         statx_supported || skip_env "Test must be statx() syscall supported"
12845
12846         local rpcs_before
12847         local rpcs_after
12848         local agl_before
12849         local agl_after
12850
12851         cancel_lru_locks $OSC
12852         rpcs_before=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
12853         agl_before=$($LCTL get_param -n llite.*.statahead_stats |
12854                 awk '/agl.total:/ {print $3}')
12855         test_123a_base "$STATX -c \"%n %i %A %h %u %g %W %X %Z\" -D"
12856         test_123a_base "$STATX --cached=always -D"
12857         agl_after=$($LCTL get_param -n llite.*.statahead_stats |
12858                 awk '/agl.total:/ {print $3}')
12859         [ $agl_before -eq $agl_after ] ||
12860                 error "Should not trigger AGL thread - $agl_before:$agl_after"
12861         rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
12862         [ $rpcs_after -eq $rpcs_before ] ||
12863                 error "$STATX should not send glimpse RPCs to $OSC"
12864 }
12865 run_test 123ac "verify statahead work by using statx without glimpse RPCs"
12866
12867 test_123b () { # statahead(bug 15027)
12868         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12869
12870         test_mkdir $DIR/$tdir
12871         createmany -o $DIR/$tdir/$tfile-%d 1000
12872
12873         cancel_lru_locks mdc
12874         cancel_lru_locks osc
12875
12876 #define OBD_FAIL_MDC_GETATTR_ENQUEUE     0x803
12877         lctl set_param fail_loc=0x80000803
12878         ls -lR $DIR/$tdir > /dev/null
12879         log "ls done"
12880         lctl set_param fail_loc=0x0
12881         lctl get_param -n llite.*.statahead_stats
12882         rm -r $DIR/$tdir
12883         sync
12884
12885 }
12886 run_test 123b "not panic with network error in statahead enqueue (bug 15027)"
12887
12888 test_123c() {
12889         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
12890
12891         test_mkdir -i 0 -c 1 $DIR/$tdir.0
12892         test_mkdir -i 1 -c 1 $DIR/$tdir.1
12893         touch $DIR/$tdir.1/{1..3}
12894         mv $DIR/$tdir.1/{1..3} $DIR/$tdir.0
12895
12896         remount_client $MOUNT
12897
12898         $MULTIOP $DIR/$tdir.0 Q
12899
12900         # let statahead to complete
12901         ls -l $DIR/$tdir.0 > /dev/null
12902
12903         testid=$(echo $TESTNAME | tr '_' ' ')
12904         dmesg | tac | sed "/$testid/,$ d" | grep "Can not initialize inode" &&
12905                 error "statahead warning" || true
12906 }
12907 run_test 123c "Can not initialize inode warning on DNE statahead"
12908
12909 test_124a() {
12910         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12911         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
12912                 skip_env "no lru resize on server"
12913
12914         local NR=2000
12915
12916         test_mkdir $DIR/$tdir
12917
12918         log "create $NR files at $DIR/$tdir"
12919         createmany -o $DIR/$tdir/f $NR ||
12920                 error "failed to create $NR files in $DIR/$tdir"
12921
12922         cancel_lru_locks mdc
12923         ls -l $DIR/$tdir > /dev/null
12924
12925         local NSDIR=""
12926         local LRU_SIZE=0
12927         for VALUE in $($LCTL get_param ldlm.namespaces.*mdc-*.lru_size); do
12928                 local PARAM=$(echo ${VALUE[0]} | cut -d "=" -f1)
12929                 LRU_SIZE=$($LCTL get_param -n $PARAM)
12930                 if [[ $LRU_SIZE -gt $(default_lru_size) ]]; then
12931                         NSDIR=$(echo $PARAM | cut -d "." -f1-3)
12932                         log "NSDIR=$NSDIR"
12933                         log "NS=$(basename $NSDIR)"
12934                         break
12935                 fi
12936         done
12937
12938         if [[ -z "$NSDIR" || $LRU_SIZE -lt $(default_lru_size) ]]; then
12939                 skip "Not enough cached locks created!"
12940         fi
12941         log "LRU=$LRU_SIZE"
12942
12943         local SLEEP=30
12944
12945         # We know that lru resize allows one client to hold $LIMIT locks
12946         # for 10h. After that locks begin to be killed by client.
12947         local MAX_HRS=10
12948         local LIMIT=$($LCTL get_param -n $NSDIR.pool.limit)
12949         log "LIMIT=$LIMIT"
12950         if [ $LIMIT -lt $LRU_SIZE ]; then
12951                 skip "Limit is too small $LIMIT"
12952         fi
12953
12954         # Make LVF so higher that sleeping for $SLEEP is enough to _start_
12955         # killing locks. Some time was spent for creating locks. This means
12956         # that up to the moment of sleep finish we must have killed some of
12957         # them (10-100 locks). This depends on how fast ther were created.
12958         # Many of them were touched in almost the same moment and thus will
12959         # be killed in groups.
12960         local LVF=$(($MAX_HRS * 60 * 60 / $SLEEP * $LIMIT / $LRU_SIZE * 100))
12961
12962         # Use $LRU_SIZE_B here to take into account real number of locks
12963         # created in the case of CMD, LRU_SIZE_B != $NR in most of cases
12964         local LRU_SIZE_B=$LRU_SIZE
12965         log "LVF=$LVF"
12966         local OLD_LVF=$($LCTL get_param -n $NSDIR.pool.lock_volume_factor)
12967         log "OLD_LVF=$OLD_LVF"
12968         $LCTL set_param -n $NSDIR.pool.lock_volume_factor $LVF
12969
12970         # Let's make sure that we really have some margin. Client checks
12971         # cached locks every 10 sec.
12972         SLEEP=$((SLEEP+20))
12973         log "Sleep ${SLEEP} sec"
12974         local SEC=0
12975         while ((SEC<$SLEEP)); do
12976                 echo -n "..."
12977                 sleep 5
12978                 SEC=$((SEC+5))
12979                 LRU_SIZE=$($LCTL get_param -n $NSDIR/lru_size)
12980                 echo -n "$LRU_SIZE"
12981         done
12982         echo ""
12983         $LCTL set_param -n $NSDIR.pool.lock_volume_factor $OLD_LVF
12984         local LRU_SIZE_A=$($LCTL get_param -n $NSDIR.lru_size)
12985
12986         [[ $LRU_SIZE_B -gt $LRU_SIZE_A ]] || {
12987                 error "No locks dropped in ${SLEEP}s. LRU size: $LRU_SIZE_A"
12988                 unlinkmany $DIR/$tdir/f $NR
12989                 return
12990         }
12991
12992         log "Dropped "$((LRU_SIZE_B-LRU_SIZE_A))" locks in ${SLEEP}s"
12993         log "unlink $NR files at $DIR/$tdir"
12994         unlinkmany $DIR/$tdir/f $NR
12995 }
12996 run_test 124a "lru resize ======================================="
12997
12998 get_max_pool_limit()
12999 {
13000         local limit=$($LCTL get_param \
13001                       -n ldlm.namespaces.*-MDT0000-mdc-*.pool.limit)
13002         local max=0
13003         for l in $limit; do
13004                 if [[ $l -gt $max ]]; then
13005                         max=$l
13006                 fi
13007         done
13008         echo $max
13009 }
13010
13011 test_124b() {
13012         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13013         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
13014                 skip_env "no lru resize on server"
13015
13016         LIMIT=$(get_max_pool_limit)
13017
13018         NR=$(($(default_lru_size)*20))
13019         if [[ $NR -gt $LIMIT ]]; then
13020                 log "Limit lock number by $LIMIT locks"
13021                 NR=$LIMIT
13022         fi
13023
13024         IFree=$(mdsrate_inodes_available)
13025         if [ $IFree -lt $NR ]; then
13026                 log "Limit lock number by $IFree inodes"
13027                 NR=$IFree
13028         fi
13029
13030         lru_resize_disable mdc
13031         test_mkdir -p $DIR/$tdir/disable_lru_resize
13032
13033         createmany -o $DIR/$tdir/disable_lru_resize/f $NR
13034         log "doing ls -la $DIR/$tdir/disable_lru_resize 3 times"
13035         cancel_lru_locks mdc
13036         stime=`date +%s`
13037         PID=""
13038         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
13039         PID="$PID $!"
13040         sleep 2
13041         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
13042         PID="$PID $!"
13043         sleep 2
13044         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
13045         PID="$PID $!"
13046         wait $PID
13047         etime=`date +%s`
13048         nolruresize_delta=$((etime-stime))
13049         log "ls -la time: $nolruresize_delta seconds"
13050         log "lru_size = $(lctl get_param -n ldlm.namespaces.*mdc*.lru_size)"
13051         unlinkmany $DIR/$tdir/disable_lru_resize/f $NR
13052
13053         lru_resize_enable mdc
13054         test_mkdir -p $DIR/$tdir/enable_lru_resize
13055
13056         createmany -o $DIR/$tdir/enable_lru_resize/f $NR
13057         log "doing ls -la $DIR/$tdir/enable_lru_resize 3 times"
13058         cancel_lru_locks mdc
13059         stime=`date +%s`
13060         PID=""
13061         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
13062         PID="$PID $!"
13063         sleep 2
13064         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
13065         PID="$PID $!"
13066         sleep 2
13067         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
13068         PID="$PID $!"
13069         wait $PID
13070         etime=`date +%s`
13071         lruresize_delta=$((etime-stime))
13072         log "ls -la time: $lruresize_delta seconds"
13073         log "lru_size = $(lctl get_param -n ldlm.namespaces.*mdc*.lru_size)"
13074
13075         if [ $lruresize_delta -gt $nolruresize_delta ]; then
13076                 log "ls -la is $(((lruresize_delta - $nolruresize_delta) * 100 / $nolruresize_delta))% slower with lru resize enabled"
13077         elif [ $nolruresize_delta -gt $lruresize_delta ]; then
13078                 log "ls -la is $(((nolruresize_delta - $lruresize_delta) * 100 / $nolruresize_delta))% faster with lru resize enabled"
13079         else
13080                 log "lru resize performs the same with no lru resize"
13081         fi
13082         unlinkmany $DIR/$tdir/enable_lru_resize/f $NR
13083 }
13084 run_test 124b "lru resize (performance test) ======================="
13085
13086 test_124c() {
13087         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13088         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
13089                 skip_env "no lru resize on server"
13090
13091         # cache ununsed locks on client
13092         local nr=100
13093         cancel_lru_locks mdc
13094         test_mkdir $DIR/$tdir
13095         createmany -o $DIR/$tdir/f $nr ||
13096                 error "failed to create $nr files in $DIR/$tdir"
13097         ls -l $DIR/$tdir > /dev/null
13098
13099         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
13100         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
13101         local max_age=$($LCTL get_param -n $nsdir.lru_max_age)
13102         local recalc_p=$($LCTL get_param -n $nsdir.pool.recalc_period)
13103         echo "unused=$unused, max_age=$max_age, recalc_p=$recalc_p"
13104
13105         # set lru_max_age to 1 sec
13106         $LCTL set_param $nsdir.lru_max_age=1000 # milliseconds
13107         echo "sleep $((recalc_p * 2)) seconds..."
13108         sleep $((recalc_p * 2))
13109
13110         local remaining=$($LCTL get_param -n $nsdir.lock_unused_count)
13111         # restore lru_max_age
13112         $LCTL set_param -n $nsdir.lru_max_age $max_age
13113         [ $remaining -eq 0 ] || error "$remaining locks are not canceled"
13114         unlinkmany $DIR/$tdir/f $nr
13115 }
13116 run_test 124c "LRUR cancel very aged locks"
13117
13118 test_124d() {
13119         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13120         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
13121                 skip_env "no lru resize on server"
13122
13123         # cache ununsed locks on client
13124         local nr=100
13125
13126         lru_resize_disable mdc
13127         stack_trap "lru_resize_enable mdc" EXIT
13128
13129         cancel_lru_locks mdc
13130
13131         # asynchronous object destroy at MDT could cause bl ast to client
13132         test_mkdir $DIR/$tdir
13133         createmany -o $DIR/$tdir/f $nr ||
13134                 error "failed to create $nr files in $DIR/$tdir"
13135         stack_trap "unlinkmany $DIR/$tdir/f $nr" EXIT
13136
13137         ls -l $DIR/$tdir > /dev/null
13138
13139         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
13140         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
13141         local max_age=$($LCTL get_param -n $nsdir.lru_max_age)
13142         local recalc_p=$($LCTL get_param -n $nsdir.pool.recalc_period)
13143
13144         echo "unused=$unused, max_age=$max_age, recalc_p=$recalc_p"
13145
13146         # set lru_max_age to 1 sec
13147         $LCTL set_param $nsdir.lru_max_age=1000 # milliseconds
13148         stack_trap "$LCTL set_param -n $nsdir.lru_max_age $max_age" EXIT
13149
13150         echo "sleep $((recalc_p * 2)) seconds..."
13151         sleep $((recalc_p * 2))
13152
13153         local remaining=$($LCTL get_param -n $nsdir.lock_unused_count)
13154
13155         [ $remaining -eq 0 ] || error "$remaining locks are not canceled"
13156 }
13157 run_test 124d "cancel very aged locks if lru-resize diasbaled"
13158
13159 test_125() { # 13358
13160         $LCTL get_param -n llite.*.client_type | grep -q local ||
13161                 skip "must run as local client"
13162         $LCTL get_param -n mdc.*-mdc-*.connect_flags | grep -q acl ||
13163                 skip_env "must have acl enabled"
13164         [ -z "$(which setfacl)" ] && skip_env "must have setfacl tool"
13165
13166         test_mkdir $DIR/$tdir
13167         $LFS setstripe -S 65536 -c -1 $DIR/$tdir || error "setstripe failed"
13168         setfacl -R -m u:bin:rwx $DIR/$tdir || error "setfacl $DIR/$tdir failed"
13169         ls -ld $DIR/$tdir || error "cannot access $DIR/$tdir"
13170 }
13171 run_test 125 "don't return EPROTO when a dir has a non-default striping and ACLs"
13172
13173 test_126() { # bug 12829/13455
13174         $GSS && skip_env "must run as gss disabled"
13175         $LCTL get_param -n llite.*.client_type | grep -q local ||
13176                 skip "must run as local client"
13177         [ "$UID" != 0 ] && skip "must run as root, not UID $UID"
13178
13179         $RUNAS -u 0 -g 1 touch $DIR/$tfile || error "touch failed"
13180         gid=`ls -n $DIR/$tfile | awk '{print $4}'`
13181         rm -f $DIR/$tfile
13182         [ $gid -eq "1" ] || error "gid is set to" $gid "instead of 1"
13183 }
13184 run_test 126 "check that the fsgid provided by the client is taken into account"
13185
13186 test_127a() { # bug 15521
13187         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13188         local name count samp unit min max sum sumsq
13189
13190         $LFS setstripe -i 0 -c 1 $DIR/$tfile || error "setstripe failed"
13191         echo "stats before reset"
13192         $LCTL get_param osc.*.stats
13193         $LCTL set_param osc.*.stats=0
13194         local fsize=$((2048 * 1024))
13195
13196         dd if=/dev/zero of=$DIR/$tfile bs=$fsize count=1
13197         cancel_lru_locks osc
13198         dd if=$DIR/$tfile of=/dev/null bs=$fsize
13199
13200         $LCTL get_param osc.*0000-osc-*.stats | grep samples > $DIR/$tfile.tmp
13201         stack_trap "rm -f $TMP/$tfile.tmp"
13202         while read name count samp unit min max sum sumsq; do
13203                 echo "got name=$name count=$count unit=$unit min=$min max=$max"
13204                 [ ! $min ] && error "Missing min value for $name proc entry"
13205                 eval $name=$count || error "Wrong proc format"
13206
13207                 case $name in
13208                 read_bytes|write_bytes)
13209                         [[ "$unit" =~ "bytes" ]] ||
13210                                 error "unit is not 'bytes': $unit"
13211                         (( $min >= 4096 )) || error "min is too small: $min"
13212                         (( $min <= $fsize )) || error "min is too big: $min"
13213                         (( $max >= 4096 )) || error "max is too small: $max"
13214                         (( $max <= $fsize )) || error "max is too big: $max"
13215                         (( $sum == $fsize )) || error "sum is wrong: $sum"
13216                         (( $sumsq >= ($fsize / 4096) * (4096 * 4096) )) ||
13217                                 error "sumsquare is too small: $sumsq"
13218                         (( $sumsq <= $fsize * $fsize )) ||
13219                                 error "sumsquare is too big: $sumsq"
13220                         ;;
13221                 ost_read|ost_write)
13222                         [[ "$unit" =~ "usec" ]] ||
13223                                 error "unit is not 'usec': $unit"
13224                         ;;
13225                 *)      ;;
13226                 esac
13227         done < $DIR/$tfile.tmp
13228
13229         #check that we actually got some stats
13230         [ "$read_bytes" ] || error "Missing read_bytes stats"
13231         [ "$write_bytes" ] || error "Missing write_bytes stats"
13232         [ "$read_bytes" != 0 ] || error "no read done"
13233         [ "$write_bytes" != 0 ] || error "no write done"
13234 }
13235 run_test 127a "verify the client stats are sane"
13236
13237 test_127b() { # bug LU-333
13238         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13239         local name count samp unit min max sum sumsq
13240
13241         echo "stats before reset"
13242         $LCTL get_param llite.*.stats
13243         $LCTL set_param llite.*.stats=0
13244
13245         # perform 2 reads and writes so MAX is different from SUM.
13246         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1
13247         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1
13248         cancel_lru_locks osc
13249         dd if=$DIR/$tfile of=/dev/null bs=$PAGE_SIZE count=1
13250         dd if=$DIR/$tfile of=/dev/null bs=$PAGE_SIZE count=1
13251
13252         $LCTL get_param llite.*.stats | grep samples > $TMP/$tfile.tmp
13253         stack_trap "rm -f $TMP/$tfile.tmp"
13254         while read name count samp unit min max sum sumsq; do
13255                 echo "got name=$name count=$count unit=$unit min=$min max=$max"
13256                 eval $name=$count || error "Wrong proc format"
13257
13258                 case $name in
13259                 read_bytes|write_bytes)
13260                         [[ "$unit" =~ "bytes" ]] ||
13261                                 error "unit is not 'bytes': $unit"
13262                         (( $count == 2 )) || error "count is not 2: $count"
13263                         (( $min == $PAGE_SIZE )) ||
13264                                 error "min is not $PAGE_SIZE: $min"
13265                         (( $max == $PAGE_SIZE )) ||
13266                                 error "max is not $PAGE_SIZE: $max"
13267                         (( $sum == $PAGE_SIZE * 2 )) ||
13268                                 error "sum is not $((PAGE_SIZE * 2)): $sum"
13269                         ;;
13270                 read|write)
13271                         [[ "$unit" =~ "usec" ]] ||
13272                                 error "unit is not 'usec': $unit"
13273                         ;;
13274                 *)      ;;
13275                 esac
13276         done < $TMP/$tfile.tmp
13277
13278         #check that we actually got some stats
13279         [ "$read_bytes" ] || error "Missing read_bytes stats"
13280         [ "$write_bytes" ] || error "Missing write_bytes stats"
13281         [ "$read_bytes" != 0 ] || error "no read done"
13282         [ "$write_bytes" != 0 ] || error "no write done"
13283 }
13284 run_test 127b "verify the llite client stats are sane"
13285
13286 test_127c() { # LU-12394
13287         [ "$OSTCOUNT" -lt "2" ] && skip_env "needs >= 2 OSTs"
13288         local size
13289         local bsize
13290         local reads
13291         local writes
13292         local count
13293
13294         $LCTL set_param llite.*.extents_stats=1
13295         stack_trap "$LCTL set_param llite.*.extents_stats=0" EXIT
13296
13297         # Use two stripes so there is enough space in default config
13298         $LFS setstripe -c 2 $DIR/$tfile
13299
13300         # Extent stats start at 0-4K and go in power of two buckets
13301         # LL_HIST_START = 12 --> 2^12 = 4K
13302         # We do 3K*2^i, so 3K, 6K, 12K, 24K... hitting each bucket.
13303         # We do not do buckets larger than 64 MiB to avoid ENOSPC issues on
13304         # small configs
13305         for size in 3K 6K 12K 24K 48K 96K 192K 384K 768K 1536K 3M 6M 12M 24M 48M;
13306                 do
13307                 # Write and read, 2x each, second time at a non-zero offset
13308                 dd if=/dev/zero of=$DIR/$tfile bs=$size count=1
13309                 dd if=/dev/zero of=$DIR/$tfile bs=$size count=1 seek=10
13310                 dd if=$DIR/$tfile of=/dev/null bs=$size count=1
13311                 dd if=$DIR/$tfile of=/dev/null bs=$size count=1 seek=10
13312                 rm -f $DIR/$tfile
13313         done
13314
13315         $LCTL get_param llite.*.extents_stats
13316
13317         count=2
13318         for bsize in 4K 8K 16K 32K 64K 128K 256K 512K 1M 2M 4M 8M 16M 32M 64M;
13319                 do
13320                 local bucket=$($LCTL get_param -n llite.*.extents_stats |
13321                                 grep -m 1 $bsize)
13322                 reads=$(echo $bucket | awk '{print $5}')
13323                 writes=$(echo $bucket | awk '{print $9}')
13324                 [ "$reads" -eq $count ] ||
13325                         error "$reads reads in < $bsize bucket, expect $count"
13326                 [ "$writes" -eq $count ] ||
13327                         error "$writes writes in < $bsize bucket, expect $count"
13328         done
13329
13330         # Test mmap write and read
13331         $LCTL set_param llite.*.extents_stats=c
13332         size=512
13333         dd if=/dev/zero of=$DIR/$tfile bs=${size}K count=1
13334         $MULTIOP $DIR/$tfile OSMRUc || error "$MULTIOP $DIR/$tfile failed"
13335         $MULTIOP $DIR/$tfile OSMWUc || error "$MULTIOP $DIR/$tfile failed"
13336
13337         $LCTL get_param llite.*.extents_stats
13338
13339         count=$(((size*1024) / PAGE_SIZE))
13340
13341         bsize=$((2 * PAGE_SIZE / 1024))K
13342
13343         bucket=$($LCTL get_param -n llite.*.extents_stats |
13344                         grep -m 1 $bsize)
13345         reads=$(echo $bucket | awk '{print $5}')
13346         writes=$(echo $bucket | awk '{print $9}')
13347         # mmap writes fault in the page first, creating an additonal read
13348         [ "$reads" -eq $((2 * count)) ] ||
13349                 error "$reads reads in < $bsize bucket, expect $count"
13350         [ "$writes" -eq $count ] ||
13351                 error "$writes writes in < $bsize bucket, expect $count"
13352 }
13353 run_test 127c "test llite extent stats with regular & mmap i/o"
13354
13355 test_128() { # bug 15212
13356         touch $DIR/$tfile
13357         $LFS 2>&1 <<-EOF | tee $TMP/$tfile.log
13358                 find $DIR/$tfile
13359                 find $DIR/$tfile
13360         EOF
13361
13362         result=$(grep error $TMP/$tfile.log)
13363         rm -f $DIR/$tfile $TMP/$tfile.log
13364         [ -z "$result" ] ||
13365                 error "consecutive find's under interactive lfs failed"
13366 }
13367 run_test 128 "interactive lfs for 2 consecutive find's"
13368
13369 set_dir_limits () {
13370         local mntdev
13371         local canondev
13372         local node
13373
13374         local ldproc=/proc/fs/ldiskfs
13375         local facets=$(get_facets MDS)
13376
13377         for facet in ${facets//,/ }; do
13378                 canondev=$(ldiskfs_canon \
13379                            *.$(convert_facet2label $facet).mntdev $facet)
13380                 do_facet $facet "test -e $ldproc/$canondev/max_dir_size" ||
13381                         ldproc=/sys/fs/ldiskfs
13382                 do_facet $facet "echo $1 >$ldproc/$canondev/max_dir_size"
13383                 do_facet $facet "echo $2 >$ldproc/$canondev/warning_dir_size"
13384         done
13385 }
13386
13387 check_mds_dmesg() {
13388         local facets=$(get_facets MDS)
13389         for facet in ${facets//,/ }; do
13390                 do_facet $facet "dmesg | tail -3 | grep $1" && return 0
13391         done
13392         return 1
13393 }
13394
13395 test_129() {
13396         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13397         [[ $MDS1_VERSION -ge $(version_code 2.5.56) ]] ||
13398                 skip "Need MDS version with at least 2.5.56"
13399         if [ "$mds1_FSTYPE" != ldiskfs ]; then
13400                 skip_env "ldiskfs only test"
13401         fi
13402         remote_mds_nodsh && skip "remote MDS with nodsh"
13403
13404         local ENOSPC=28
13405         local has_warning=false
13406
13407         rm -rf $DIR/$tdir
13408         mkdir -p $DIR/$tdir
13409
13410         # block size of mds1
13411         local maxsize=$(($($LCTL get_param -n mdc.*MDT0000*.blocksize) * 8))
13412         set_dir_limits $maxsize $((maxsize * 6 / 8))
13413         stack_trap "set_dir_limits 0 0"
13414         stack_trap "unlinkmany $DIR/$tdir/file_base_ 2000 || true"
13415         local dirsize=$(stat -c%s "$DIR/$tdir")
13416         local nfiles=0
13417         while (( $dirsize <= $maxsize )); do
13418                 $MCREATE $DIR/$tdir/file_base_$nfiles
13419                 rc=$?
13420                 # check two errors:
13421                 # ENOSPC for ext4 max_dir_size, which has been used since
13422                 # kernel v3.6-rc1-8-gdf981d03ee, lustre v2_4_50_0-79-gaed82035c0
13423                 if (( rc == ENOSPC )); then
13424                         set_dir_limits 0 0
13425                         echo "rc=$rc returned as expected after $nfiles files"
13426
13427                         createmany -o $DIR/$tdir/file_extra_$nfiles. 5 ||
13428                                 error "create failed w/o dir size limit"
13429
13430                         # messages may be rate limited if test is run repeatedly
13431                         check_mds_dmesg '"is approaching max"' ||
13432                                 echo "warning message should be output"
13433                         check_mds_dmesg '"has reached max"' ||
13434                                 echo "reached message should be output"
13435
13436                         dirsize=$(stat -c%s "$DIR/$tdir")
13437
13438                         [[ $dirsize -ge $maxsize ]] && return 0
13439                         error "dirsize $dirsize < $maxsize after $nfiles files"
13440                 elif (( rc != 0 )); then
13441                         break
13442                 fi
13443                 nfiles=$((nfiles + 1))
13444                 dirsize=$(stat -c%s "$DIR/$tdir")
13445         done
13446
13447         error "rc=$rc, size=$dirsize/$maxsize, mdt=$MDSCOUNT, nfiles=$nfiles"
13448 }
13449 run_test 129 "test directory size limit ========================"
13450
13451 OLDIFS="$IFS"
13452 cleanup_130() {
13453         trap 0
13454         IFS="$OLDIFS"
13455 }
13456
13457 test_130a() {
13458         local filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
13459         [ -n "$filefrag_op" ] && skip_env "filefrag does not support FIEMAP"
13460
13461         trap cleanup_130 EXIT RETURN
13462
13463         local fm_file=$DIR/$tfile
13464         $LFS setstripe -S 65536 -c 1 $fm_file || error "setstripe on $fm_file"
13465         dd if=/dev/zero of=$fm_file bs=65536 count=1 ||
13466                 error "dd failed for $fm_file"
13467
13468         # LU-1795: test filefrag/FIEMAP once, even if unsupported
13469         filefrag -ves $fm_file
13470         RC=$?
13471         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
13472                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
13473         [ $RC != 0 ] && error "filefrag $fm_file failed"
13474
13475         filefrag_op=$(filefrag -ve -k $fm_file |
13476                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
13477         lun=$($LFS getstripe -i $fm_file)
13478
13479         start_blk=`echo $filefrag_op | cut -d: -f2 | cut -d. -f1`
13480         IFS=$'\n'
13481         tot_len=0
13482         for line in $filefrag_op
13483         do
13484                 frag_lun=`echo $line | cut -d: -f5`
13485                 ext_len=`echo $line | cut -d: -f4`
13486                 if (( $frag_lun != $lun )); then
13487                         cleanup_130
13488                         error "FIEMAP on 1-stripe file($fm_file) failed"
13489                         return
13490                 fi
13491                 (( tot_len += ext_len ))
13492         done
13493
13494         if (( lun != frag_lun || start_blk != 0 || tot_len != 64 )); then
13495                 cleanup_130
13496                 error "FIEMAP on 1-stripe file($fm_file) failed;"
13497                 return
13498         fi
13499
13500         cleanup_130
13501
13502         echo "FIEMAP on single striped file succeeded"
13503 }
13504 run_test 130a "FIEMAP (1-stripe file)"
13505
13506 test_130b() {
13507         [ "$OSTCOUNT" -lt "2" ] && skip_env "needs >= 2 OSTs"
13508
13509         local filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
13510         [ -n "$filefrag_op" ] && skip_env "filefrag does not support FIEMAP"
13511
13512         trap cleanup_130 EXIT RETURN
13513
13514         local fm_file=$DIR/$tfile
13515         $LFS setstripe -S 65536 -c $OSTCOUNT $fm_file ||
13516                         error "setstripe on $fm_file"
13517         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
13518                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
13519
13520         dd if=/dev/zero of=$fm_file bs=1M count=$OSTCOUNT ||
13521                 error "dd failed on $fm_file"
13522
13523         filefrag -ves $fm_file || error "filefrag $fm_file failed"
13524         filefrag_op=$(filefrag -ve -k $fm_file |
13525                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
13526
13527         last_lun=$(echo $filefrag_op | cut -d: -f5 |
13528                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
13529
13530         IFS=$'\n'
13531         tot_len=0
13532         num_luns=1
13533         for line in $filefrag_op
13534         do
13535                 frag_lun=$(echo $line | cut -d: -f5 |
13536                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
13537                 ext_len=$(echo $line | cut -d: -f4)
13538                 if (( $frag_lun != $last_lun )); then
13539                         if (( tot_len != 1024 )); then
13540                                 cleanup_130
13541                                 error "FIEMAP on $fm_file failed; returned " \
13542                                 "len $tot_len for OST $last_lun instead of 1024"
13543                                 return
13544                         else
13545                                 (( num_luns += 1 ))
13546                                 tot_len=0
13547                         fi
13548                 fi
13549                 (( tot_len += ext_len ))
13550                 last_lun=$frag_lun
13551         done
13552         if (( num_luns != $OSTCOUNT || tot_len != 1024 )); then
13553                 cleanup_130
13554                 error "FIEMAP on $fm_file failed; returned wrong number of " \
13555                         "luns or wrong len for OST $last_lun"
13556                 return
13557         fi
13558
13559         cleanup_130
13560
13561         echo "FIEMAP on $OSTCOUNT-stripe file succeeded"
13562 }
13563 run_test 130b "FIEMAP ($OSTCOUNT-stripe file)"
13564
13565 test_130c() {
13566         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
13567
13568         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
13569         [ -n "$filefrag_op" ] && skip "filefrag does not support FIEMAP"
13570
13571         trap cleanup_130 EXIT RETURN
13572
13573         local fm_file=$DIR/$tfile
13574         $LFS setstripe -S 65536 -c 2 $fm_file || error "setstripe on $fm_file"
13575         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
13576                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
13577
13578         dd if=/dev/zero of=$fm_file seek=1 bs=1M count=1 ||
13579                         error "dd failed on $fm_file"
13580
13581         filefrag -ves $fm_file || error "filefrag $fm_file failed"
13582         filefrag_op=$(filefrag -ve -k $fm_file |
13583                 sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
13584
13585         last_lun=$(echo $filefrag_op | cut -d: -f5 |
13586                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
13587
13588         IFS=$'\n'
13589         tot_len=0
13590         num_luns=1
13591         for line in $filefrag_op
13592         do
13593                 frag_lun=$(echo $line | cut -d: -f5 |
13594                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
13595                 ext_len=$(echo $line | cut -d: -f4)
13596                 if (( $frag_lun != $last_lun )); then
13597                         logical=`echo $line | cut -d: -f2 | cut -d. -f1`
13598                         if (( logical != 512 )); then
13599                                 cleanup_130
13600                                 error "FIEMAP on $fm_file failed; returned " \
13601                                 "logical start for lun $logical instead of 512"
13602                                 return
13603                         fi
13604                         if (( tot_len != 512 )); then
13605                                 cleanup_130
13606                                 error "FIEMAP on $fm_file failed; returned " \
13607                                 "len $tot_len for OST $last_lun instead of 1024"
13608                                 return
13609                         else
13610                                 (( num_luns += 1 ))
13611                                 tot_len=0
13612                         fi
13613                 fi
13614                 (( tot_len += ext_len ))
13615                 last_lun=$frag_lun
13616         done
13617         if (( num_luns != 2 || tot_len != 512 )); then
13618                 cleanup_130
13619                 error "FIEMAP on $fm_file failed; returned wrong number of " \
13620                         "luns or wrong len for OST $last_lun"
13621                 return
13622         fi
13623
13624         cleanup_130
13625
13626         echo "FIEMAP on 2-stripe file with hole succeeded"
13627 }
13628 run_test 130c "FIEMAP (2-stripe file with hole)"
13629
13630 test_130d() {
13631         [[ $OSTCOUNT -lt 3 ]] && skip_env "needs >= 3 OSTs"
13632
13633         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
13634         [ -n "$filefrag_op" ] && skip "filefrag does not support FIEMAP"
13635
13636         trap cleanup_130 EXIT RETURN
13637
13638         local fm_file=$DIR/$tfile
13639         $LFS setstripe -S 65536 -c $OSTCOUNT $fm_file ||
13640                         error "setstripe on $fm_file"
13641         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
13642                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
13643
13644         local actual_stripe_count=$($LFS getstripe -c $fm_file)
13645         dd if=/dev/zero of=$fm_file bs=1M count=$actual_stripe_count ||
13646                 error "dd failed on $fm_file"
13647
13648         filefrag -ves $fm_file || error "filefrag $fm_file failed"
13649         filefrag_op=$(filefrag -ve -k $fm_file |
13650                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
13651
13652         last_lun=$(echo $filefrag_op | cut -d: -f5 |
13653                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
13654
13655         IFS=$'\n'
13656         tot_len=0
13657         num_luns=1
13658         for line in $filefrag_op
13659         do
13660                 frag_lun=$(echo $line | cut -d: -f5 |
13661                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
13662                 ext_len=$(echo $line | cut -d: -f4)
13663                 if (( $frag_lun != $last_lun )); then
13664                         if (( tot_len != 1024 )); then
13665                                 cleanup_130
13666                                 error "FIEMAP on $fm_file failed; returned " \
13667                                 "len $tot_len for OST $last_lun instead of 1024"
13668                                 return
13669                         else
13670                                 (( num_luns += 1 ))
13671                                 tot_len=0
13672                         fi
13673                 fi
13674                 (( tot_len += ext_len ))
13675                 last_lun=$frag_lun
13676         done
13677         if (( num_luns != actual_stripe_count || tot_len != 1024 )); then
13678                 cleanup_130
13679                 error "FIEMAP on $fm_file failed; returned wrong number of " \
13680                         "luns or wrong len for OST $last_lun"
13681                 return
13682         fi
13683
13684         cleanup_130
13685
13686         echo "FIEMAP on N-stripe file succeeded"
13687 }
13688 run_test 130d "FIEMAP (N-stripe file)"
13689
13690 test_130e() {
13691         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
13692
13693         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
13694         [ -n "$filefrag_op" ] && skip_env "filefrag does not support FIEMAP"
13695
13696         trap cleanup_130 EXIT RETURN
13697
13698         local fm_file=$DIR/$tfile
13699         $LFS setstripe -S 131072 -c 2 $fm_file || error "setstripe on $fm_file"
13700
13701         NUM_BLKS=512
13702         EXPECTED_LEN=$(( (NUM_BLKS / 2) * 64 ))
13703         for ((i = 0; i < $NUM_BLKS; i++)); do
13704                 dd if=/dev/zero of=$fm_file count=1 bs=64k seek=$((2*$i)) \
13705                         conv=notrunc > /dev/null 2>&1
13706         done
13707
13708         filefrag -ves $fm_file || error "filefrag $fm_file failed"
13709         filefrag_op=$(filefrag -ve -k $fm_file |
13710                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
13711
13712         last_lun=$(echo $filefrag_op | cut -d: -f5)
13713
13714         IFS=$'\n'
13715         tot_len=0
13716         num_luns=1
13717         for line in $filefrag_op; do
13718                 frag_lun=$(echo $line | cut -d: -f5)
13719                 ext_len=$(echo $line | cut -d: -f4)
13720                 if [[ "$frag_lun" != "$last_lun" ]]; then
13721                         if (( tot_len != $EXPECTED_LEN )); then
13722                                 cleanup_130
13723                                 error "OST$last_lun $tot_len != $EXPECTED_LEN"
13724                         else
13725                                 (( num_luns += 1 ))
13726                                 tot_len=0
13727                         fi
13728                 fi
13729                 (( tot_len += ext_len ))
13730                 last_lun=$frag_lun
13731         done
13732         if (( num_luns != 2 || tot_len != $EXPECTED_LEN )); then
13733                 cleanup_130
13734                 error "OST$last_lun $num_luns != 2, $tot_len != $EXPECTED_LEN"
13735         fi
13736
13737         echo "FIEMAP with continuation calls succeeded"
13738 }
13739 run_test 130e "FIEMAP (test continuation FIEMAP calls)"
13740
13741 test_130f() {
13742         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
13743         [ -n "$filefrag_op" ] && skip "filefrag does not support FIEMAP"
13744
13745         local fm_file=$DIR/$tfile
13746         $MULTIOP $fm_file oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:T33554432c ||
13747                 error "multiop create with lov_delay_create on $fm_file"
13748
13749         filefrag -ves $fm_file || error "filefrag $fm_file failed"
13750         filefrag_extents=$(filefrag -vek $fm_file |
13751                            awk '/extents? found/ { print $2 }')
13752         if [[ "$filefrag_extents" != "0" ]]; then
13753                 error "$fm_file: filefrag_extents=$filefrag_extents != 0"
13754         fi
13755
13756         rm -f $fm_file
13757 }
13758 run_test 130f "FIEMAP (unstriped file)"
13759
13760 test_130g() {
13761         local file=$DIR/$tfile
13762         local nr=$((OSTCOUNT * 100))
13763
13764         $LFS setstripe -C $nr $file ||
13765                 error "failed to setstripe -C $nr $file"
13766
13767         dd if=/dev/zero of=$file count=$nr bs=1M
13768         sync
13769         nr=$($LFS getstripe -c $file)
13770
13771         local extents=$(filefrag -v $file |
13772                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}' | wc -l)
13773
13774         echo "filefrag list $extents extents in file with stripecount $nr"
13775         if (( extents < nr )); then
13776                 $LFS getstripe $file
13777                 filefrag -v $file
13778                 error "filefrag printed $extents < $nr extents"
13779         fi
13780
13781         rm -f $file
13782 }
13783 run_test 130g "FIEMAP (overstripe file)"
13784
13785 # Test for writev/readv
13786 test_131a() {
13787         rwv -f $DIR/$tfile -w -n 3 524288 1048576 1572864 ||
13788                 error "writev test failed"
13789         rwv -f $DIR/$tfile -r -v -n 2 1572864 1048576 ||
13790                 error "readv failed"
13791         rm -f $DIR/$tfile
13792 }
13793 run_test 131a "test iov's crossing stripe boundary for writev/readv"
13794
13795 test_131b() {
13796         local fsize=$((524288 + 1048576 + 1572864))
13797         rwv -f $DIR/$tfile -w -a -n 3 524288 1048576 1572864 &&
13798                 $CHECKSTAT -t file $DIR/$tfile -s $fsize ||
13799                         error "append writev test failed"
13800
13801         ((fsize += 1572864 + 1048576))
13802         rwv -f $DIR/$tfile -w -a -n 2 1572864 1048576 &&
13803                 $CHECKSTAT -t file $DIR/$tfile -s $fsize ||
13804                         error "append writev test failed"
13805         rm -f $DIR/$tfile
13806 }
13807 run_test 131b "test append writev"
13808
13809 test_131c() {
13810         rwv -f $DIR/$tfile -w -d -n 1 1048576 || return 0
13811         error "NOT PASS"
13812 }
13813 run_test 131c "test read/write on file w/o objects"
13814
13815 test_131d() {
13816         rwv -f $DIR/$tfile -w -n 1 1572864
13817         NOB=`rwv -f $DIR/$tfile -r -n 3 524288 524288 1048576 | awk '/error/ {print $6}'`
13818         if [ "$NOB" != 1572864 ]; then
13819                 error "Short read filed: read $NOB bytes instead of 1572864"
13820         fi
13821         rm -f $DIR/$tfile
13822 }
13823 run_test 131d "test short read"
13824
13825 test_131e() {
13826         rwv -f $DIR/$tfile -w -s 1048576 -n 1 1048576
13827         rwv -f $DIR/$tfile -r -z -s 0 -n 1 524288 || \
13828         error "read hitting hole failed"
13829         rm -f $DIR/$tfile
13830 }
13831 run_test 131e "test read hitting hole"
13832
13833 check_stats() {
13834         local facet=$1
13835         local op=$2
13836         local want=${3:-0}
13837         local res
13838
13839         case $facet in
13840         mds*) res=$(do_facet $facet \
13841                    $LCTL get_param mdt.$FSNAME-MDT0000.md_stats | grep "$op")
13842                  ;;
13843         ost*) res=$(do_facet $facet \
13844                    $LCTL get_param obdfilter.$FSNAME-OST0000.stats | grep "$op")
13845                  ;;
13846         *) error "Wrong facet '$facet'" ;;
13847         esac
13848         [ "$res" ] || error "The counter for $op on $facet was not incremented"
13849         # if the argument $3 is zero, it means any stat increment is ok.
13850         if [[ $want -gt 0 ]]; then
13851                 local count=$(echo $res | awk '{ print $2 }')
13852                 [[ $count -ne $want ]] &&
13853                         error "The $op counter on $facet is $count, not $want"
13854         fi
13855 }
13856
13857 test_133a() {
13858         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13859         remote_ost_nodsh && skip "remote OST with nodsh"
13860         remote_mds_nodsh && skip "remote MDS with nodsh"
13861         do_facet $SINGLEMDS $LCTL list_param mdt.*.rename_stats ||
13862                 skip_env "MDS doesn't support rename stats"
13863
13864         local testdir=$DIR/${tdir}/stats_testdir
13865
13866         mkdir -p $DIR/${tdir}
13867
13868         # clear stats.
13869         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
13870         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
13871
13872         # verify mdt stats first.
13873         mkdir ${testdir} || error "mkdir failed"
13874         check_stats $SINGLEMDS "mkdir" 1
13875         touch ${testdir}/${tfile} || error "touch failed"
13876         check_stats $SINGLEMDS "open" 1
13877         check_stats $SINGLEMDS "close" 1
13878         [ $MDS1_VERSION -ge $(version_code 2.8.54) ] && {
13879                 mknod ${testdir}/${tfile}-pipe p || error "mknod failed"
13880                 check_stats $SINGLEMDS "mknod" 2
13881         }
13882         rm -f ${testdir}/${tfile}-pipe || error "pipe remove failed"
13883         check_stats $SINGLEMDS "unlink" 1
13884         rm -f ${testdir}/${tfile} || error "file remove failed"
13885         check_stats $SINGLEMDS "unlink" 2
13886
13887         # remove working dir and check mdt stats again.
13888         rmdir ${testdir} || error "rmdir failed"
13889         check_stats $SINGLEMDS "rmdir" 1
13890
13891         local testdir1=$DIR/${tdir}/stats_testdir1
13892         mkdir -p ${testdir}
13893         mkdir -p ${testdir1}
13894         touch ${testdir1}/test1
13895         mv ${testdir1}/test1 ${testdir} || error "file crossdir rename"
13896         check_stats $SINGLEMDS "crossdir_rename" 1
13897
13898         mv ${testdir}/test1 ${testdir}/test0 || error "file samedir rename"
13899         check_stats $SINGLEMDS "samedir_rename" 1
13900
13901         rm -rf $DIR/${tdir}
13902 }
13903 run_test 133a "Verifying MDT stats ========================================"
13904
13905 test_133b() {
13906         local res
13907
13908         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13909         remote_ost_nodsh && skip "remote OST with nodsh"
13910         remote_mds_nodsh && skip "remote MDS with nodsh"
13911
13912         local testdir=$DIR/${tdir}/stats_testdir
13913
13914         mkdir -p ${testdir} || error "mkdir failed"
13915         touch ${testdir}/${tfile} || error "touch failed"
13916         cancel_lru_locks mdc
13917
13918         # clear stats.
13919         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
13920         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
13921
13922         # extra mdt stats verification.
13923         chmod 444 ${testdir}/${tfile} || error "chmod failed"
13924         check_stats $SINGLEMDS "setattr" 1
13925         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
13926         if [ $MDS1_VERSION -ne $(version_code 2.2.0) ]
13927         then            # LU-1740
13928                 ls -l ${testdir}/${tfile} > /dev/null|| error "ls failed"
13929                 check_stats $SINGLEMDS "getattr" 1
13930         fi
13931         rm -rf $DIR/${tdir}
13932
13933         # when DNE is enabled, MDT uses STATFS RPC to ping other targets
13934         # so the check below is not reliable
13935         [ $MDSCOUNT -eq 1 ] || return 0
13936
13937         # Sleep to avoid a cached response.
13938         #define OBD_STATFS_CACHE_SECONDS 1
13939         sleep 2
13940         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
13941         do_facet ost1 $LCTL set_param obdfilter.*.exports.*.stats=clear
13942         $LFS df || error "lfs failed"
13943         check_stats $SINGLEMDS "statfs" 1
13944
13945         # check aggregated statfs (LU-10018)
13946         [ $MDS1_VERSION -lt $(version_code 2.11.54) ] &&
13947                 return 0
13948         [ $CLIENT_VERSION -lt $(version_code 2.11.54) ] &&
13949                 return 0
13950         sleep 2
13951         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
13952         do_facet ost1 $LCTL set_param obdfilter.*.exports.*.stats=clear
13953         df $DIR
13954         check_stats $SINGLEMDS "statfs" 1
13955
13956         # We want to check that the client didn't send OST_STATFS to
13957         # ost1 but the MDT also uses OST_STATFS for precreate. So some
13958         # extra care is needed here.
13959         if remote_mds; then
13960                 local nid=$($LCTL list_nids | head -1 | sed  "s/\./\\\./g")
13961                 local param="obdfilter.$FSNAME-OST0000.exports.'$nid'.stats"
13962
13963                 res=$(do_facet ost1 $LCTL get_param $param | grep statfs)
13964                 [ "$res" ] && error "OST got STATFS"
13965         fi
13966
13967         return 0
13968 }
13969 run_test 133b "Verifying extra MDT stats =================================="
13970
13971 test_133c() {
13972         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13973         remote_ost_nodsh && skip "remote OST with nodsh"
13974         remote_mds_nodsh && skip "remote MDS with nodsh"
13975
13976         local testdir=$DIR/$tdir/stats_testdir
13977
13978         test_mkdir -p $testdir
13979
13980         # verify obdfilter stats.
13981         $LFS setstripe -c 1 -i 0 $testdir/$tfile
13982         sync
13983         cancel_lru_locks osc
13984         wait_delete_completed
13985
13986         # clear stats.
13987         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
13988         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
13989
13990         dd if=/dev/zero of=$testdir/$tfile conv=notrunc bs=512k count=1 ||
13991                 error "dd failed"
13992         sync
13993         cancel_lru_locks osc
13994         check_stats ost1 "write" 1
13995
13996         dd if=$testdir/$tfile of=/dev/null bs=1k count=1 || error "dd failed"
13997         check_stats ost1 "read" 1
13998
13999         > $testdir/$tfile || error "truncate failed"
14000         check_stats ost1 "punch" 1
14001
14002         rm -f $testdir/$tfile || error "file remove failed"
14003         wait_delete_completed
14004         check_stats ost1 "destroy" 1
14005
14006         rm -rf $DIR/$tdir
14007 }
14008 run_test 133c "Verifying OST stats ========================================"
14009
14010 order_2() {
14011         local value=$1
14012         local orig=$value
14013         local order=1
14014
14015         while [ $value -ge 2 ]; do
14016                 order=$((order*2))
14017                 value=$((value/2))
14018         done
14019
14020         if [ $orig -gt $order ]; then
14021                 order=$((order*2))
14022         fi
14023         echo $order
14024 }
14025
14026 size_in_KMGT() {
14027     local value=$1
14028     local size=('K' 'M' 'G' 'T');
14029     local i=0
14030     local size_string=$value
14031
14032     while [ $value -ge 1024 ]; do
14033         if [ $i -gt 3 ]; then
14034             #T is the biggest unit we get here, if that is bigger,
14035             #just return XXXT
14036             size_string=${value}T
14037             break
14038         fi
14039         value=$((value >> 10))
14040         if [ $value -lt 1024 ]; then
14041             size_string=${value}${size[$i]}
14042             break
14043         fi
14044         i=$((i + 1))
14045     done
14046
14047     echo $size_string
14048 }
14049
14050 get_rename_size() {
14051         local size=$1
14052         local context=${2:-.}
14053         local sample=$(do_facet $SINGLEMDS $LCTL \
14054                 get_param mdt.$FSNAME-MDT0000.rename_stats |
14055                 grep -A1 $context |
14056                 awk '/ '${size}'/ {print $4}' | sed -e "s/,//g")
14057         echo $sample
14058 }
14059
14060 test_133d() {
14061         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14062         remote_ost_nodsh && skip "remote OST with nodsh"
14063         remote_mds_nodsh && skip "remote MDS with nodsh"
14064         do_facet $SINGLEMDS $LCTL list_param mdt.*.rename_stats ||
14065                 skip_env "MDS doesn't support rename stats"
14066
14067         local testdir1=$DIR/${tdir}/stats_testdir1
14068         local testdir2=$DIR/${tdir}/stats_testdir2
14069         mkdir -p $DIR/${tdir}
14070
14071         do_facet $SINGLEMDS $LCTL set_param mdt.*.rename_stats=clear
14072
14073         lfs mkdir -i 0 -c 1 ${testdir1} || error "mkdir failed"
14074         lfs mkdir -i 0 -c 1 ${testdir2} || error "mkdir failed"
14075
14076         createmany -o $testdir1/test 512 || error "createmany failed"
14077
14078         # check samedir rename size
14079         mv ${testdir1}/test0 ${testdir1}/test_0
14080
14081         local testdir1_size=$(ls -l $DIR/${tdir} |
14082                 awk '/stats_testdir1/ {print $5}')
14083         local testdir2_size=$(ls -l $DIR/${tdir} |
14084                 awk '/stats_testdir2/ {print $5}')
14085
14086         testdir1_size=$(order_2 $testdir1_size)
14087         testdir2_size=$(order_2 $testdir2_size)
14088
14089         testdir1_size=$(size_in_KMGT $testdir1_size)
14090         testdir2_size=$(size_in_KMGT $testdir2_size)
14091
14092         echo "source rename dir size: ${testdir1_size}"
14093         echo "target rename dir size: ${testdir2_size}"
14094
14095         local cmd="do_facet $SINGLEMDS $LCTL "
14096         cmd+="get_param mdt.$FSNAME-MDT0000.rename_stats"
14097
14098         eval $cmd || error "$cmd failed"
14099         local samedir=$($cmd | grep 'same_dir')
14100         local same_sample=$(get_rename_size $testdir1_size)
14101         [ -z "$samedir" ] && error "samedir_rename_size count error"
14102         [[ $same_sample -eq 1 ]] ||
14103                 error "samedir_rename_size error $same_sample"
14104         echo "Check same dir rename stats success"
14105
14106         do_facet $SINGLEMDS $LCTL set_param mdt.*.rename_stats=clear
14107
14108         # check crossdir rename size
14109         mv ${testdir1}/test_0 ${testdir2}/test_0
14110
14111         testdir1_size=$(ls -l $DIR/${tdir} |
14112                 awk '/stats_testdir1/ {print $5}')
14113         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         eval $cmd || error "$cmd failed"
14126         local crossdir=$($cmd | grep 'crossdir')
14127         local src_sample=$(get_rename_size $testdir1_size crossdir_src)
14128         local tgt_sample=$(get_rename_size $testdir2_size crossdir_tgt)
14129         [ -z "$crossdir" ] && error "crossdir_rename_size count error"
14130         [[ $src_sample -eq 1 ]] ||
14131                 error "crossdir_rename_size error $src_sample"
14132         [[ $tgt_sample -eq 1 ]] ||
14133                 error "crossdir_rename_size error $tgt_sample"
14134         echo "Check cross dir rename stats success"
14135         rm -rf $DIR/${tdir}
14136 }
14137 run_test 133d "Verifying rename_stats ========================================"
14138
14139 test_133e() {
14140         remote_mds_nodsh && skip "remote MDS with nodsh"
14141         remote_ost_nodsh && skip "remote OST with nodsh"
14142         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14143
14144         local testdir=$DIR/${tdir}/stats_testdir
14145         local ctr f0 f1 bs=32768 count=42 sum
14146
14147         mkdir -p ${testdir} || error "mkdir failed"
14148
14149         $LFS setstripe -c 1 -i 0 ${testdir}/${tfile}
14150
14151         for ctr in {write,read}_bytes; do
14152                 sync
14153                 cancel_lru_locks osc
14154
14155                 do_facet ost1 $LCTL set_param -n \
14156                         "obdfilter.*.exports.clear=clear"
14157
14158                 if [ $ctr = write_bytes ]; then
14159                         f0=/dev/zero
14160                         f1=${testdir}/${tfile}
14161                 else
14162                         f0=${testdir}/${tfile}
14163                         f1=/dev/null
14164                 fi
14165
14166                 dd if=$f0 of=$f1 conv=notrunc bs=$bs count=$count || \
14167                         error "dd failed"
14168                 sync
14169                 cancel_lru_locks osc
14170
14171                 sum=$(do_facet ost1 $LCTL get_param \
14172                         "obdfilter.*.exports.*.stats" |
14173                         awk -v ctr=$ctr 'BEGIN { sum = 0 }
14174                                 $1 == ctr { sum += $7 }
14175                                 END { printf("%0.0f", sum) }')
14176
14177                 if ((sum != bs * count)); then
14178                         error "Bad $ctr sum, expected $((bs * count)), got $sum"
14179                 fi
14180         done
14181
14182         rm -rf $DIR/${tdir}
14183 }
14184 run_test 133e "Verifying OST {read,write}_bytes nid stats ================="
14185
14186 test_133f() {
14187         [[ $(lustre_version_code $facet) -ge $(version_code 2.7.65) ]] ||
14188                 skip "too old lustre for get_param -R ($facet_ver)"
14189
14190         # verifying readability.
14191         $LCTL get_param -R '*' &> /dev/null
14192
14193         # Verifing writability with badarea_io.
14194         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
14195         local skipped_params='force_lbug|changelog_mask|daemon_file'
14196         $LCTL list_param -FR '*' | grep '=' | tr -d = |
14197                 egrep -v "$skipped_params" |
14198                 xargs -n 1 find $proc_dirs -name |
14199                 xargs -n 1 badarea_io ||
14200                 error "client badarea_io failed"
14201
14202         # remount the FS in case writes/reads /proc break the FS
14203         cleanup || error "failed to unmount"
14204         setup || error "failed to setup"
14205 }
14206 run_test 133f "Check reads/writes of client lustre proc files with bad area io"
14207
14208 test_133g() {
14209         remote_mds_nodsh && skip "remote MDS with nodsh"
14210         remote_ost_nodsh && skip "remote OST with nodsh"
14211
14212         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
14213         local skipped_params="'force_lbug|changelog_mask|daemon_file'"
14214         local facet
14215         for facet in mds1 ost1; do
14216                 local facet_ver=$(lustre_version_code $facet)
14217                 if [ $facet_ver -ge $(version_code 2.7.65) ]; then
14218                         do_facet $facet "$LCTL get_param -R '*'" &> /dev/null
14219                 else
14220                         log "$facet: too old lustre for get_param -R"
14221                 fi
14222                 if [ $facet_ver -ge $(version_code 2.5.54) ]; then
14223                         do_facet $facet "$LCTL list_param -FR '*' | grep '=' |
14224                                 tr -d = | egrep -v $skipped_params |
14225                                 xargs -n 1 find $proc_dirs -name |
14226                                 xargs -n 1 badarea_io" ||
14227                                         error "$facet badarea_io failed"
14228                 else
14229                         skip_noexit "$facet: too old lustre for get_param -R"
14230                 fi
14231         done
14232
14233         # remount the FS in case writes/reads /proc break the FS
14234         cleanup || error "failed to unmount"
14235         setup || error "failed to setup"
14236 }
14237 run_test 133g "Check reads/writes of server lustre proc files with bad area io"
14238
14239 test_133h() {
14240         remote_mds_nodsh && skip "remote MDS with nodsh"
14241         remote_ost_nodsh && skip "remote OST with nodsh"
14242         [[ $MDS1_VERSION -lt $(version_code 2.9.54) ]] &&
14243                 skip "Need MDS version at least 2.9.54"
14244
14245         local facet
14246         for facet in client mds1 ost1; do
14247                 # Get the list of files that are missing the terminating newline
14248                 local plist=$(do_facet $facet
14249                         $LCTL list_param -FR '*' | grep '=' | tr -d =)
14250                 local ent
14251                 for ent in $plist; do
14252                         local missing=$(do_facet $facet $LCTL get_param $ent \|\
14253                                 awk -v FS='\v' -v RS='\v\v' \
14254                                 "'END { if(NR>0 && \\\$NF !~ /.*\\\n\$/) \
14255                                         print FILENAME}'" 2>/dev/null)
14256                         [ -z $missing ] || {
14257                                 do_facet $facet $LCTL get_param $ent | od -An -tx1
14258                                 error "file does not end with newline: $facet-$ent"
14259                         }
14260                 done
14261         done
14262 }
14263 run_test 133h "Proc files should end with newlines"
14264
14265 test_134a() {
14266         remote_mds_nodsh && skip "remote MDS with nodsh"
14267         [[ $MDS1_VERSION -lt $(version_code 2.7.54) ]] &&
14268                 skip "Need MDS version at least 2.7.54"
14269
14270         mkdir_on_mdt0 $DIR/$tdir || error "failed to create $DIR/$tdir"
14271         cancel_lru_locks mdc
14272
14273         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
14274         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
14275         [ $unused -eq 0 ] || error "$unused locks are not cleared"
14276
14277         local nr=1000
14278         createmany -o $DIR/$tdir/f $nr ||
14279                 error "failed to create $nr files in $DIR/$tdir"
14280         unused=$($LCTL get_param -n $nsdir.lock_unused_count)
14281
14282         #define OBD_FAIL_LDLM_WATERMARK_LOW     0x327
14283         do_facet mds1 $LCTL set_param fail_loc=0x327
14284         do_facet mds1 $LCTL set_param fail_val=500
14285         touch $DIR/$tdir/m
14286
14287         echo "sleep 10 seconds ..."
14288         sleep 10
14289         local lck_cnt=$($LCTL get_param -n $nsdir.lock_unused_count)
14290
14291         do_facet mds1 $LCTL set_param fail_loc=0
14292         do_facet mds1 $LCTL set_param fail_val=0
14293         [ $lck_cnt -lt $unused ] ||
14294                 error "No locks reclaimed, before:$unused, after:$lck_cnt"
14295
14296         rm $DIR/$tdir/m
14297         unlinkmany $DIR/$tdir/f $nr
14298 }
14299 run_test 134a "Server reclaims locks when reaching lock_reclaim_threshold"
14300
14301 test_134b() {
14302         remote_mds_nodsh && skip "remote MDS with nodsh"
14303         [[ $MDS1_VERSION -lt $(version_code 2.7.54) ]] &&
14304                 skip "Need MDS version at least 2.7.54"
14305
14306         mkdir_on_mdt0 $DIR/$tdir || error "failed to create $DIR/$tdir"
14307         cancel_lru_locks mdc
14308
14309         local low_wm=$(do_facet mds1 $LCTL get_param -n \
14310                         ldlm.lock_reclaim_threshold_mb)
14311         # disable reclaim temporarily
14312         do_facet mds1 $LCTL set_param ldlm.lock_reclaim_threshold_mb=0
14313
14314         #define OBD_FAIL_LDLM_WATERMARK_HIGH     0x328
14315         do_facet mds1 $LCTL set_param fail_loc=0x328
14316         do_facet mds1 $LCTL set_param fail_val=500
14317
14318         $LCTL set_param debug=+trace
14319
14320         local nr=600
14321         createmany -o $DIR/$tdir/f $nr &
14322         local create_pid=$!
14323
14324         echo "Sleep $TIMEOUT seconds ..."
14325         sleep $TIMEOUT
14326         if ! ps -p $create_pid  > /dev/null 2>&1; then
14327                 do_facet mds1 $LCTL set_param fail_loc=0
14328                 do_facet mds1 $LCTL set_param fail_val=0
14329                 do_facet mds1 $LCTL set_param \
14330                         ldlm.lock_reclaim_threshold_mb=${low_wm}m
14331                 error "createmany finished incorrectly!"
14332         fi
14333         do_facet mds1 $LCTL set_param fail_loc=0
14334         do_facet mds1 $LCTL set_param fail_val=0
14335         do_facet mds1 $LCTL set_param ldlm.lock_reclaim_threshold_mb=${low_wm}m
14336         wait $create_pid || return 1
14337
14338         unlinkmany $DIR/$tdir/f $nr
14339 }
14340 run_test 134b "Server rejects lock request when reaching lock_limit_mb"
14341
14342 test_135() {
14343         remote_mds_nodsh && skip "remote MDS with nodsh"
14344         [[ $MDS1_VERSION -lt $(version_code 2.13.50) ]] &&
14345                 skip "Need MDS version at least 2.13.50"
14346         local fname
14347
14348         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
14349
14350 #define OBD_FAIL_PLAIN_RECORDS 0x1319
14351         #set only one record at plain llog
14352         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x1319 fail_val=1
14353
14354         #fill already existed plain llog each 64767
14355         #wrapping whole catalog
14356         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 1))
14357
14358         createmany -o $DIR/$tdir/$tfile_ 64700
14359         for (( i = 0; i < 64700; i = i + 2 ))
14360         do
14361                 rm $DIR/$tdir/$tfile_$i &
14362                 rm $DIR/$tdir/$tfile_$((i + 1)) &
14363                 local pid=$!
14364                 wait $pid
14365         done
14366
14367         #waiting osp synchronization
14368         wait_delete_completed
14369 }
14370 run_test 135 "Race catalog processing"
14371
14372 test_136() {
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         $LFS setstripe -c 1 -i 0 $DIR/$tdir || error "failed to set striping"
14380         #set only one record at plain llog
14381 #define OBD_FAIL_CATALOG_FULL_CHECK                0x131a
14382         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x131a fail_val=1
14383
14384         #fill already existed 2 plain llogs each 64767
14385         #wrapping whole catalog
14386         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 1))
14387         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 3 / 2))
14388         wait_delete_completed
14389
14390         createmany -o $DIR/$tdir/$tfile_ 10
14391         sleep 25
14392
14393         do_facet $SINGLEMDS $LCTL set_param fail_val=3
14394         for (( i = 0; i < 10; i = i + 3 ))
14395         do
14396                 rm $DIR/$tdir/$tfile_$i &
14397                 rm $DIR/$tdir/$tfile_$((i + 1)) &
14398                 local pid=$!
14399                 wait $pid
14400                 sleep 7
14401                 rm $DIR/$tdir/$tfile_$((i + 2)) &
14402         done
14403
14404         #waiting osp synchronization
14405         wait_delete_completed
14406 }
14407 run_test 136 "Race catalog processing 2"
14408
14409 test_140() { #bug-17379
14410         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14411
14412         test_mkdir $DIR/$tdir
14413         cd $DIR/$tdir || error "Changing to $DIR/$tdir"
14414         cp $(which stat) . || error "Copying stat to $DIR/$tdir"
14415
14416         # VFS limits max symlink depth to 5(4KSTACK) or 7(8KSTACK) or 8
14417         # For kernel > 3.5, bellow only tests consecutive symlink (MAX 40)
14418         local i=0
14419         while i=$((i + 1)); do
14420                 test_mkdir $i
14421                 cd $i || error "Changing to $i"
14422                 ln -s ../stat stat || error "Creating stat symlink"
14423                 # Read the symlink until ELOOP present,
14424                 # not LBUGing the system is considered success,
14425                 # we didn't overrun the stack.
14426                 $OPENFILE -f O_RDONLY stat >/dev/null 2>&1; ret=$?
14427                 if [ $ret -ne 0 ]; then
14428                         if [ $ret -eq 40 ]; then
14429                                 break  # -ELOOP
14430                         else
14431                                 error "Open stat symlink"
14432                                         return
14433                         fi
14434                 fi
14435         done
14436         i=$((i - 1))
14437         echo "The symlink depth = $i"
14438         [ $i -eq 5 ] || [ $i -eq 7 ] || [ $i -eq 8 ] || [ $i -eq 40 ] ||
14439                 error "Invalid symlink depth"
14440
14441         # Test recursive symlink
14442         ln -s symlink_self symlink_self
14443         $OPENFILE -f O_RDONLY symlink_self >/dev/null 2>&1; ret=$?
14444         echo "open symlink_self returns $ret"
14445         [ $ret -eq 40 ] || error "recursive symlink doesn't return -ELOOP"
14446 }
14447 run_test 140 "Check reasonable stack depth (shouldn't LBUG) ===="
14448
14449 test_150a() {
14450         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14451
14452         local TF="$TMP/$tfile"
14453
14454         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
14455         dd if=/dev/urandom of=$TF bs=6096 count=1 || error "dd failed"
14456         cp $TF $DIR/$tfile
14457         cancel_lru_locks $OSC
14458         cmp $TF $DIR/$tfile || error "$TMP/$tfile $DIR/$tfile differ"
14459         remount_client $MOUNT
14460         df -P $MOUNT
14461         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (remount)"
14462
14463         $TRUNCATE $TF 6000
14464         $TRUNCATE $DIR/$tfile 6000
14465         cancel_lru_locks $OSC
14466         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (truncate1)"
14467
14468         echo "12345" >>$TF
14469         echo "12345" >>$DIR/$tfile
14470         cancel_lru_locks $OSC
14471         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (append1)"
14472
14473         echo "12345" >>$TF
14474         echo "12345" >>$DIR/$tfile
14475         cancel_lru_locks $OSC
14476         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (append2)"
14477 }
14478 run_test 150a "truncate/append tests"
14479
14480 test_150b() {
14481         check_set_fallocate_or_skip
14482
14483         touch $DIR/$tfile
14484         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
14485         check_fallocate $DIR/$tfile || error "fallocate failed"
14486 }
14487 run_test 150b "Verify fallocate (prealloc) functionality"
14488
14489 test_150bb() {
14490         check_set_fallocate_or_skip
14491
14492         touch $DIR/$tfile
14493         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
14494         dd if=/dev/urandom of=$DIR/$tfile bs=1M count=20 || error "dd failed"
14495         > $DIR/$tfile
14496         fallocate -l $((1048576 * 20)) $DIR/$tfile || error "fallocate failed"
14497         # precomputed md5sum for 20MB of zeroes
14498         local expect="8f4e33f3dc3e414ff94e5fb6905cba8c"
14499         local sum=($(md5sum $DIR/$tfile))
14500
14501         [[ "${sum[0]}" == "$expect" ]] || error "fallocate unwritten is not zero"
14502
14503         check_set_fallocate 1
14504
14505         > $DIR/$tfile
14506         fallocate -l $((1048576 * 20)) $DIR/$tfile || error "fallocate failed"
14507         sum=($(md5sum $DIR/$tfile))
14508
14509         [[ "${sum[0]}" == "$expect" ]] || error "fallocate zero is not zero"
14510 }
14511 run_test 150bb "Verify fallocate modes both zero space"
14512
14513 test_150c() {
14514         check_set_fallocate_or_skip
14515         local striping="-c2"
14516
14517         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
14518         $LFS setstripe -c $OSTCOUNT -S1M $DIR/$tfile || error "setstripe failed"
14519         fallocate -l ${OSTCOUNT}m $DIR/$tfile || error "fallocate failed"
14520         local bytes=$(($(stat -c '%b * %B' $DIR/$tfile)))
14521         local want=$((OSTCOUNT * 1048576))
14522
14523         # Must allocate all requested space, not more than 5% extra
14524         (( $bytes >= $want && $bytes < $want * 105 / 100 )) ||
14525                 error "bytes $bytes is not $want"
14526
14527         rm -f $DIR/$tfile
14528
14529         echo "verify fallocate on PFL file"
14530
14531         [[ "x$DOM" == "xyes" ]] && striping="-L mdt"
14532
14533         $LFS setstripe -E1M $striping -E16M -c3 -Eeof -c 4 $DIR/$tfile ||
14534                 error "Create $DIR/$tfile failed"
14535         fallocate -l $((1048576 * 512)) $DIR/$tfile ||
14536                         error "fallocate failed"
14537         bytes=$(($(stat -c '%b * %B' $DIR/$tfile)))
14538         want=$((512 * 1048576))
14539
14540         # Must allocate all requested space, not more than 5% extra
14541         (( $bytes >= $want && $bytes < $want * 105 / 100 )) ||
14542                 error "bytes $bytes is not $want"
14543 }
14544 run_test 150c "Verify fallocate Size and Blocks"
14545
14546 test_150d() {
14547         check_set_fallocate_or_skip
14548         local striping="-c2"
14549
14550         [[ "x$DOM" == "xyes" ]] && striping="-L mdt"
14551
14552         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
14553         $LFS setstripe -E1M $striping -E eof -c $OSTCOUNT -S1M $DIR/$tdir ||
14554                 error "setstripe failed"
14555         fallocate -o 1G -l ${OSTCOUNT}m $DIR/$tdir || error "fallocate failed"
14556         local bytes=$(($(stat -c '%b * %B' $DIR/$tdir)))
14557         local want=$((OSTCOUNT * 1048576))
14558
14559         # Must allocate all requested space, not more than 5% extra
14560         (( $bytes >= $want && $bytes < $want * 105 / 100 )) ||
14561                 error "bytes $bytes is not $want"
14562 }
14563 run_test 150d "Verify fallocate Size and Blocks - Non zero start"
14564
14565 test_150e() {
14566         check_set_fallocate_or_skip
14567
14568         echo "df before:"
14569         $LFS df
14570         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
14571         $LFS setstripe -c${OSTCOUNT} $DIR/$tfile ||
14572                 error "$LFS setstripe -c${OSTCOUNT} $DIR/$tfile failed"
14573
14574         # Find OST with Minimum Size
14575         min_size_ost=$($LFS df | awk "/$FSNAME-OST/ { print \$4 }" |
14576                        sort -un | head -1)
14577
14578         # Get 100MB per OST of the available space to reduce run time
14579         # else 60% of the available space if we are running SLOW tests
14580         if [ $SLOW == "no" ]; then
14581                 local space=$((1024 * 100 * OSTCOUNT))
14582         else
14583                 local space=$(((min_size_ost * 60)/100 * OSTCOUNT))
14584         fi
14585
14586         fallocate -l${space}k $DIR/$tfile ||
14587                 error "fallocate ${space}k $DIR/$tfile failed"
14588         echo "'fallocate -l ${space}k $DIR/$tfile' succeeded"
14589
14590         # get size immediately after fallocate. This should be correctly
14591         # updated
14592         local size=$(stat -c '%s' $DIR/$tfile)
14593         local used=$(( $(stat -c '%b * %B' $DIR/$tfile) / 1024))
14594
14595         # Sleep for a while for statfs to get updated. And not pull from cache.
14596         sleep 2
14597
14598         echo "df after fallocate:"
14599         $LFS df
14600
14601         (( size / 1024 == space )) || error "size $size != requested $space"
14602         [ "$ost1_FSTYPE" != ldiskfs ] || (( used >= space )) ||
14603                 error "used $used < space $space"
14604
14605         rm $DIR/$tfile || error "rm failed"
14606         sync
14607         wait_delete_completed
14608
14609         echo "df after unlink:"
14610         $LFS df
14611 }
14612 run_test 150e "Verify 60% of available OST space consumed by fallocate"
14613
14614 test_150f() {
14615         local size
14616         local blocks
14617         local want_size_before=20480 # in bytes
14618         local want_blocks_before=40 # 512 sized blocks
14619         local want_blocks_after=24  # 512 sized blocks
14620         local length=$(((want_blocks_before - want_blocks_after) * 512))
14621
14622         [[ $OST1_VERSION -ge $(version_code 2.14.0) ]] ||
14623                 skip "need at least 2.14.0 for fallocate punch"
14624
14625         if [ "$ost1_FSTYPE" = "zfs" ] || [ "$mds1_FSTYPE" = "zfs" ]; then
14626                 skip "LU-14160: punch mode is not implemented on OSD ZFS"
14627         fi
14628
14629         check_set_fallocate_or_skip
14630         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
14631
14632         [[ "x$DOM" == "xyes" ]] &&
14633                 $LFS setstripe -E1M -L mdt -E eof $DIR/$tfile
14634
14635         echo "Verify fallocate punch: Range within the file range"
14636         yes 'A' | dd of=$DIR/$tfile bs=4096 count=5 ||
14637                 error "dd failed for bs 4096 and count 5"
14638
14639         # Call fallocate with punch range which is within the file range
14640         fallocate -p --offset 4096 -l $length $DIR/$tfile ||
14641                 error "fallocate failed: offset 4096 and length $length"
14642         # client must see changes immediately after fallocate
14643         size=$(stat -c '%s' $DIR/$tfile)
14644         blocks=$(stat -c '%b' $DIR/$tfile)
14645
14646         # Verify punch worked.
14647         (( blocks == want_blocks_after )) ||
14648                 error "punch failed: blocks $blocks != $want_blocks_after"
14649
14650         (( size == want_size_before )) ||
14651                 error "punch failed: size $size != $want_size_before"
14652
14653         # Verify there is hole in file
14654         local data_off=$(lseek_test -d 4096 $DIR/$tfile)
14655         # precomputed md5sum
14656         local expect="4a9a834a2db02452929c0a348273b4aa"
14657
14658         cksum=($(md5sum $DIR/$tfile))
14659         [[ "${cksum[0]}" == "$expect" ]] ||
14660                 error "unexpected MD5SUM after punch: ${cksum[0]}"
14661
14662         # Start second sub-case for fallocate punch.
14663         echo "Verify fallocate punch: Range overlapping and less than blocksize"
14664         yes 'A' | dd of=$DIR/$tfile bs=4096 count=5 ||
14665                 error "dd failed for bs 4096 and count 5"
14666
14667         # Punch range less than block size will have no change in block count
14668         want_blocks_after=40  # 512 sized blocks
14669
14670         # Punch overlaps two blocks and less than blocksize
14671         fallocate -p --offset 4000 -l 3000 $DIR/$tfile ||
14672                 error "fallocate failed: offset 4000 length 3000"
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 if range is really zero'ed out. We expect Zeros.
14684         # precomputed md5sum
14685         expect="c57ec5d769c3dbe3426edc3f7d7e11d3"
14686         cksum=($(md5sum $DIR/$tfile))
14687         [[ "${cksum[0]}" == "$expect" ]] ||
14688                 error "unexpected MD5SUM after punch: ${cksum[0]}"
14689 }
14690 run_test 150f "Verify fallocate punch functionality"
14691
14692 test_150g() {
14693         local space
14694         local size
14695         local blocks
14696         local blocks_after
14697         local size_after
14698         local BS=4096 # Block size in bytes
14699
14700         [[ $OST1_VERSION -ge $(version_code 2.14.0) ]] ||
14701                 skip "need at least 2.14.0 for fallocate punch"
14702
14703         if [ "$ost1_FSTYPE" = "zfs" ] || [ "$mds1_FSTYPE" = "zfs" ]; then
14704                 skip "LU-14160: punch mode is not implemented on OSD ZFS"
14705         fi
14706
14707         check_set_fallocate_or_skip
14708         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
14709
14710         if [[ "x$DOM" == "xyes" ]]; then
14711                 $LFS setstripe -E2M -L mdt -E eof -c${OSTCOUNT} $DIR/$tfile ||
14712                         error "$LFS setstripe DoM + ${OSTCOUNT} OST failed"
14713         else
14714                 $LFS setstripe -c${OSTCOUNT} $DIR/$tfile ||
14715                         error "$LFS setstripe -c${OSTCOUNT} $DIR/$tfile failed"
14716         fi
14717
14718         # Get 100MB per OST of the available space to reduce run time
14719         # else 60% of the available space if we are running SLOW tests
14720         if [ $SLOW == "no" ]; then
14721                 space=$((1024 * 100 * OSTCOUNT))
14722         else
14723                 # Find OST with Minimum Size
14724                 space=$($LFS df | awk "/$FSNAME-OST/ { print \$4 }" |
14725                         sort -un | head -1)
14726                 echo "min size OST: $space"
14727                 space=$(((space * 60)/100 * OSTCOUNT))
14728         fi
14729         # space in 1k units, round to 4k blocks
14730         local blkcount=$((space * 1024 / $BS))
14731
14732         echo "Verify fallocate punch: Very large Range"
14733         fallocate -l${space}k $DIR/$tfile ||
14734                 error "fallocate ${space}k $DIR/$tfile failed"
14735         # write 1M at the end, start and in the middle
14736         yes 'A' | dd of=$DIR/$tfile bs=$BS count=256 ||
14737                 error "dd failed: bs $BS count 256"
14738         yes 'A' | dd of=$DIR/$tfile bs=$BS seek=$((blkcount - 256)) count=256 ||
14739                 error "dd failed: bs $BS count 256 seek $((blkcount - 256))"
14740         yes 'A' | dd of=$DIR/$tfile bs=$BS seek=$((blkcount / 2)) count=1024 ||
14741                 error "dd failed: bs $BS count 256 seek $((blkcount / 2))"
14742
14743         # Gather stats.
14744         size=$(stat -c '%s' $DIR/$tfile)
14745
14746         # gather punch length.
14747         local punch_size=$((size - (BS * 2)))
14748
14749         echo "punch_size = $punch_size"
14750         echo "size - punch_size: $((size - punch_size))"
14751         echo "size - punch_size in blocks: $(((size - punch_size)/BS))"
14752
14753         # Call fallocate to punch all except 2 blocks. We leave the
14754         # first and the last block
14755         echo "fallocate -p --offset $BS -l $punch_size $DIR/$tfile"
14756         fallocate -p --offset $BS -l $punch_size $DIR/$tfile ||
14757                 error "fallocate failed: offset $BS length $punch_size"
14758
14759         size_after=$(stat -c '%s' $DIR/$tfile)
14760         blocks_after=$(stat -c '%b' $DIR/$tfile)
14761
14762         # Verify punch worked.
14763         # Size should be kept
14764         (( size == size_after )) ||
14765                 error "punch failed: size $size != $size_after"
14766
14767         # two 4k data blocks to remain plus possible 1 extra extent block
14768         (( blocks_after <= ((BS / 512) * 3) )) ||
14769                 error "too many blocks remains: $blocks_after"
14770
14771         # Verify that file has hole between the first and the last blocks
14772         local hole_start=$(lseek_test -l 0 $DIR/$tfile)
14773         local hole_end=$(lseek_test -d $BS $DIR/$tfile)
14774
14775         echo "Hole at [$hole_start, $hole_end)"
14776         (( hole_start == BS )) ||
14777                 error "no hole at offset $BS after punch"
14778
14779         (( hole_end == BS + punch_size )) ||
14780                 error "data at offset $hole_end < $((BS + punch_size))"
14781 }
14782 run_test 150g "Verify fallocate punch on large range"
14783
14784 #LU-2902 roc_hit was not able to read all values from lproc
14785 function roc_hit_init() {
14786         local list=$(comma_list $(osts_nodes))
14787         local dir=$DIR/$tdir-check
14788         local file=$dir/$tfile
14789         local BEFORE
14790         local AFTER
14791         local idx
14792
14793         test_mkdir $dir
14794         #use setstripe to do a write to every ost
14795         for i in $(seq 0 $((OSTCOUNT-1))); do
14796                 $LFS setstripe -c 1 -i $i $dir || error "$LFS setstripe $file failed"
14797                 dd if=/dev/urandom of=$file bs=4k count=4 2>&1 > /dev/null
14798                 idx=$(printf %04x $i)
14799                 BEFORE=$(get_osd_param $list *OST*$idx stats |
14800                         awk '$1 == "cache_access" {sum += $7}
14801                                 END { printf("%0.0f", sum) }')
14802
14803                 cancel_lru_locks osc
14804                 cat $file >/dev/null
14805
14806                 AFTER=$(get_osd_param $list *OST*$idx stats |
14807                         awk '$1 == "cache_access" {sum += $7}
14808                                 END { printf("%0.0f", sum) }')
14809
14810                 echo BEFORE:$BEFORE AFTER:$AFTER
14811                 if ! let "AFTER - BEFORE == 4"; then
14812                         rm -rf $dir
14813                         error "roc_hit is not safe to use"
14814                 fi
14815                 rm $file
14816         done
14817
14818         rm -rf $dir
14819 }
14820
14821 function roc_hit() {
14822         local list=$(comma_list $(osts_nodes))
14823         echo $(get_osd_param $list '' stats |
14824                 awk '$1 == "cache_hit" {sum += $7}
14825                         END { printf("%0.0f", sum) }')
14826 }
14827
14828 function set_cache() {
14829         local on=1
14830
14831         if [ "$2" == "off" ]; then
14832                 on=0;
14833         fi
14834         local list=$(comma_list $(osts_nodes))
14835         set_osd_param $list '' $1_cache_enable $on
14836
14837         cancel_lru_locks osc
14838 }
14839
14840 test_151() {
14841         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14842         remote_ost_nodsh && skip "remote OST with nodsh"
14843
14844         local CPAGES=3
14845         local list=$(comma_list $(osts_nodes))
14846
14847         # check whether obdfilter is cache capable at all
14848         if ! get_osd_param $list '' read_cache_enable >/dev/null; then
14849                 skip "not cache-capable obdfilter"
14850         fi
14851
14852         # check cache is enabled on all obdfilters
14853         if get_osd_param $list '' read_cache_enable | grep 0; then
14854                 skip "oss cache is disabled"
14855         fi
14856
14857         set_osd_param $list '' writethrough_cache_enable 1
14858
14859         # check write cache is enabled on all obdfilters
14860         if get_osd_param $list '' writethrough_cache_enable | grep 0; then
14861                 skip "oss write cache is NOT enabled"
14862         fi
14863
14864         roc_hit_init
14865
14866         #define OBD_FAIL_OBD_NO_LRU  0x609
14867         do_nodes $list $LCTL set_param fail_loc=0x609
14868
14869         # pages should be in the case right after write
14870         dd if=/dev/urandom of=$DIR/$tfile bs=4k count=$CPAGES ||
14871                 error "dd failed"
14872
14873         local BEFORE=$(roc_hit)
14874         cancel_lru_locks osc
14875         cat $DIR/$tfile >/dev/null
14876         local AFTER=$(roc_hit)
14877
14878         do_nodes $list $LCTL set_param fail_loc=0
14879
14880         if ! let "AFTER - BEFORE == CPAGES"; then
14881                 error "NOT IN CACHE: before: $BEFORE, after: $AFTER"
14882         fi
14883
14884         cancel_lru_locks osc
14885         # invalidates OST cache
14886         do_nodes $list "echo 1 > /proc/sys/vm/drop_caches"
14887         set_osd_param $list '' read_cache_enable 0
14888         cat $DIR/$tfile >/dev/null
14889
14890         # now data shouldn't be found in the cache
14891         BEFORE=$(roc_hit)
14892         cancel_lru_locks osc
14893         cat $DIR/$tfile >/dev/null
14894         AFTER=$(roc_hit)
14895         if let "AFTER - BEFORE != 0"; then
14896                 error "IN CACHE: before: $BEFORE, after: $AFTER"
14897         fi
14898
14899         set_osd_param $list '' read_cache_enable 1
14900         rm -f $DIR/$tfile
14901 }
14902 run_test 151 "test cache on oss and controls ==============================="
14903
14904 test_152() {
14905         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14906
14907         local TF="$TMP/$tfile"
14908
14909         # simulate ENOMEM during write
14910 #define OBD_FAIL_OST_NOMEM      0x226
14911         lctl set_param fail_loc=0x80000226
14912         dd if=/dev/urandom of=$TF bs=6096 count=1 || error "dd failed"
14913         cp $TF $DIR/$tfile
14914         sync || error "sync failed"
14915         lctl set_param fail_loc=0
14916
14917         # discard client's cache
14918         cancel_lru_locks osc
14919
14920         # simulate ENOMEM during read
14921         lctl set_param fail_loc=0x80000226
14922         cmp $TF $DIR/$tfile || error "cmp failed"
14923         lctl set_param fail_loc=0
14924
14925         rm -f $TF
14926 }
14927 run_test 152 "test read/write with enomem ============================"
14928
14929 test_153() {
14930         $MULTIOP $DIR/$tfile Ow4096Ycu || error "multiop failed"
14931 }
14932 run_test 153 "test if fdatasync does not crash ======================="
14933
14934 dot_lustre_fid_permission_check() {
14935         local fid=$1
14936         local ffid=$MOUNT/.lustre/fid/$fid
14937         local test_dir=$2
14938
14939         echo "stat fid $fid"
14940         stat $ffid > /dev/null || error "stat $ffid failed."
14941         echo "touch fid $fid"
14942         touch $ffid || error "touch $ffid failed."
14943         echo "write to fid $fid"
14944         cat /etc/hosts > $ffid || error "write $ffid failed."
14945         echo "read fid $fid"
14946         diff /etc/hosts $ffid || error "read $ffid failed."
14947         echo "append write to fid $fid"
14948         cat /etc/hosts >> $ffid || error "append write $ffid failed."
14949         echo "rename fid $fid"
14950         mv $ffid $test_dir/$tfile.1 &&
14951                 error "rename $ffid to $tfile.1 should fail."
14952         touch $test_dir/$tfile.1
14953         mv $test_dir/$tfile.1 $ffid &&
14954                 error "rename $tfile.1 to $ffid should fail."
14955         rm -f $test_dir/$tfile.1
14956         echo "truncate fid $fid"
14957         $TRUNCATE $ffid 777 || error "truncate $ffid failed."
14958         echo "link fid $fid"
14959         ln -f $ffid $test_dir/tfile.lnk || error "link $ffid failed."
14960         if [[ $($LCTL get_param -n mdc.*-mdc-*.connect_flags) =~ acl ]]; then
14961                 echo "setfacl fid $fid"
14962                 setfacl -R -m u:bin:rwx $ffid || error "setfacl $ffid failed."
14963                 echo "getfacl fid $fid"
14964                 getfacl $ffid >/dev/null || error "getfacl $ffid failed."
14965         fi
14966         echo "unlink fid $fid"
14967         unlink $MOUNT/.lustre/fid/$fid && error "unlink $ffid should fail."
14968         echo "mknod fid $fid"
14969         mknod $ffid c 1 3 && error "mknod $ffid should fail."
14970
14971         fid=[0xf00000400:0x1:0x0]
14972         ffid=$MOUNT/.lustre/fid/$fid
14973
14974         echo "stat non-exist fid $fid"
14975         stat $ffid > /dev/null && error "stat non-exist $ffid should fail."
14976         echo "write to non-exist fid $fid"
14977         cat /etc/hosts > $ffid && error "write non-exist $ffid should fail."
14978         echo "link new fid $fid"
14979         ln $test_dir/$tfile $ffid && error "link $ffid should fail."
14980
14981         mkdir -p $test_dir/$tdir
14982         touch $test_dir/$tdir/$tfile
14983         fid=$($LFS path2fid $test_dir/$tdir)
14984         rc=$?
14985         [ $rc -ne 0 ] &&
14986                 error "error: could not get fid for $test_dir/$dir/$tfile."
14987
14988         ffid=$MOUNT/.lustre/fid/$fid
14989
14990         echo "ls $fid"
14991         ls $ffid > /dev/null || error "ls $ffid failed."
14992         echo "touch $fid/$tfile.1"
14993         touch $ffid/$tfile.1 || error "touch $ffid/$tfile.1 failed."
14994
14995         echo "touch $MOUNT/.lustre/fid/$tfile"
14996         touch $MOUNT/.lustre/fid/$tfile && \
14997                 error "touch $MOUNT/.lustre/fid/$tfile should fail."
14998
14999         echo "setxattr to $MOUNT/.lustre/fid"
15000         setfattr -n trusted.name1 -v value1 $MOUNT/.lustre/fid
15001
15002         echo "listxattr for $MOUNT/.lustre/fid"
15003         getfattr -d -m "^trusted" $MOUNT/.lustre/fid
15004
15005         echo "delxattr from $MOUNT/.lustre/fid"
15006         setfattr -x trusted.name1 $MOUNT/.lustre/fid
15007
15008         echo "touch invalid fid: $MOUNT/.lustre/fid/[0x200000400:0x2:0x3]"
15009         touch $MOUNT/.lustre/fid/[0x200000400:0x2:0x3] &&
15010                 error "touch invalid fid should fail."
15011
15012         echo "touch non-normal fid: $MOUNT/.lustre/fid/[0x1:0x2:0x0]"
15013         touch $MOUNT/.lustre/fid/[0x1:0x2:0x0] &&
15014                 error "touch non-normal fid should fail."
15015
15016         echo "rename $tdir to $MOUNT/.lustre/fid"
15017         mrename $test_dir/$tdir $MOUNT/.lustre/fid &&
15018                 error "rename to $MOUNT/.lustre/fid should fail."
15019
15020         if [ $MDS1_VERSION -ge $(version_code 2.3.51) ]
15021         then            # LU-3547
15022                 local old_obf_mode=$(stat --format="%a" $DIR/.lustre/fid)
15023                 local new_obf_mode=777
15024
15025                 echo "change mode of $DIR/.lustre/fid to $new_obf_mode"
15026                 chmod $new_obf_mode $DIR/.lustre/fid ||
15027                         error "chmod $new_obf_mode $DIR/.lustre/fid failed"
15028
15029                 local obf_mode=$(stat --format=%a $DIR/.lustre/fid)
15030                 [ $obf_mode -eq $new_obf_mode ] ||
15031                         error "stat $DIR/.lustre/fid returned wrong mode $obf_mode"
15032
15033                 echo "restore mode of $DIR/.lustre/fid to $old_obf_mode"
15034                 chmod $old_obf_mode $DIR/.lustre/fid ||
15035                         error "chmod $old_obf_mode $DIR/.lustre/fid failed"
15036         fi
15037
15038         $OPENFILE -f O_LOV_DELAY_CREATE:O_CREAT $test_dir/$tfile-2
15039         fid=$($LFS path2fid $test_dir/$tfile-2)
15040
15041         if [ $MDS1_VERSION -ge $(version_code 2.6.50) ]
15042         then # LU-5424
15043                 echo "cp /etc/passwd $MOUNT/.lustre/fid/$fid"
15044                 cp /etc/passwd $MOUNT/.lustre/fid/$fid ||
15045                         error "create lov data thru .lustre failed"
15046         fi
15047         echo "cp /etc/passwd $test_dir/$tfile-2"
15048         cp /etc/passwd $test_dir/$tfile-2 ||
15049                 error "copy to $test_dir/$tfile-2 failed."
15050         echo "diff /etc/passwd $MOUNT/.lustre/fid/$fid"
15051         diff /etc/passwd $MOUNT/.lustre/fid/$fid ||
15052                 error "diff /etc/passwd $MOUNT/.lustre/fid/$fid failed."
15053
15054         rm -rf $test_dir/tfile.lnk
15055         rm -rf $test_dir/$tfile-2
15056 }
15057
15058 test_154A() {
15059         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
15060                 skip "Need MDS version at least 2.4.1"
15061
15062         local tf=$DIR/$tfile
15063         touch $tf
15064
15065         local fid=$($LFS path2fid $tf)
15066         [ -z "$fid" ] && error "path2fid unable to get $tf FID"
15067
15068         # check that we get the same pathname back
15069         local rootpath
15070         local found
15071         for rootpath in "$MOUNT" "$MOUNT///" "$MOUNT/$tfile"; do
15072                 echo "$rootpath $fid"
15073                 found=$($LFS fid2path $rootpath "$fid")
15074                 [ -z "$found" ] && error "fid2path unable to get '$fid' path"
15075                 [ "$found" == "$tf" ] || error "fid2path $found != $tf"
15076         done
15077
15078         # check wrong root path format
15079         rootpath=$MOUNT"_wrong"
15080         found=$($LFS fid2path $rootpath "$fid")
15081         [ -z "$found" ] || error "should fail ($rootpath != $MOUNT)"
15082 }
15083 run_test 154A "lfs path2fid and fid2path basic checks"
15084
15085 test_154B() {
15086         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
15087                 skip "Need MDS version at least 2.4.1"
15088
15089         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
15090         touch $DIR/$tdir/$tfile || error "touch $DIR/$tdir/$tfile failed"
15091         local linkea=$($LL_DECODE_LINKEA $DIR/$tdir/$tfile | grep 'pfid')
15092         [ -z "$linkea" ] && error "decode linkea $DIR/$tdir/$tfile failed"
15093
15094         local name=$(echo $linkea | awk '/pfid/ {print $5}' | sed -e "s/'//g")
15095         local PFID=$(echo $linkea | awk '/pfid/ {print $3}' | sed -e "s/,//g")
15096
15097         # check that we get the same pathname
15098         echo "PFID: $PFID, name: $name"
15099         local FOUND=$($LFS fid2path $MOUNT "$PFID")
15100         [ -z "$FOUND" ] && error "fid2path unable to get $PFID path"
15101         [ "$FOUND/$name" != "$DIR/$tdir/$tfile" ] &&
15102                 error "ll_decode_linkea has $FOUND/$name != $DIR/$tdir/$tfile"
15103
15104         rm -rf $DIR/$tdir || error "Can not delete directory $DIR/$tdir"
15105 }
15106 run_test 154B "verify the ll_decode_linkea tool"
15107
15108 test_154a() {
15109         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15110         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
15111         [[ $MDS1_VERSION -ge $(version_code 2.2.51) ]] ||
15112                 skip "Need MDS version at least 2.2.51"
15113         [ -z "$(which setfacl)" ] && skip_env "must have setfacl tool"
15114
15115         cp /etc/hosts $DIR/$tfile
15116
15117         fid=$($LFS path2fid $DIR/$tfile)
15118         rc=$?
15119         [ $rc -ne 0 ] && error "error: could not get fid for $DIR/$tfile."
15120
15121         dot_lustre_fid_permission_check "$fid" $DIR ||
15122                 error "dot lustre permission check $fid failed"
15123
15124         ls -a $MOUNT | grep "\.lustre" && error ".lustre should not be listed"
15125
15126         rm -rf $MOUNT/.lustre && error ".lustre is not allowed to be unlinked"
15127
15128         touch $MOUNT/.lustre/file &&
15129                 error "creation is not allowed under .lustre"
15130
15131         mkdir $MOUNT/.lustre/dir &&
15132                 error "mkdir is not allowed under .lustre"
15133
15134         rm -rf $DIR/$tfile
15135 }
15136 run_test 154a "Open-by-FID"
15137
15138 test_154b() {
15139         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15140         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
15141         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
15142         [[ $MDS1_VERSION -ge $(version_code 2.2.51) ]] ||
15143                 skip "Need MDS version at least 2.2.51"
15144
15145         local remote_dir=$DIR/$tdir/remote_dir
15146         local MDTIDX=1
15147         local rc=0
15148
15149         mkdir -p $DIR/$tdir
15150         $LFS mkdir -i $MDTIDX $remote_dir ||
15151                 error "create remote directory failed"
15152
15153         cp /etc/hosts $remote_dir/$tfile
15154
15155         fid=$($LFS path2fid $remote_dir/$tfile)
15156         rc=$?
15157         [ $rc -ne 0 ] && error "error: could not get fid for $remote_dir/$tfile"
15158
15159         dot_lustre_fid_permission_check "$fid" $remote_dir ||
15160                 error "dot lustre permission check $fid failed"
15161         rm -rf $DIR/$tdir
15162 }
15163 run_test 154b "Open-by-FID for remote directory"
15164
15165 test_154c() {
15166         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
15167                 skip "Need MDS version at least 2.4.1"
15168
15169         touch $DIR/$tfile.1 $DIR/$tfile.2 $DIR/$tfile.3
15170         local FID1=$($LFS path2fid $DIR/$tfile.1)
15171         local FID2=$($LFS path2fid $DIR/$tfile.2)
15172         local FID3=$($LFS path2fid $DIR/$tfile.3)
15173
15174         local N=1
15175         $LFS path2fid $DIR/$tfile.[123] | while read PATHNAME FID; do
15176                 [ "$PATHNAME" = "$DIR/$tfile.$N:" ] ||
15177                         error "path2fid pathname $PATHNAME != $DIR/$tfile.$N:"
15178                 local want=FID$N
15179                 [ "$FID" = "${!want}" ] ||
15180                         error "path2fid $PATHNAME FID $FID != FID$N ${!want}"
15181                 N=$((N + 1))
15182         done
15183
15184         $LFS fid2path $MOUNT "$FID1" "$FID2" "$FID3" | while read PATHNAME;
15185         do
15186                 [ "$PATHNAME" = "$DIR/$tfile.$N" ] ||
15187                         error "fid2path pathname $PATHNAME != $DIR/$tfile.$N:"
15188                 N=$((N + 1))
15189         done
15190 }
15191 run_test 154c "lfs path2fid and fid2path multiple arguments"
15192
15193 test_154d() {
15194         remote_mds_nodsh && skip "remote MDS with nodsh"
15195         [[ $MDS1_VERSION -lt $(version_code 2.5.53) ]] &&
15196                 skip "Need MDS version at least 2.5.53"
15197
15198         if remote_mds; then
15199                 nid=$($LCTL list_nids | sed  "s/\./\\\./g")
15200         else
15201                 nid="0@lo"
15202         fi
15203         local proc_ofile="mdt.*.exports.'$nid'.open_files"
15204         local fd
15205         local cmd
15206
15207         rm -f $DIR/$tfile
15208         touch $DIR/$tfile
15209
15210         local fid=$($LFS path2fid $DIR/$tfile)
15211         # Open the file
15212         fd=$(free_fd)
15213         cmd="exec $fd<$DIR/$tfile"
15214         eval $cmd
15215         local fid_list=$(do_facet $SINGLEMDS $LCTL get_param $proc_ofile)
15216         echo "$fid_list" | grep "$fid"
15217         rc=$?
15218
15219         cmd="exec $fd>/dev/null"
15220         eval $cmd
15221         if [ $rc -ne 0 ]; then
15222                 error "FID $fid not found in open files list $fid_list"
15223         fi
15224 }
15225 run_test 154d "Verify open file fid"
15226
15227 test_154e()
15228 {
15229         [[ $MDS1_VERSION -lt $(version_code 2.6.50) ]] &&
15230                 skip "Need MDS version at least 2.6.50"
15231
15232         if ls -a $MOUNT | grep -q '^\.lustre$'; then
15233                 error ".lustre returned by readdir"
15234         fi
15235 }
15236 run_test 154e ".lustre is not returned by readdir"
15237
15238 test_154f() {
15239         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
15240
15241         # create parent directory on a single MDT to avoid cross-MDT hardlinks
15242         mkdir_on_mdt0 $DIR/$tdir
15243         # test dirs inherit from its stripe
15244         mkdir -p $DIR/$tdir/foo1 || error "mkdir error"
15245         mkdir -p $DIR/$tdir/foo2 || error "mkdir error"
15246         cp /etc/hosts $DIR/$tdir/foo1/$tfile
15247         ln $DIR/$tdir/foo1/$tfile $DIR/$tdir/foo2/link
15248         touch $DIR/f
15249
15250         # get fid of parents
15251         local FID0=$($LFS path2fid $DIR/$tdir)
15252         local FID1=$($LFS path2fid $DIR/$tdir/foo1)
15253         local FID2=$($LFS path2fid $DIR/$tdir/foo2)
15254         local FID3=$($LFS path2fid $DIR)
15255
15256         # check that path2fid --parents returns expected <parent_fid>/name
15257         # 1) test for a directory (single parent)
15258         local parent=$($LFS path2fid --parents $DIR/$tdir/foo1)
15259         [ "$parent" == "$FID0/foo1" ] ||
15260                 error "expected parent: $FID0/foo1, got: $parent"
15261
15262         # 2) test for a file with nlink > 1 (multiple parents)
15263         parent=$($LFS path2fid --parents $DIR/$tdir/foo1/$tfile)
15264         echo "$parent" | grep -F "$FID1/$tfile" ||
15265                 error "$FID1/$tfile not returned in parent list"
15266         echo "$parent" | grep -F "$FID2/link" ||
15267                 error "$FID2/link not returned in parent list"
15268
15269         # 3) get parent by fid
15270         local file_fid=$($LFS path2fid $DIR/$tdir/foo1/$tfile)
15271         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
15272         echo "$parent" | grep -F "$FID1/$tfile" ||
15273                 error "$FID1/$tfile not returned in parent list (by fid)"
15274         echo "$parent" | grep -F "$FID2/link" ||
15275                 error "$FID2/link not returned in parent list (by fid)"
15276
15277         # 4) test for entry in root directory
15278         parent=$($LFS path2fid --parents $DIR/f)
15279         echo "$parent" | grep -F "$FID3/f" ||
15280                 error "$FID3/f not returned in parent list"
15281
15282         # 5) test it on root directory
15283         [ -z "$($LFS path2fid --parents $MOUNT 2>/dev/null)" ] ||
15284                 error "$MOUNT should not have parents"
15285
15286         # enable xattr caching and check that linkea is correctly updated
15287         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
15288         save_lustre_params client "llite.*.xattr_cache" > $save
15289         lctl set_param llite.*.xattr_cache 1
15290
15291         # 6.1) linkea update on rename
15292         mv $DIR/$tdir/foo1/$tfile $DIR/$tdir/foo2/$tfile.moved
15293
15294         # get parents by fid
15295         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
15296         # foo1 should no longer be returned in parent list
15297         echo "$parent" | grep -F "$FID1" &&
15298                 error "$FID1 should no longer be in parent list"
15299         # the new path should appear
15300         echo "$parent" | grep -F "$FID2/$tfile.moved" ||
15301                 error "$FID2/$tfile.moved is not in parent list"
15302
15303         # 6.2) linkea update on unlink
15304         rm -f $DIR/$tdir/foo2/link
15305         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
15306         # foo2/link should no longer be returned in parent list
15307         echo "$parent" | grep -F "$FID2/link" &&
15308                 error "$FID2/link should no longer be in parent list"
15309         true
15310
15311         rm -f $DIR/f
15312         restore_lustre_params < $save
15313         rm -f $save
15314 }
15315 run_test 154f "get parent fids by reading link ea"
15316
15317 test_154g()
15318 {
15319         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
15320         [[ $MDS1_VERSION -ge $(version_code 2.6.92) &&
15321            $CLIENT_VERSION -gt $(version_code 2.6.99) ]] ||
15322                 skip "Need MDS version at least 2.6.92"
15323
15324         mkdir_on_mdt0 $DIR/$tdir
15325         llapi_fid_test -d $DIR/$tdir
15326 }
15327 run_test 154g "various llapi FID tests"
15328
15329 test_155_small_load() {
15330     local temp=$TMP/$tfile
15331     local file=$DIR/$tfile
15332
15333     dd if=/dev/urandom of=$temp bs=6096 count=1 || \
15334         error "dd of=$temp bs=6096 count=1 failed"
15335     cp $temp $file
15336     cancel_lru_locks $OSC
15337     cmp $temp $file || error "$temp $file differ"
15338
15339     $TRUNCATE $temp 6000
15340     $TRUNCATE $file 6000
15341     cmp $temp $file || error "$temp $file differ (truncate1)"
15342
15343     echo "12345" >>$temp
15344     echo "12345" >>$file
15345     cmp $temp $file || error "$temp $file differ (append1)"
15346
15347     echo "12345" >>$temp
15348     echo "12345" >>$file
15349     cmp $temp $file || error "$temp $file differ (append2)"
15350
15351     rm -f $temp $file
15352     true
15353 }
15354
15355 test_155_big_load() {
15356         remote_ost_nodsh && skip "remote OST with nodsh"
15357
15358         local temp=$TMP/$tfile
15359         local file=$DIR/$tfile
15360
15361         free_min_max
15362         local cache_size=$(do_facet ost$((MAXI+1)) \
15363                 "awk '/cache/ {sum+=\\\$4} END {print sum}' /proc/cpuinfo")
15364         local large_file_size=$((cache_size * 2))
15365
15366         echo "OSS cache size: $cache_size KB"
15367         echo "Large file size: $large_file_size KB"
15368
15369         [ $MAXV -le $large_file_size ] &&
15370                 skip_env "max available OST size needs > $large_file_size KB"
15371
15372         $LFS setstripe $file -c 1 -i $MAXI || error "$LFS setstripe $file failed"
15373
15374         dd if=/dev/urandom of=$temp bs=$large_file_size count=1k ||
15375                 error "dd of=$temp bs=$large_file_size count=1k failed"
15376         cp $temp $file
15377         ls -lh $temp $file
15378         cancel_lru_locks osc
15379         cmp $temp $file || error "$temp $file differ"
15380
15381         rm -f $temp $file
15382         true
15383 }
15384
15385 save_writethrough() {
15386         local facets=$(get_facets OST)
15387
15388         save_lustre_params $facets "osd-*.*.writethrough_cache_enable" > $1
15389 }
15390
15391 test_155a() {
15392         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15393
15394         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15395
15396         save_writethrough $p
15397
15398         set_cache read on
15399         set_cache writethrough on
15400         test_155_small_load
15401         restore_lustre_params < $p
15402         rm -f $p
15403 }
15404 run_test 155a "Verify small file correctness: read cache:on write_cache:on"
15405
15406 test_155b() {
15407         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15408
15409         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15410
15411         save_writethrough $p
15412
15413         set_cache read on
15414         set_cache writethrough off
15415         test_155_small_load
15416         restore_lustre_params < $p
15417         rm -f $p
15418 }
15419 run_test 155b "Verify small file correctness: read cache:on write_cache:off"
15420
15421 test_155c() {
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 off
15429         set_cache writethrough on
15430         test_155_small_load
15431         restore_lustre_params < $p
15432         rm -f $p
15433 }
15434 run_test 155c "Verify small file correctness: read cache:off write_cache:on"
15435
15436 test_155d() {
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 off
15444         set_cache writethrough off
15445         test_155_small_load
15446         restore_lustre_params < $p
15447         rm -f $p
15448 }
15449 run_test 155d "Verify small file correctness: read cache:off write_cache:off"
15450
15451 test_155e() {
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 on
15459         set_cache writethrough on
15460         test_155_big_load
15461         restore_lustre_params < $p
15462         rm -f $p
15463 }
15464 run_test 155e "Verify big file correctness: read cache:on write_cache:on"
15465
15466 test_155f() {
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 on
15474         set_cache writethrough off
15475         test_155_big_load
15476         restore_lustre_params < $p
15477         rm -f $p
15478 }
15479 run_test 155f "Verify big file correctness: read cache:on write_cache:off"
15480
15481 test_155g() {
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 off
15489         set_cache writethrough on
15490         test_155_big_load
15491         restore_lustre_params < $p
15492         rm -f $p
15493 }
15494 run_test 155g "Verify big file correctness: read cache:off write_cache:on"
15495
15496 test_155h() {
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 off
15504         set_cache writethrough off
15505         test_155_big_load
15506         restore_lustre_params < $p
15507         rm -f $p
15508 }
15509 run_test 155h "Verify big file correctness: read cache:off write_cache:off"
15510
15511 test_156() {
15512         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15513         remote_ost_nodsh && skip "remote OST with nodsh"
15514         [ $OST1_VERSION -lt $(version_code 2.6.93) ] &&
15515                 skip "stats not implemented on old servers"
15516         [ "$ost1_FSTYPE" = "zfs" ] &&
15517                 skip "LU-1956/LU-2261: stats not implemented on OSD ZFS"
15518
15519         local CPAGES=3
15520         local BEFORE
15521         local AFTER
15522         local file="$DIR/$tfile"
15523         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15524
15525         save_writethrough $p
15526         roc_hit_init
15527
15528         log "Turn on read and write cache"
15529         set_cache read on
15530         set_cache writethrough on
15531
15532         log "Write data and read it back."
15533         log "Read should be satisfied from the cache."
15534         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
15535         BEFORE=$(roc_hit)
15536         cancel_lru_locks osc
15537         cat $file >/dev/null
15538         AFTER=$(roc_hit)
15539         if ! let "AFTER - BEFORE == CPAGES"; then
15540                 error "NOT IN CACHE (2): before: $BEFORE, after: $AFTER"
15541         else
15542                 log "cache hits: before: $BEFORE, after: $AFTER"
15543         fi
15544
15545         log "Read again; it should be satisfied from the cache."
15546         BEFORE=$AFTER
15547         cancel_lru_locks osc
15548         cat $file >/dev/null
15549         AFTER=$(roc_hit)
15550         if ! let "AFTER - BEFORE == CPAGES"; then
15551                 error "NOT IN CACHE (3): before: $BEFORE, after: $AFTER"
15552         else
15553                 log "cache hits:: before: $BEFORE, after: $AFTER"
15554         fi
15555
15556         log "Turn off the read cache and turn on the write cache"
15557         set_cache read off
15558         set_cache writethrough on
15559
15560         log "Read again; it should be satisfied from the cache."
15561         BEFORE=$(roc_hit)
15562         cancel_lru_locks osc
15563         cat $file >/dev/null
15564         AFTER=$(roc_hit)
15565         if ! let "AFTER - BEFORE == CPAGES"; then
15566                 error "NOT IN CACHE (4): before: $BEFORE, after: $AFTER"
15567         else
15568                 log "cache hits:: before: $BEFORE, after: $AFTER"
15569         fi
15570
15571         if [ $OST1_VERSION -lt $(version_code 2.12.55) ]; then
15572                 # > 2.12.56 uses pagecache if cached
15573                 log "Read again; it should not be satisfied from the cache."
15574                 BEFORE=$AFTER
15575                 cancel_lru_locks osc
15576                 cat $file >/dev/null
15577                 AFTER=$(roc_hit)
15578                 if ! let "AFTER - BEFORE == 0"; then
15579                         error "IN CACHE (5): before: $BEFORE, after: $AFTER"
15580                 else
15581                         log "cache hits:: before: $BEFORE, after: $AFTER"
15582                 fi
15583         fi
15584
15585         log "Write data and read it back."
15586         log "Read should be satisfied from the cache."
15587         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
15588         BEFORE=$(roc_hit)
15589         cancel_lru_locks osc
15590         cat $file >/dev/null
15591         AFTER=$(roc_hit)
15592         if ! let "AFTER - BEFORE == CPAGES"; then
15593                 error "NOT IN CACHE (6): before: $BEFORE, after: $AFTER"
15594         else
15595                 log "cache hits:: before: $BEFORE, after: $AFTER"
15596         fi
15597
15598         if [ $OST1_VERSION -lt $(version_code 2.12.55) ]; then
15599                 # > 2.12.56 uses pagecache if cached
15600                 log "Read again; it should not be satisfied from the cache."
15601                 BEFORE=$AFTER
15602                 cancel_lru_locks osc
15603                 cat $file >/dev/null
15604                 AFTER=$(roc_hit)
15605                 if ! let "AFTER - BEFORE == 0"; then
15606                         error "IN CACHE (7): before: $BEFORE, after: $AFTER"
15607                 else
15608                         log "cache hits:: before: $BEFORE, after: $AFTER"
15609                 fi
15610         fi
15611
15612         log "Turn off read and write cache"
15613         set_cache read off
15614         set_cache writethrough off
15615
15616         log "Write data and read it back"
15617         log "It should not be satisfied from the cache."
15618         rm -f $file
15619         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
15620         cancel_lru_locks osc
15621         BEFORE=$(roc_hit)
15622         cat $file >/dev/null
15623         AFTER=$(roc_hit)
15624         if ! let "AFTER - BEFORE == 0"; then
15625                 error_ignore bz20762 "IN CACHE (8):before:$BEFORE,after:$AFTER"
15626         else
15627                 log "cache hits:: before: $BEFORE, after: $AFTER"
15628         fi
15629
15630         log "Turn on the read cache and turn off the write cache"
15631         set_cache read on
15632         set_cache writethrough off
15633
15634         log "Write data and read it back"
15635         log "It should not be satisfied from the cache."
15636         rm -f $file
15637         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
15638         BEFORE=$(roc_hit)
15639         cancel_lru_locks osc
15640         cat $file >/dev/null
15641         AFTER=$(roc_hit)
15642         if ! let "AFTER - BEFORE == 0"; then
15643                 error_ignore bz20762 "IN CACHE (9):before:$BEFORE,after:$AFTER"
15644         else
15645                 log "cache hits:: before: $BEFORE, after: $AFTER"
15646         fi
15647
15648         log "Read again; it should be satisfied from the cache."
15649         BEFORE=$(roc_hit)
15650         cancel_lru_locks osc
15651         cat $file >/dev/null
15652         AFTER=$(roc_hit)
15653         if ! let "AFTER - BEFORE == CPAGES"; then
15654                 error "NOT IN CACHE (1): before: $BEFORE, after: $AFTER"
15655         else
15656                 log "cache hits:: before: $BEFORE, after: $AFTER"
15657         fi
15658
15659         restore_lustre_params < $p
15660         rm -f $p $file
15661 }
15662 run_test 156 "Verification of tunables"
15663
15664 test_160a() {
15665         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15666         remote_mds_nodsh && skip "remote MDS with nodsh"
15667         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] ||
15668                 skip "Need MDS version at least 2.2.0"
15669
15670         changelog_register || error "changelog_register failed"
15671         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
15672         changelog_users $SINGLEMDS | grep -q $cl_user ||
15673                 error "User $cl_user not found in changelog_users"
15674
15675         mkdir_on_mdt0 $DIR/$tdir
15676
15677         # change something
15678         test_mkdir -p $DIR/$tdir/pics/2008/zachy
15679         changelog_clear 0 || error "changelog_clear failed"
15680         touch $DIR/$tdir/pics/2008/zachy/$tfile                 # open 1
15681         cp /etc/hosts $DIR/$tdir/pics/2008/zachy/pic1.jpg       # open 2
15682         mv $DIR/$tdir/pics/2008/zachy $DIR/$tdir/pics/zach
15683         ln $DIR/$tdir/pics/zach/pic1.jpg $DIR/$tdir/pics/2008/portland.jpg
15684         ln -s $DIR/$tdir/pics/2008/portland.jpg $DIR/$tdir/pics/desktop.jpg
15685         rm $DIR/$tdir/pics/desktop.jpg
15686
15687         echo "verifying changelog mask"
15688         changelog_chmask "-MKDIR"
15689         changelog_chmask "-CLOSE"
15690
15691         test_mkdir -p $DIR/$tdir/pics/zach/sofia                # not logged
15692         echo "zzzzzz" > $DIR/$tdir/pics/zach/file               # not logged
15693
15694         changelog_chmask "+MKDIR"
15695         changelog_chmask "+CLOSE"
15696
15697         test_mkdir -p $DIR/$tdir/pics/2008/sofia                # mkdir 1
15698         echo "zzzzzz" > $DIR/$tdir/pics/zach/file               # open 3
15699
15700         MKDIRS=$(changelog_dump | grep -c "MKDIR")
15701         CLOSES=$(changelog_dump | grep -c "CLOSE")
15702         [ $MKDIRS -eq 1 ] || error "MKDIR changelog mask count $MKDIRS != 1"
15703         [ $CLOSES -eq 3 ] || error "CLOSE changelog mask count $CLOSES != 3"
15704
15705         # verify contents
15706         echo "verifying target fid"
15707         local fidc=$(changelog_extract_field "CREAT" "$tfile" "t=")
15708         local fidf=$($LFS path2fid $DIR/$tdir/pics/zach/$tfile)
15709         [ "$fidc" == "$fidf" ] ||
15710                 error "changelog '$tfile' fid $fidc != file fid $fidf"
15711         echo "verifying parent fid"
15712         # The FID returned from the Changelog may be the directory shard on
15713         # a different MDT, and not the FID returned by path2fid on the parent.
15714         # Instead of comparing FIDs, verify that fid2path(fidp) is correct,
15715         # since this is what will matter when recreating this file in the tree.
15716         local fidp=$(changelog_extract_field "CREAT" "$tfile" "p=")
15717         local pathp=$($LFS fid2path $MOUNT "$fidp")
15718         [ "${pathp%/}" == "$DIR/$tdir/pics/zach" ] ||
15719                 error "changelog fid2path($fidc) $pathp != $DIR/$tdir/pics/zach"
15720
15721         echo "getting records for $cl_user"
15722         changelog_users $SINGLEMDS
15723         local user_rec1=$(changelog_user_rec $SINGLEMDS $cl_user)
15724         local nclr=3
15725         __changelog_clear $SINGLEMDS $cl_user +$nclr ||
15726                 error "changelog_clear failed"
15727         local user_rec2=$(changelog_user_rec $SINGLEMDS $cl_user)
15728         echo "verifying user clear: $user_rec1 + $nclr == $user_rec2"
15729         [ $user_rec2 == $((user_rec1 + nclr)) ] ||
15730                 error "user index expect $user_rec1 + $nclr != $user_rec2"
15731
15732         local min0_rec=$(changelog_users $SINGLEMDS |
15733                 awk 'min == "" || $2 < min { min = $2 }; END { print min }')
15734         local first_rec=$($LFS changelog $(facet_svc $SINGLEMDS) |
15735                           awk '{ print $1; exit; }')
15736
15737         changelog_dump | tail -n 5
15738         echo "verifying user min purge: $min0_rec + 1 == $first_rec"
15739         [ $first_rec == $((min0_rec + 1)) ] ||
15740                 error "first index should be $min0_rec + 1 not $first_rec"
15741
15742         # LU-3446 changelog index reset on MDT restart
15743         local cur_rec1=$(changelog_users $SINGLEMDS |
15744                          awk '/^current.index:/ { print $NF }')
15745         changelog_clear 0 ||
15746                 error "clear all changelog records for $cl_user failed"
15747         stop $SINGLEMDS || error "Fail to stop $SINGLEMDS"
15748         start $SINGLEMDS $(mdsdevname ${SINGLEMDS//mds/}) $MDS_MOUNT_OPTS ||
15749                 error "Fail to start $SINGLEMDS"
15750         local cur_rec2=$(changelog_users $SINGLEMDS |
15751                          awk '/^current.index:/ { print $NF }')
15752         echo "verifying index survives MDT restart: $cur_rec1 == $cur_rec2"
15753         [ $cur_rec1 == $cur_rec2 ] ||
15754                 error "current index should be $cur_rec1 not $cur_rec2"
15755
15756         echo "verifying users from this test are deregistered"
15757         changelog_deregister || error "changelog_deregister failed"
15758         changelog_users $SINGLEMDS | grep -q $cl_user &&
15759                 error "User '$cl_user' still in changelog_users"
15760
15761         # lctl get_param -n mdd.*.changelog_users
15762         # current_index: 144
15763         # ID    index (idle seconds)
15764         # cl3   144   (2) mask=<list>
15765         if [ -z "$(changelog_users $SINGLEMDS | grep -v current.index)" ]; then
15766                 # this is the normal case where all users were deregistered
15767                 # make sure no new records are added when no users are present
15768                 local last_rec1=$(changelog_users $SINGLEMDS |
15769                                   awk '/^current.index:/ { print $NF }')
15770                 touch $DIR/$tdir/chloe
15771                 local last_rec2=$(changelog_users $SINGLEMDS |
15772                                   awk '/^current.index:/ { print $NF }')
15773                 echo "verify changelogs are off: $last_rec1 == $last_rec2"
15774                 [ $last_rec1 == $last_rec2 ] || error "changelogs not off"
15775         else
15776                 # any changelog users must be leftovers from a previous test
15777                 changelog_users $SINGLEMDS
15778                 echo "other changelog users; can't verify off"
15779         fi
15780 }
15781 run_test 160a "changelog sanity"
15782
15783 test_160b() { # LU-3587
15784         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15785         remote_mds_nodsh && skip "remote MDS with nodsh"
15786         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] ||
15787                 skip "Need MDS version at least 2.2.0"
15788
15789         changelog_register || error "changelog_register failed"
15790         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
15791         changelog_users $SINGLEMDS | grep -q $cl_user ||
15792                 error "User '$cl_user' not found in changelog_users"
15793
15794         local longname1=$(str_repeat a 255)
15795         local longname2=$(str_repeat b 255)
15796
15797         cd $DIR
15798         echo "creating very long named file"
15799         touch $longname1 || error "create of '$longname1' failed"
15800         echo "renaming very long named file"
15801         mv $longname1 $longname2
15802
15803         changelog_dump | grep RENME | tail -n 5
15804         rm -f $longname2
15805 }
15806 run_test 160b "Verify that very long rename doesn't crash in changelog"
15807
15808 test_160c() {
15809         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15810         remote_mds_nodsh && skip "remote MDS with nodsh"
15811
15812         [[ $MDS1_VERSION -gt $(version_code 2.5.57) ]] ||
15813                 [[ $MDS1_VERSION -gt $(version_code 2.5.1) &&
15814                    $MDS1_VERSION -lt $(version_code 2.5.50) ]] ||
15815                 skip "Need MDS version at least 2.5.58 or 2.5.2+"
15816
15817         local rc=0
15818
15819         # Registration step
15820         changelog_register || error "changelog_register failed"
15821
15822         rm -rf $DIR/$tdir
15823         mkdir -p $DIR/$tdir
15824         $MCREATE $DIR/$tdir/foo_160c
15825         changelog_chmask "-TRUNC"
15826         $TRUNCATE $DIR/$tdir/foo_160c 200
15827         changelog_chmask "+TRUNC"
15828         $TRUNCATE $DIR/$tdir/foo_160c 199
15829         changelog_dump | tail -n 5
15830         local truncs=$(changelog_dump | tail -n 5 | grep -c TRUNC)
15831         [ $truncs -eq 1 ] || error "TRUNC changelog mask count $truncs != 1"
15832 }
15833 run_test 160c "verify that changelog log catch the truncate event"
15834
15835 test_160d() {
15836         remote_mds_nodsh && skip "remote MDS with nodsh"
15837         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
15838         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15839         [[ $MDS1_VERSION -ge $(version_code 2.7.60) ]] ||
15840                 skip "Need MDS version at least 2.7.60"
15841
15842         # Registration step
15843         changelog_register || error "changelog_register failed"
15844
15845         mkdir -p $DIR/$tdir/migrate_dir
15846         changelog_clear 0 || error "changelog_clear failed"
15847
15848         $LFS migrate -m 1 $DIR/$tdir/migrate_dir || error "migrate fails"
15849         changelog_dump | tail -n 5
15850         local migrates=$(changelog_dump | grep -c "MIGRT")
15851         [ $migrates -eq 1 ] || error "MIGRATE changelog count $migrates != 1"
15852 }
15853 run_test 160d "verify that changelog log catch the migrate event"
15854
15855 test_160e() {
15856         remote_mds_nodsh && skip "remote MDS with nodsh"
15857
15858         # Create a user
15859         changelog_register || error "changelog_register failed"
15860
15861         local MDT0=$(facet_svc $SINGLEMDS)
15862         local rc
15863
15864         # No user (expect fail)
15865         do_facet $SINGLEMDS $LCTL --device $MDT0 changelog_deregister
15866         rc=$?
15867         if [ $rc -eq 0 ]; then
15868                 error "Should fail without user"
15869         elif [ $rc -ne 4 ]; then
15870                 error "changelog_deregister failed with $rc, expect 4(CMD_HELP)"
15871         fi
15872
15873         # Delete a future user (expect fail)
15874         do_facet $SINGLEMDS $LCTL --device $MDT0 changelog_deregister "cl77"
15875         rc=$?
15876         if [ $rc -eq 0 ]; then
15877                 error "Deleted non-existant user cl77"
15878         elif [ $rc -ne 2 ]; then
15879                 error "changelog_deregister failed with $rc, expect 2 (ENOENT)"
15880         fi
15881
15882         # Clear to a bad index (1 billion should be safe)
15883         $LFS changelog_clear $MDT0 "${CL_USERS[$SINGLEMDS]%% *}" 1000000000
15884         rc=$?
15885
15886         if [ $rc -eq 0 ]; then
15887                 error "Successfully cleared to invalid CL index"
15888         elif [ $rc -ne 22 ]; then
15889                 error "changelog_clear failed with $rc, expected 22 (EINVAL)"
15890         fi
15891 }
15892 run_test 160e "changelog negative testing (should return errors)"
15893
15894 test_160f() {
15895         remote_mds_nodsh && skip "remote MDS with nodsh" && return
15896         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
15897                 skip "Need MDS version at least 2.10.56"
15898
15899         local mdts=$(comma_list $(mdts_nodes))
15900
15901         # Create a user
15902         changelog_register || error "first changelog_register failed"
15903         changelog_register || error "second changelog_register failed"
15904         local cl_users
15905         declare -A cl_user1
15906         declare -A cl_user2
15907         local user_rec1
15908         local user_rec2
15909         local i
15910
15911         # generate some changelog records to accumulate on each MDT
15912         # use all_char because created files should be evenly distributed
15913         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
15914                 error "test_mkdir $tdir failed"
15915         log "$(date +%s): creating first files"
15916         for ((i = 0; i < MDSCOUNT * 2; i++)); do
15917                 $LFS mkdir -i $((i%MDSCOUNT)) $DIR/$tdir/d$i.$((i/MDSCOUNT)) ||
15918                         error "create $DIR/$tdir/d$i.$((i/MDSCOUNT)) failed"
15919         done
15920
15921         # check changelogs have been generated
15922         local start=$SECONDS
15923         local idle_time=$((MDSCOUNT * 5 + 5))
15924         local nbcl=$(changelog_dump | wc -l)
15925         [[ $nbcl -eq 0 ]] && error "no changelogs found"
15926
15927         for param in "changelog_max_idle_time=$idle_time" \
15928                      "changelog_gc=1" \
15929                      "changelog_min_gc_interval=2" \
15930                      "changelog_min_free_cat_entries=3"; do
15931                 local MDT0=$(facet_svc $SINGLEMDS)
15932                 local var="${param%=*}"
15933                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
15934
15935                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
15936                 do_nodes $mdts $LCTL set_param mdd.*.$param
15937         done
15938
15939         # force cl_user2 to be idle (1st part), but also cancel the
15940         # cl_user1 records so that it is not evicted later in the test.
15941         local sleep1=$((idle_time / 2))
15942         echo "$(date +%s): sleep1 $sleep1/${idle_time}s"
15943         sleep $sleep1
15944
15945         # simulate changelog catalog almost full
15946         #define OBD_FAIL_CAT_FREE_RECORDS       0x1313
15947         do_nodes $mdts "$LCTL set_param fail_loc=0x1313 fail_val=3"
15948
15949         for i in $(seq $MDSCOUNT); do
15950                 cl_users=(${CL_USERS[mds$i]})
15951                 cl_user1[mds$i]="${cl_users[0]}"
15952                 cl_user2[mds$i]="${cl_users[1]}"
15953
15954                 [ -n "${cl_user1[mds$i]}" ] ||
15955                         error "mds$i: no user registered"
15956                 [ -n "${cl_user2[mds$i]}" ] ||
15957                         error "mds$i: only ${cl_user2[mds$i]} is registered"
15958
15959                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
15960                 [ -n "$user_rec1" ] ||
15961                         error "mds$i: User ${cl_user1[mds$i]} not registered"
15962                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
15963                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
15964                 [ -n "$user_rec2" ] ||
15965                         error "mds$i: User ${cl_user1[mds$i]} not registered"
15966                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
15967                      "$user_rec1 + 2 == $user_rec2"
15968                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
15969                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
15970                               "$user_rec1 + 2, but is $user_rec2"
15971                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
15972                 [ -n "$user_rec2" ] ||
15973                         error "mds$i: User ${cl_user2[mds$i]} not registered"
15974                 [ $user_rec1 == $user_rec2 ] ||
15975                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
15976                               "$user_rec1, but is $user_rec2"
15977         done
15978
15979         # force cl_user2 idle (2nd part) to just exceed changelog_max_idle_time
15980         local sleep2=$((idle_time - (SECONDS - start) + 1))
15981         echo "$(date +%s): sleep2 $sleep2/${idle_time}s"
15982         sleep $sleep2
15983
15984         # Generate one more changelog to trigger GC at fail_loc for cl_user2.
15985         # cl_user1 should be OK because it recently processed records.
15986         echo "$(date +%s): creating $((MDSCOUNT * 2)) files"
15987         for ((i = 0; i < MDSCOUNT * 2; i++)); do
15988                 $LFS mkdir -i $((i%MDSCOUNT)) $DIR/$tdir/d$i.$((i/MDSCOUNT+2))||
15989                         error "create $DIR/$tdir/d$i.$((i/MDSCOUNT+2)) failed"
15990         done
15991
15992         # ensure gc thread is done
15993         for i in $(mdts_nodes); do
15994                 wait_update $i "ps -e -o comm= | grep chlg_gc_thread" "" 20 ||
15995                         error "$i: GC-thread not done"
15996         done
15997
15998         local first_rec
15999         for (( i = 1; i <= MDSCOUNT; i++ )); do
16000                 # check cl_user1 still registered
16001                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
16002                         error "mds$i: User ${cl_user1[mds$i]} not registered"
16003                 # check cl_user2 unregistered
16004                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
16005                         error "mds$i: User ${cl_user2[mds$i]} still registered"
16006
16007                 # check changelogs are present and starting at $user_rec1 + 1
16008                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16009                 [ -n "$user_rec1" ] ||
16010                         error "mds$i: User ${cl_user1[mds$i]} not registered"
16011                 first_rec=$($LFS changelog $(facet_svc mds$i) |
16012                             awk '{ print $1; exit; }')
16013
16014                 echo "mds$i: $(date +%s) verify rec $user_rec1+1 == $first_rec"
16015                 [ $((user_rec1 + 1)) == $first_rec ] ||
16016                         error "mds$i: rec $first_rec != $user_rec1 + 1"
16017         done
16018 }
16019 run_test 160f "changelog garbage collect (timestamped users)"
16020
16021 test_160g() {
16022         remote_mds_nodsh && skip "remote MDS with nodsh"
16023         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
16024                 skip "Need MDS version at least 2.10.56"
16025
16026         local mdts=$(comma_list $(mdts_nodes))
16027
16028         #define OBD_FAIL_TIME_IN_CHLOG_USER     0x1314
16029         do_nodes $mdts $LCTL set_param fail_loc=0x1314
16030
16031         # Create a user
16032         changelog_register || error "first changelog_register failed"
16033         changelog_register || error "second changelog_register failed"
16034         local cl_users
16035         declare -A cl_user1
16036         declare -A cl_user2
16037         local user_rec1
16038         local user_rec2
16039         local i
16040
16041         # generate some changelog records to accumulate on each MDT
16042         # use all_char because created files should be evenly distributed
16043         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
16044                 error "test_mkdir $tdir failed"
16045         for ((i = 0; i < MDSCOUNT; i++)); do
16046                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
16047                         error "create $DIR/$tdir/d$i.1 failed"
16048         done
16049
16050         # check changelogs have been generated
16051         local nbcl=$(changelog_dump | wc -l)
16052         (( $nbcl > 0 )) || error "no changelogs found"
16053
16054         # reduce the max_idle_indexes value to make sure we exceed it
16055         for param in "changelog_max_idle_indexes=1" \
16056                      "changelog_gc=1" \
16057                      "changelog_min_gc_interval=2" \
16058                      "changelog_min_free_cat_entries=3"; do
16059                 local MDT0=$(facet_svc $SINGLEMDS)
16060                 local var="${param%=*}"
16061                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
16062
16063                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
16064                 do_nodes $mdts $LCTL set_param mdd.*.$param ||
16065                         error "unable to set mdd.*.$param"
16066         done
16067
16068         # simulate changelog catalog almost full
16069         #define OBD_FAIL_CAT_FREE_RECORDS       0x1313
16070         do_nodes $mdts "$LCTL set_param fail_loc=0x1313 fail_val=3"
16071
16072         local start=$SECONDS
16073         for i in $(seq $MDSCOUNT); do
16074                 cl_users=(${CL_USERS[mds$i]})
16075                 cl_user1[mds$i]="${cl_users[0]}"
16076                 cl_user2[mds$i]="${cl_users[1]}"
16077
16078                 [ -n "${cl_user1[mds$i]}" ] ||
16079                         error "mds$i: no user registered"
16080                 [ -n "${cl_user2[mds$i]}" ] ||
16081                         error "mds$i: only ${cl_user1[mds$i]} is registered"
16082
16083                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16084                 [ -n "$user_rec1" ] ||
16085                         error "mds$i: User ${cl_user1[mds$i]} not registered"
16086                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
16087                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16088                 [ -n "$user_rec2" ] ||
16089                         error "mds$i: User ${cl_user1[mds$i]} not registered"
16090                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
16091                      "$user_rec1 + 2 == $user_rec2"
16092                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
16093                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
16094                               "$user_rec1 + 2, but is $user_rec2"
16095                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
16096                 [ -n "$user_rec2" ] ||
16097                         error "mds$i: User ${cl_user2[mds$i]} not registered"
16098                 [ $user_rec1 == $user_rec2 ] ||
16099                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
16100                               "$user_rec1, but is $user_rec2"
16101         done
16102
16103         # ensure we are past the previous changelog_min_gc_interval set above
16104         local sleep2=$((start + 2 - SECONDS))
16105         (( sleep2 > 0 )) && echo "sleep $sleep2 for interval" && sleep $sleep2
16106
16107         # Generate one more changelog to trigger GC at fail_loc for cl_user2.
16108         # cl_user1 should be OK because it recently processed records.
16109         for ((i = 0; i < MDSCOUNT; i++)); do
16110                 $LFS mkdir -i $i $DIR/$tdir/d$i.3 $DIR/$tdir/d$i.4 ||
16111                         error "create $DIR/$tdir/d$i.3 failed"
16112         done
16113
16114         # ensure gc thread is done
16115         for i in $(mdts_nodes); do
16116                 wait_update $i "ps -e -o comm= | grep chlg_gc_thread" "" 20 ||
16117                         error "$i: GC-thread not done"
16118         done
16119
16120         local first_rec
16121         for (( i = 1; i <= MDSCOUNT; i++ )); do
16122                 # check cl_user1 still registered
16123                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
16124                         error "mds$i: User ${cl_user1[mds$i]} not registered"
16125                 # check cl_user2 unregistered
16126                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
16127                         error "mds$i: User ${cl_user2[mds$i]} still registered"
16128
16129                 # check changelogs are present and starting at $user_rec1 + 1
16130                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16131                 [ -n "$user_rec1" ] ||
16132                         error "mds$i: User ${cl_user1[mds$i]} not registered"
16133                 first_rec=$($LFS changelog $(facet_svc mds$i) |
16134                             awk '{ print $1; exit; }')
16135
16136                 echo "mds$i: $(date +%s) verify rec $user_rec1+1 == $first_rec"
16137                 [ $((user_rec1 + 1)) == $first_rec ] ||
16138                         error "mds$i: rec $first_rec != $user_rec1 + 1"
16139         done
16140 }
16141 run_test 160g "changelog garbage collect (old users)"
16142
16143 test_160h() {
16144         remote_mds_nodsh && skip "remote MDS with nodsh" && return
16145         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
16146                 skip "Need MDS version at least 2.10.56"
16147
16148         local mdts=$(comma_list $(mdts_nodes))
16149
16150         # Create a user
16151         changelog_register || error "first changelog_register failed"
16152         changelog_register || error "second changelog_register failed"
16153         local cl_users
16154         declare -A cl_user1
16155         declare -A cl_user2
16156         local user_rec1
16157         local user_rec2
16158         local i
16159
16160         # generate some changelog records to accumulate on each MDT
16161         # use all_char because created files should be evenly distributed
16162         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
16163                 error "test_mkdir $tdir failed"
16164         for ((i = 0; i < MDSCOUNT; i++)); do
16165                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
16166                         error "create $DIR/$tdir/d$i.1 failed"
16167         done
16168
16169         # check changelogs have been generated
16170         local nbcl=$(changelog_dump | wc -l)
16171         [[ $nbcl -eq 0 ]] && error "no changelogs found"
16172
16173         for param in "changelog_max_idle_time=10" \
16174                      "changelog_gc=1" \
16175                      "changelog_min_gc_interval=2"; do
16176                 local MDT0=$(facet_svc $SINGLEMDS)
16177                 local var="${param%=*}"
16178                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
16179
16180                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
16181                 do_nodes $mdts $LCTL set_param mdd.*.$param
16182         done
16183
16184         # force cl_user2 to be idle (1st part)
16185         sleep 9
16186
16187         for i in $(seq $MDSCOUNT); do
16188                 cl_users=(${CL_USERS[mds$i]})
16189                 cl_user1[mds$i]="${cl_users[0]}"
16190                 cl_user2[mds$i]="${cl_users[1]}"
16191
16192                 [ -n "${cl_user1[mds$i]}" ] ||
16193                         error "mds$i: no user registered"
16194                 [ -n "${cl_user2[mds$i]}" ] ||
16195                         error "mds$i: only ${cl_user2[mds$i]} is registered"
16196
16197                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16198                 [ -n "$user_rec1" ] ||
16199                         error "mds$i: User ${cl_user1[mds$i]} not registered"
16200                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
16201                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16202                 [ -n "$user_rec2" ] ||
16203                         error "mds$i: User ${cl_user1[mds$i]} not registered"
16204                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
16205                      "$user_rec1 + 2 == $user_rec2"
16206                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
16207                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
16208                               "$user_rec1 + 2, but is $user_rec2"
16209                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
16210                 [ -n "$user_rec2" ] ||
16211                         error "mds$i: User ${cl_user2[mds$i]} not registered"
16212                 [ $user_rec1 == $user_rec2 ] ||
16213                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
16214                               "$user_rec1, but is $user_rec2"
16215         done
16216
16217         # force cl_user2 to be idle (2nd part) and to reach
16218         # changelog_max_idle_time
16219         sleep 2
16220
16221         # force each GC-thread start and block then
16222         # one per MDT/MDD, set fail_val accordingly
16223         #define OBD_FAIL_FORCE_GC_THREAD 0x1316
16224         do_nodes $mdts $LCTL set_param fail_loc=0x1316
16225
16226         # generate more changelogs to trigger fail_loc
16227         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
16228                 error "create $DIR/$tdir/${tfile}bis failed"
16229
16230         # stop MDT to stop GC-thread, should be done in back-ground as it will
16231         # block waiting for the thread to be released and exit
16232         declare -A stop_pids
16233         for i in $(seq $MDSCOUNT); do
16234                 stop mds$i &
16235                 stop_pids[mds$i]=$!
16236         done
16237
16238         for i in $(mdts_nodes); do
16239                 local facet
16240                 local nb=0
16241                 local facets=$(facets_up_on_host $i)
16242
16243                 for facet in ${facets//,/ }; do
16244                         if [[ $facet == mds* ]]; then
16245                                 nb=$((nb + 1))
16246                         fi
16247                 done
16248                 # ensure each MDS's gc threads are still present and all in "R"
16249                 # state (OBD_FAIL_FORCE_GC_THREAD effect!)
16250                 [[ $(do_node $i pgrep chlg_gc_thread | wc -l) -eq $nb ]] ||
16251                         error "$i: expected $nb GC-thread"
16252                 wait_update $i \
16253                         "ps -C chlg_gc_thread -o state --no-headers | uniq" \
16254                         "R" 20 ||
16255                         error "$i: GC-thread not found in R-state"
16256                 # check umounts of each MDT on MDS have reached kthread_stop()
16257                 [[ $(do_node $i pgrep umount | wc -l) -eq $nb ]] ||
16258                         error "$i: expected $nb umount"
16259                 wait_update $i \
16260                         "ps -C umount -o state --no-headers | uniq" "D" 20 ||
16261                         error "$i: umount not found in D-state"
16262         done
16263
16264         # release all GC-threads
16265         do_nodes $mdts $LCTL set_param fail_loc=0
16266
16267         # wait for MDT stop to complete
16268         for i in $(seq $MDSCOUNT); do
16269                 wait ${stop_pids[mds$i]} || error "mds$i: stop failed"
16270         done
16271
16272         # XXX
16273         # may try to check if any orphan changelog records are present
16274         # via ldiskfs/zfs and llog_reader...
16275
16276         # re-start/mount MDTs
16277         for i in $(seq $MDSCOUNT); do
16278                 start mds$i $(mdsdevname $i) $MDS_MOUNT_OPTS ||
16279                         error "Fail to start mds$i"
16280         done
16281
16282         local first_rec
16283         for i in $(seq $MDSCOUNT); do
16284                 # check cl_user1 still registered
16285                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
16286                         error "mds$i: User ${cl_user1[mds$i]} not registered"
16287                 # check cl_user2 unregistered
16288                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
16289                         error "mds$i: User ${cl_user2[mds$i]} still registered"
16290
16291                 # check changelogs are present and starting at $user_rec1 + 1
16292                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16293                 [ -n "$user_rec1" ] ||
16294                         error "mds$i: User ${cl_user1[mds$i]} not registered"
16295                 first_rec=$($LFS changelog $(facet_svc mds$i) |
16296                             awk '{ print $1; exit; }')
16297
16298                 echo "mds$i: verifying first index $user_rec1 + 1 == $first_rec"
16299                 [ $((user_rec1 + 1)) == $first_rec ] ||
16300                         error "mds$i: first index should be $user_rec1 + 1, " \
16301                               "but is $first_rec"
16302         done
16303 }
16304 run_test 160h "changelog gc thread stop upon umount, orphan records delete " \
16305               "during mount"
16306
16307 test_160i() {
16308
16309         local mdts=$(comma_list $(mdts_nodes))
16310
16311         changelog_register || error "first changelog_register failed"
16312
16313         # generate some changelog records to accumulate on each MDT
16314         # use all_char because created files should be evenly distributed
16315         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
16316                 error "test_mkdir $tdir failed"
16317         for ((i = 0; i < MDSCOUNT; i++)); do
16318                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
16319                         error "create $DIR/$tdir/d$i.1 failed"
16320         done
16321
16322         # check changelogs have been generated
16323         local nbcl=$(changelog_dump | wc -l)
16324         [[ $nbcl -eq 0 ]] && error "no changelogs found"
16325
16326         # simulate race between register and unregister
16327         # XXX as fail_loc is set per-MDS, with DNE configs the race
16328         # simulation will only occur for one MDT per MDS and for the
16329         # others the normal race scenario will take place
16330         #define CFS_FAIL_CHLOG_USER_REG_UNREG_RACE          0x1315
16331         do_nodes $mdts $LCTL set_param fail_loc=0x10001315
16332         do_nodes $mdts $LCTL set_param fail_val=1
16333
16334         # unregister 1st user
16335         changelog_deregister &
16336         local pid1=$!
16337         # wait some time for deregister work to reach race rdv
16338         sleep 2
16339         # register 2nd user
16340         changelog_register || error "2nd user register failed"
16341
16342         wait $pid1 || error "1st user deregister failed"
16343
16344         local i
16345         local last_rec
16346         declare -A LAST_REC
16347         for i in $(seq $MDSCOUNT); do
16348                 if changelog_users mds$i | grep "^cl"; then
16349                         # make sure new records are added with one user present
16350                         LAST_REC[mds$i]=$(changelog_users $SINGLEMDS |
16351                                           awk '/^current.index:/ { print $NF }')
16352                 else
16353                         error "mds$i has no user registered"
16354                 fi
16355         done
16356
16357         # generate more changelog records to accumulate on each MDT
16358         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
16359                 error "create $DIR/$tdir/${tfile}bis failed"
16360
16361         for i in $(seq $MDSCOUNT); do
16362                 last_rec=$(changelog_users $SINGLEMDS |
16363                            awk '/^current.index:/ { print $NF }')
16364                 echo "verify changelogs are on: $last_rec != ${LAST_REC[mds$i]}"
16365                 [ $last_rec != ${LAST_REC[mds$i]} ] ||
16366                         error "changelogs are off on mds$i"
16367         done
16368 }
16369 run_test 160i "changelog user register/unregister race"
16370
16371 test_160j() {
16372         remote_mds_nodsh && skip "remote MDS with nodsh"
16373         [[ $MDS1_VERSION -lt $(version_code 2.12.56) ]] &&
16374                 skip "Need MDS version at least 2.12.56"
16375
16376         mount_client $MOUNT2 || error "mount_client on $MOUNT2 failed"
16377         stack_trap "umount $MOUNT2" EXIT
16378
16379         changelog_register || error "first changelog_register failed"
16380         stack_trap "changelog_deregister" EXIT
16381
16382         # generate some changelog
16383         # use all_char because created files should be evenly distributed
16384         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
16385                 error "mkdir $tdir failed"
16386         for ((i = 0; i < MDSCOUNT; i++)); do
16387                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
16388                         error "create $DIR/$tdir/d$i.1 failed"
16389         done
16390
16391         # open the changelog device
16392         exec 3>/dev/changelog-$FSNAME-MDT0000
16393         stack_trap "exec 3>&-" EXIT
16394         exec 4</dev/changelog-$FSNAME-MDT0000
16395         stack_trap "exec 4<&-" EXIT
16396
16397         # umount the first lustre mount
16398         umount $MOUNT
16399         stack_trap "mount_client $MOUNT" EXIT
16400
16401         # read changelog, which may or may not fail, but should not crash
16402         cat <&4 >/dev/null
16403
16404         # clear changelog
16405         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
16406         changelog_users $SINGLEMDS | grep -q $cl_user ||
16407                 error "User $cl_user not found in changelog_users"
16408
16409         printf 'clear:'$cl_user':0' >&3
16410 }
16411 run_test 160j "client can be umounted while its chanangelog is being used"
16412
16413 test_160k() {
16414         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16415         remote_mds_nodsh && skip "remote MDS with nodsh"
16416
16417         mkdir -p $DIR/$tdir/1/1
16418
16419         changelog_register || error "changelog_register failed"
16420         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
16421
16422         changelog_users $SINGLEMDS | grep -q $cl_user ||
16423                 error "User '$cl_user' not found in changelog_users"
16424 #define OBD_FAIL_MDS_CHANGELOG_REORDER 0x15d
16425         do_facet mds1 $LCTL set_param fail_loc=0x8000015d fail_val=3
16426         rmdir $DIR/$tdir/1/1 & sleep 1
16427         mkdir $DIR/$tdir/2
16428         touch $DIR/$tdir/2/2
16429         rm -rf $DIR/$tdir/2
16430
16431         wait
16432         sleep 4
16433
16434         changelog_dump | grep rmdir || error "rmdir not recorded"
16435 }
16436 run_test 160k "Verify that changelog records are not lost"
16437
16438 # Verifies that a file passed as a parameter has recently had an operation
16439 # performed on it that has generated an MTIME changelog which contains the
16440 # correct parent FID. As files might reside on a different MDT from the
16441 # parent directory in DNE configurations, the FIDs are translated to paths
16442 # before being compared, which should be identical
16443 compare_mtime_changelog() {
16444         local file="${1}"
16445         local mdtidx
16446         local mtime
16447         local cl_fid
16448         local pdir
16449         local dir
16450
16451         mdtidx=$($LFS getstripe --mdt-index $file)
16452         mdtidx=$(printf "%04x" $mdtidx)
16453
16454         # Obtain the parent FID from the MTIME changelog
16455         mtime=$($LFS changelog $FSNAME-MDT$mdtidx | tail -n 1 | grep MTIME)
16456         [ -z "$mtime" ] && error "MTIME changelog not recorded"
16457
16458         cl_fid=$(sed -e 's/.* p=//' -e 's/ .*//' <<<$mtime)
16459         [ -z "$cl_fid" ] && error "parent FID not present"
16460
16461         # Verify that the path for the parent FID is the same as the path for
16462         # the test directory
16463         pdir=$($LFS fid2path $MOUNT "$cl_fid")
16464
16465         dir=$(dirname $1)
16466
16467         [[ "${pdir%/}" == "$dir" ]] ||
16468                 error "MTIME changelog parent FID is wrong, expected $dir, got $pdir"
16469 }
16470
16471 test_160l() {
16472         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16473
16474         remote_mds_nodsh && skip "remote MDS with nodsh"
16475         [[ $MDS1_VERSION -ge $(version_code 2.13.55) ]] ||
16476                 skip "Need MDS version at least 2.13.55"
16477
16478         local cl_user
16479
16480         changelog_register || error "changelog_register failed"
16481         cl_user="${CL_USERS[$SINGLEMDS]%% *}"
16482
16483         changelog_users $SINGLEMDS | grep -q $cl_user ||
16484                 error "User '$cl_user' not found in changelog_users"
16485
16486         # Clear some types so that MTIME changelogs are generated
16487         changelog_chmask "-CREAT"
16488         changelog_chmask "-CLOSE"
16489
16490         test_mkdir $DIR/$tdir || error "failed to mkdir $DIR/$tdir"
16491
16492         # Test CL_MTIME during setattr
16493         touch $DIR/$tdir/$tfile
16494         compare_mtime_changelog $DIR/$tdir/$tfile
16495
16496         # Test CL_MTIME during close
16497         $MULTIOP $DIR/$tdir/${tfile}_2 O_2w4096c || error "multiop failed"
16498         compare_mtime_changelog $DIR/$tdir/${tfile}_2
16499 }
16500 run_test 160l "Verify that MTIME changelog records contain the parent FID"
16501
16502 test_160m() {
16503         remote_mds_nodsh && skip "remote MDS with nodsh" && return
16504         [[ $MDS1_VERSION -ge $(version_code 2.14.51) ]] ||
16505                 skip "Need MDS version at least 2.14.51"
16506         local cl_users
16507         local cl_user1
16508         local cl_user2
16509         local pid1
16510
16511         # Create a user
16512         changelog_register || error "first changelog_register failed"
16513         changelog_register || error "second changelog_register failed"
16514
16515         cl_users=(${CL_USERS[mds1]})
16516         cl_user1="${cl_users[0]}"
16517         cl_user2="${cl_users[1]}"
16518         # generate some changelog records to accumulate on MDT0
16519         test_mkdir -p -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
16520         createmany -m $DIR/$tdir/$tfile 50 ||
16521                 error "create $DIR/$tdir/$tfile failed"
16522         unlinkmany $DIR/$tdir/$tfile 50 || error "unlinkmany failed"
16523         rm -f $DIR/$tdir
16524
16525         # check changelogs have been generated
16526         local nbcl=$(changelog_dump | wc -l)
16527         [[ $nbcl -eq 0 ]] && error "no changelogs found"
16528
16529 #define OBD_FAIL_MDS_CHANGELOG_RACE      0x15f
16530         do_facet mds1 $LCTL set_param fail_loc=0x8000015f fail_val=0
16531
16532         __changelog_clear mds1 $cl_user1 +10
16533         __changelog_clear mds1 $cl_user2 0 &
16534         pid1=$!
16535         sleep 2
16536         __changelog_clear mds1 $cl_user1 0 ||
16537                 error "fail to cancel record for $cl_user1"
16538         wait $pid1
16539         [[ $? -eq 0 ]] || error "fail to cancel record for $cl_user2"
16540 }
16541 run_test 160m "Changelog clear race"
16542
16543 test_160n() {
16544         remote_mds_nodsh && skip "remote MDS with nodsh" && return
16545         [[ $MDS1_VERSION -ge $(version_code 2.14.51) ]] ||
16546                 skip "Need MDS version at least 2.14.51"
16547         local cl_users
16548         local cl_user1
16549         local cl_user2
16550         local pid1
16551         local first_rec
16552         local last_rec=0
16553
16554         # Create a user
16555         changelog_register || error "first changelog_register failed"
16556
16557         cl_users=(${CL_USERS[mds1]})
16558         cl_user1="${cl_users[0]}"
16559
16560         # generate some changelog records to accumulate on MDT0
16561         test_mkdir -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
16562         first_rec=$(changelog_users $SINGLEMDS |
16563                         awk '/^current.index:/ { print $NF }')
16564         while (( last_rec < (( first_rec + 65000)) )); do
16565                 createmany -m $DIR/$tdir/$tfile 10000 ||
16566                         error "create $DIR/$tdir/$tfile failed"
16567
16568                 for i in $(seq 0 10000); do
16569                         mrename $DIR/$tdir/$tfile$i $DIR/$tdir/$tfile-new$i \
16570                                 > /dev/null
16571                 done
16572
16573                 unlinkmany $DIR/$tdir/$tfile-new 10000 ||
16574                         error "unlinkmany failed unlink"
16575                 last_rec=$(changelog_users $SINGLEMDS |
16576                         awk '/^current.index:/ { print $NF }')
16577                 echo last record $last_rec
16578                 (( last_rec == 0 )) && error "no changelog found"
16579         done
16580
16581 #define OBD_FAIL_MDS_CHANGELOG_DEL       0x16c
16582         do_facet mds1 $LCTL set_param fail_loc=0x8000016c fail_val=0
16583
16584         __changelog_clear mds1 $cl_user1 0 &
16585         pid1=$!
16586         sleep 2
16587         __changelog_clear mds1 $cl_user1 0 ||
16588                 error "fail to cancel record for $cl_user1"
16589         wait $pid1
16590         [[ $? -eq 0 ]] || error "fail to cancel record for $cl_user2"
16591 }
16592 run_test 160n "Changelog destroy race"
16593
16594 test_160o() {
16595         local mdt="$(facet_svc $SINGLEMDS)"
16596
16597         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
16598         remote_mds_nodsh && skip "remote MDS with nodsh"
16599         [ $MDS1_VERSION -ge $(version_code 2.14.52) ] ||
16600                 skip "Need MDS version at least 2.14.52"
16601
16602         changelog_register --user test_160o -m unlnk+close+open ||
16603                 error "changelog_register failed"
16604
16605         do_facet $SINGLEMDS $LCTL --device $mdt \
16606                                 changelog_register -u "Tt3_-#" &&
16607                 error "bad symbols in name should fail"
16608
16609         do_facet $SINGLEMDS $LCTL --device $mdt \
16610                                 changelog_register -u test_160o &&
16611                 error "the same name registration should fail"
16612
16613         do_facet $SINGLEMDS $LCTL --device $mdt \
16614                         changelog_register -u test_160toolongname &&
16615                 error "too long name registration should fail"
16616
16617         changelog_chmask "MARK+HSM"
16618         lctl get_param mdd.*.changelog*mask
16619         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
16620         changelog_users $SINGLEMDS | grep -q $cl_user ||
16621                 error "User $cl_user not found in changelog_users"
16622         #verify username
16623         echo $cl_user | grep -q test_160o ||
16624                 error "User $cl_user has no specific name 'test160o'"
16625
16626         # change something
16627         changelog_clear 0 || error "changelog_clear failed"
16628         # generate some changelog records to accumulate on MDT0
16629         test_mkdir -p -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
16630         touch $DIR/$tdir/$tfile                 # open 1
16631
16632         OPENS=$(changelog_dump | grep -c "OPEN")
16633         [[ $OPENS -eq 1 ]] || error "OPEN changelog mask count $OPENS != 1"
16634
16635         # must be no MKDIR it wasn't set as user mask
16636         MKDIR=$(changelog_dump | grep -c "MKDIR")
16637         [[ $MKDIR -eq 0 ]] || error "MKDIR changelog mask found $MKDIR > 0"
16638
16639         oldmask=$(do_facet $SINGLEMDS $LCTL get_param \
16640                                 mdd.$mdt.changelog_current_mask -n)
16641         # register maskless user
16642         changelog_register || error "changelog_register failed"
16643         # effective mask should be not changed because it is not minimal
16644         mask=$(do_facet $SINGLEMDS $LCTL get_param \
16645                                 mdd.$mdt.changelog_current_mask -n)
16646         [[ $mask == $oldmask ]] || error "mask was changed: $mask vs $oldmask"
16647         # set server mask to minimal value
16648         changelog_chmask "MARK"
16649         # check effective mask again, should be treated as DEFMASK now
16650         mask=$(do_facet $SINGLEMDS $LCTL get_param \
16651                                 mdd.$mdt.changelog_current_mask -n)
16652         [[ $mask == *"HLINK"* ]] || error "mask is not DEFMASK as expected"
16653
16654         do_facet $SINGLEMDS $LCTL --device $mdt \
16655                                 changelog_deregister -u test_160o ||
16656                 error "cannot deregister by name"
16657 }
16658 run_test 160o "changelog user name and mask"
16659
16660 test_160p() {
16661         remote_mds_nodsh && skip "remote MDS with nodsh" && return
16662         [[ $MDS1_VERSION -ge $(version_code 2.14.51) ]] ||
16663                 skip "Need MDS version at least 2.14.51"
16664         [[ "$mds1_FSTYPE" == "ldiskfs" ]] || skip "ldiskfs only test"
16665         local cl_users
16666         local cl_user1
16667         local entry_count
16668
16669         # Create a user
16670         changelog_register || error "first changelog_register failed"
16671
16672         cl_users=(${CL_USERS[mds1]})
16673         cl_user1="${cl_users[0]}"
16674
16675         test_mkdir -p -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
16676         createmany -m $DIR/$tdir/$tfile 50 ||
16677                 error "create $DIR/$tdir/$tfile failed"
16678         unlinkmany $DIR/$tdir/$tfile 50 || error "unlinkmany failed"
16679         rm -rf $DIR/$tdir
16680
16681         # check changelogs have been generated
16682         entry_count=$(changelog_dump | wc -l)
16683         ((entry_count != 0)) || error "no changelog entries found"
16684
16685         # remove changelog_users and check that orphan entries are removed
16686         stop mds1
16687         do_facet mds1 "$DEBUGFS -w -R 'rm changelog_users' $(mdsdevname 1)"
16688         start mds1 || error "cannot start mdt"
16689         entry_count=$(changelog_dump | wc -l)
16690         ((entry_count == 0)) ||
16691                 error "found $entry_count changelog entries, expected none"
16692 }
16693 run_test 160p "Changelog orphan cleanup with no users"
16694
16695 test_160q() {
16696         local mdt="$(facet_svc $SINGLEMDS)"
16697         local clu
16698
16699         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
16700         remote_mds_nodsh && skip "remote MDS with nodsh"
16701         [ $MDS1_VERSION -ge $(version_code 2.14.54) ] ||
16702                 skip "Need MDS version at least 2.14.54"
16703
16704         # set server mask to minimal value like server init does
16705         changelog_chmask "MARK"
16706         clu=$(do_facet $SINGLEMDS $LCTL --device $mdt changelog_register -n) ||
16707                 error "changelog_register failed"
16708         # check effective mask again, should be treated as DEFMASK now
16709         mask=$(do_facet $SINGLEMDS $LCTL get_param \
16710                                 mdd.$mdt.changelog_current_mask -n)
16711         do_facet $SINGLEMDS $LCTL --device $mdt changelog_deregister $clu ||
16712                 error "changelog_deregister failed"
16713         [[ $mask == *"HLINK"* ]] || error "mask is not DEFMASK as expected"
16714 }
16715 run_test 160q "changelog effective mask is DEFMASK if not set"
16716
16717 test_161a() {
16718         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16719
16720         test_mkdir -c1 $DIR/$tdir
16721         cp /etc/hosts $DIR/$tdir/$tfile
16722         test_mkdir -c1 $DIR/$tdir/foo1
16723         test_mkdir -c1 $DIR/$tdir/foo2
16724         ln $DIR/$tdir/$tfile $DIR/$tdir/foo1/sofia
16725         ln $DIR/$tdir/$tfile $DIR/$tdir/foo2/zachary
16726         ln $DIR/$tdir/$tfile $DIR/$tdir/foo1/luna
16727         ln $DIR/$tdir/$tfile $DIR/$tdir/foo2/thor
16728         local FID=$($LFS path2fid $DIR/$tdir/$tfile | tr -d '[]')
16729         if [ "$($LFS fid2path $DIR $FID | wc -l)" != "5" ]; then
16730                 $LFS fid2path $DIR $FID
16731                 error "bad link ea"
16732         fi
16733         # middle
16734         rm $DIR/$tdir/foo2/zachary
16735         # last
16736         rm $DIR/$tdir/foo2/thor
16737         # first
16738         rm $DIR/$tdir/$tfile
16739         # rename
16740         mv $DIR/$tdir/foo1/sofia $DIR/$tdir/foo2/maggie
16741         [ "$($LFS fid2path $FSNAME --link 1 $FID)" != "$tdir/foo2/maggie" ] &&
16742                 { $LFS fid2path $DIR $FID; error "bad link rename"; }
16743         rm $DIR/$tdir/foo2/maggie
16744
16745         # overflow the EA
16746         local longname=$tfile.avg_len_is_thirty_two_
16747         stack_trap "unlinkmany $DIR/$tdir/foo2/$longname 1000 || \
16748                 error_noexit 'failed to unlink many hardlinks'" EXIT
16749         createmany -l$DIR/$tdir/foo1/luna $DIR/$tdir/foo2/$longname 1000 ||
16750                 error "failed to hardlink many files"
16751         links=$($LFS fid2path $DIR $FID | wc -l)
16752         echo -n "${links}/1000 links in link EA"
16753         [[ $links -gt 60 ]] || error "expected at least 60 links in link EA"
16754 }
16755 run_test 161a "link ea sanity"
16756
16757 test_161b() {
16758         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16759         [ $MDSCOUNT -lt 2 ] && skip_env "skipping remote directory test"
16760
16761         local MDTIDX=1
16762         local remote_dir=$DIR/$tdir/remote_dir
16763
16764         mkdir -p $DIR/$tdir
16765         $LFS mkdir -i $MDTIDX $remote_dir ||
16766                 error "create remote directory failed"
16767
16768         cp /etc/hosts $remote_dir/$tfile
16769         mkdir -p $remote_dir/foo1
16770         mkdir -p $remote_dir/foo2
16771         ln $remote_dir/$tfile $remote_dir/foo1/sofia
16772         ln $remote_dir/$tfile $remote_dir/foo2/zachary
16773         ln $remote_dir/$tfile $remote_dir/foo1/luna
16774         ln $remote_dir/$tfile $remote_dir/foo2/thor
16775
16776         local FID=$($LFS path2fid $remote_dir/$tfile | tr -d '[' |
16777                      tr -d ']')
16778         if [ "$($LFS fid2path $DIR $FID | wc -l)" != "5" ]; then
16779                 $LFS fid2path $DIR $FID
16780                 error "bad link ea"
16781         fi
16782         # middle
16783         rm $remote_dir/foo2/zachary
16784         # last
16785         rm $remote_dir/foo2/thor
16786         # first
16787         rm $remote_dir/$tfile
16788         # rename
16789         mv $remote_dir/foo1/sofia $remote_dir/foo2/maggie
16790         local link_path=$($LFS fid2path $FSNAME --link 1 $FID)
16791         if [ "$DIR/$link_path" != "$remote_dir/foo2/maggie" ]; then
16792                 $LFS fid2path $DIR $FID
16793                 error "bad link rename"
16794         fi
16795         rm $remote_dir/foo2/maggie
16796
16797         # overflow the EA
16798         local longname=filename_avg_len_is_thirty_two_
16799         createmany -l$remote_dir/foo1/luna $remote_dir/foo2/$longname 1000 ||
16800                 error "failed to hardlink many files"
16801         links=$($LFS fid2path $DIR $FID | wc -l)
16802         echo -n "${links}/1000 links in link EA"
16803         [[ ${links} -gt 60 ]] ||
16804                 error "expected at least 60 links in link EA"
16805         unlinkmany $remote_dir/foo2/$longname 1000 ||
16806         error "failed to unlink many hardlinks"
16807 }
16808 run_test 161b "link ea sanity under remote directory"
16809
16810 test_161c() {
16811         remote_mds_nodsh && skip "remote MDS with nodsh"
16812         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16813         [[ $MDS1_VERSION -lt $(version_code 2.1.5) ]] &&
16814                 skip "Need MDS version at least 2.1.5"
16815
16816         # define CLF_RENAME_LAST 0x0001
16817         # rename overwrite a target having nlink = 1 (changelog flag 0x1)
16818         changelog_register || error "changelog_register failed"
16819
16820         rm -rf $DIR/$tdir
16821         test_mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir
16822         touch $DIR/$tdir/foo_161c
16823         touch $DIR/$tdir/bar_161c
16824         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/bar_161c
16825         changelog_dump | grep RENME | tail -n 5
16826         local flags=$(changelog_dump | grep "RENME.*bar_161c" | cut -f5 -d' ')
16827         changelog_clear 0 || error "changelog_clear failed"
16828         if [ x$flags != "x0x1" ]; then
16829                 error "flag $flags is not 0x1"
16830         fi
16831
16832         echo "rename overwrite target with nlink = 1, changelog flags=$flags"
16833         # rename overwrite a target having nlink > 1 (changelog flag 0x0)
16834         touch $DIR/$tdir/foo_161c
16835         touch $DIR/$tdir/bar_161c
16836         ln $DIR/$tdir/bar_161c $DIR/$tdir/foobar_161c
16837         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/bar_161c
16838         changelog_dump | grep RENME | tail -n 5
16839         flags=$(changelog_dump | grep "RENME.*bar_161c" | cut -f5 -d' ')
16840         changelog_clear 0 || error "changelog_clear failed"
16841         if [ x$flags != "x0x0" ]; then
16842                 error "flag $flags is not 0x0"
16843         fi
16844         echo "rename overwrite a target having nlink > 1," \
16845                 "changelog record has flags of $flags"
16846
16847         # rename doesn't overwrite a target (changelog flag 0x0)
16848         touch $DIR/$tdir/foo_161c
16849         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/foo2_161c
16850         changelog_dump | grep RENME | tail -n 5
16851         flags=$(changelog_dump | grep RENME | tail -1 | cut -f5 -d' ')
16852         changelog_clear 0 || error "changelog_clear failed"
16853         if [ x$flags != "x0x0" ]; then
16854                 error "flag $flags is not 0x0"
16855         fi
16856         echo "rename doesn't overwrite a target," \
16857                 "changelog record has flags of $flags"
16858
16859         # define CLF_UNLINK_LAST 0x0001
16860         # unlink a file having nlink = 1 (changelog flag 0x1)
16861         rm -f $DIR/$tdir/foo2_161c
16862         changelog_dump | grep UNLNK | tail -n 5
16863         flags=$(changelog_dump | grep UNLNK | tail -1 | cut -f5 -d' ')
16864         changelog_clear 0 || error "changelog_clear failed"
16865         if [ x$flags != "x0x1" ]; then
16866                 error "flag $flags is not 0x1"
16867         fi
16868         echo "unlink a file having nlink = 1," \
16869                 "changelog record has flags of $flags"
16870
16871         # unlink a file having nlink > 1 (changelog flag 0x0)
16872         ln -f $DIR/$tdir/bar_161c $DIR/$tdir/foobar_161c
16873         rm -f $DIR/$tdir/foobar_161c
16874         changelog_dump | grep UNLNK | tail -n 5
16875         flags=$(changelog_dump | grep UNLNK | tail -1 | cut -f5 -d' ')
16876         changelog_clear 0 || error "changelog_clear failed"
16877         if [ x$flags != "x0x0" ]; then
16878                 error "flag $flags is not 0x0"
16879         fi
16880         echo "unlink a file having nlink > 1, changelog record flags '$flags'"
16881 }
16882 run_test 161c "check CL_RENME[UNLINK] changelog record flags"
16883
16884 test_161d() {
16885         remote_mds_nodsh && skip "remote MDS with nodsh"
16886         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
16887
16888         local pid
16889         local fid
16890
16891         changelog_register || error "changelog_register failed"
16892
16893         # work in a standalone dir to avoid locking on $DIR/$MOUNT to
16894         # interfer with $MOUNT/.lustre/fid/ access
16895         mkdir $DIR/$tdir
16896         [[ $? -eq 0 ]] || error "mkdir failed"
16897
16898         #define OBD_FAIL_LLITE_CREATE_NODE_PAUSE 0x140c | OBD_FAIL_ONCE
16899         $LCTL set_param fail_loc=0x8000140c
16900         # 5s pause
16901         $LCTL set_param fail_val=5
16902
16903         # create file
16904         echo foofoo > $DIR/$tdir/$tfile &
16905         pid=$!
16906
16907         # wait for create to be delayed
16908         sleep 2
16909
16910         ps -p $pid
16911         [[ $? -eq 0 ]] || error "create should be blocked"
16912
16913         local tempfile="$(mktemp --tmpdir $tfile.XXXXXX)"
16914         stack_trap "rm -f $tempfile"
16915         fid=$(changelog_extract_field "CREAT" "$tfile" "t=")
16916         cat $MOUNT/.lustre/fid/$fid 2>/dev/null >$tempfile || error "cat failed"
16917         # some delay may occur during ChangeLog publishing and file read just
16918         # above, that could allow file write to happen finally
16919         [[ -s $tempfile ]] && echo "file should be empty"
16920
16921         $LCTL set_param fail_loc=0
16922
16923         wait $pid
16924         [[ $? -eq 0 ]] || error "create failed"
16925 }
16926 run_test 161d "create with concurrent .lustre/fid access"
16927
16928 check_path() {
16929         local expected="$1"
16930         shift
16931         local fid="$2"
16932
16933         local path
16934         path=$($LFS fid2path "$@")
16935         local rc=$?
16936
16937         if [ $rc -ne 0 ]; then
16938                 error "path looked up of '$expected' failed: rc=$rc"
16939         elif [ "$path" != "$expected" ]; then
16940                 error "path looked up '$path' instead of '$expected'"
16941         else
16942                 echo "FID '$fid' resolves to path '$path' as expected"
16943         fi
16944 }
16945
16946 test_162a() { # was test_162
16947         test_mkdir -p -c1 $DIR/$tdir/d2
16948         touch $DIR/$tdir/d2/$tfile
16949         touch $DIR/$tdir/d2/x1
16950         touch $DIR/$tdir/d2/x2
16951         test_mkdir -p -c1 $DIR/$tdir/d2/a/b/c
16952         test_mkdir -p -c1 $DIR/$tdir/d2/p/q/r
16953         # regular file
16954         local fid=$($LFS path2fid $DIR/$tdir/d2/$tfile | tr -d '[]')
16955         check_path "$tdir/d2/$tfile" $FSNAME "$fid" --link 0
16956
16957         # softlink
16958         ln -s $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/p/q/r/slink
16959         fid=$($LFS path2fid $DIR/$tdir/d2/p/q/r/slink | tr -d '[]')
16960         check_path "$tdir/d2/p/q/r/slink" $FSNAME "$fid" --link 0
16961
16962         # softlink to wrong file
16963         ln -s /this/is/garbage $DIR/$tdir/d2/p/q/r/slink.wrong
16964         fid=$($LFS path2fid $DIR/$tdir/d2/p/q/r/slink.wrong | tr -d '[]')
16965         check_path "$tdir/d2/p/q/r/slink.wrong" $FSNAME "$fid" --link 0
16966
16967         # hardlink
16968         ln $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/p/q/r/hlink
16969         mv $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/a/b/c/new_file
16970         fid=$($LFS path2fid $DIR/$tdir/d2/a/b/c/new_file | tr -d '[]')
16971         # fid2path dir/fsname should both work
16972         check_path "$tdir/d2/a/b/c/new_file" $FSNAME "$fid" --link 1
16973         check_path "$DIR/$tdir/d2/p/q/r/hlink" $DIR "$fid" --link 0
16974
16975         # hardlink count: check that there are 2 links
16976         local nlinks=$($LFS fid2path $DIR "$fid" | wc -l)
16977         [ $nlinks -eq 2 ] || error "expect 2 links, found $nlinks"
16978
16979         # hardlink indexing: remove the first link
16980         rm $DIR/$tdir/d2/p/q/r/hlink
16981         check_path "$tdir/d2/a/b/c/new_file" $FSNAME $fid --link 0
16982 }
16983 run_test 162a "path lookup sanity"
16984
16985 test_162b() {
16986         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16987         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
16988
16989         mkdir $DIR/$tdir
16990         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
16991                                 error "create striped dir failed"
16992
16993         local FID=$($LFS getdirstripe $DIR/$tdir/striped_dir |
16994                                         tail -n 1 | awk '{print $2}')
16995         stat $MOUNT/.lustre/fid/$FID && error "sub_stripe can be accessed"
16996
16997         touch $DIR/$tdir/striped_dir/f{0..4} || error "touch f0..4 failed"
16998         mkdir $DIR/$tdir/striped_dir/d{0..4} || error "mkdir d0..4 failed"
16999
17000         # regular file
17001         for ((i=0;i<5;i++)); do
17002                 FID=$($LFS path2fid $DIR/$tdir/striped_dir/f$i | tr -d '[]') ||
17003                         error "get fid for f$i failed"
17004                 check_path "$tdir/striped_dir/f$i" $FSNAME $FID --link 0
17005
17006                 FID=$($LFS path2fid $DIR/$tdir/striped_dir/d$i | tr -d '[]') ||
17007                         error "get fid for d$i failed"
17008                 check_path "$tdir/striped_dir/d$i" $FSNAME $FID --link 0
17009         done
17010
17011         return 0
17012 }
17013 run_test 162b "striped directory path lookup sanity"
17014
17015 # LU-4239: Verify fid2path works with paths 100 or more directories deep
17016 test_162c() {
17017         [[ $MDS1_VERSION -lt $(version_code 2.7.51) ]] &&
17018                 skip "Need MDS version at least 2.7.51"
17019
17020         local lpath=$tdir.local
17021         local rpath=$tdir.remote
17022
17023         test_mkdir $DIR/$lpath
17024         test_mkdir $DIR/$rpath
17025
17026         for ((i = 0; i <= 101; i++)); do
17027                 lpath="$lpath/$i"
17028                 mkdir $DIR/$lpath
17029                 FID=$($LFS path2fid $DIR/$lpath | tr -d '[]') ||
17030                         error "get fid for local directory $DIR/$lpath failed"
17031                 check_path "$DIR/$lpath" $MOUNT $FID --link 0
17032
17033                 rpath="$rpath/$i"
17034                 test_mkdir $DIR/$rpath
17035                 FID=$($LFS path2fid $DIR/$rpath | tr -d '[]') ||
17036                         error "get fid for remote directory $DIR/$rpath failed"
17037                 check_path "$DIR/$rpath" $MOUNT $FID --link 0
17038         done
17039
17040         return 0
17041 }
17042 run_test 162c "fid2path works with paths 100 or more directories deep"
17043
17044 oalr_event_count() {
17045         local event="${1}"
17046         local trace="${2}"
17047
17048         awk -v name="${FSNAME}-OST0000" \
17049             -v event="${event}" \
17050             '$1 == "TRACE" && $2 == event && $3 == name' \
17051             "${trace}" |
17052         wc -l
17053 }
17054
17055 oalr_expect_event_count() {
17056         local event="${1}"
17057         local trace="${2}"
17058         local expect="${3}"
17059         local count
17060
17061         count=$(oalr_event_count "${event}" "${trace}")
17062         if ((count == expect)); then
17063                 return 0
17064         fi
17065
17066         error_noexit "${event} event count was '${count}', expected ${expect}"
17067         cat "${trace}" >&2
17068         exit 1
17069 }
17070
17071 cleanup_165() {
17072         do_facet ost1 killall --quiet -KILL ofd_access_log_reader || true
17073         stop ost1
17074         start ost1 "$(ostdevname 1)" $OST_MOUNT_OPTS
17075 }
17076
17077 setup_165() {
17078         sync # Flush previous IOs so we can count log entries.
17079         do_facet ost1 $LCTL set_param "obdfilter.${FSNAME}-OST0000.access_log_size=4096"
17080         stack_trap cleanup_165 EXIT
17081 }
17082
17083 test_165a() {
17084         local trace="/tmp/${tfile}.trace"
17085         local rc
17086         local count
17087
17088         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
17089                 skip "OFD access log unsupported"
17090
17091         setup_165
17092         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
17093         sleep 5
17094
17095         do_facet ost1 ofd_access_log_reader --list
17096         stop ost1
17097
17098         do_facet ost1 killall -TERM ofd_access_log_reader
17099         wait
17100         rc=$?
17101
17102         if ((rc != 0)); then
17103                 error "ofd_access_log_reader exited with rc = '${rc}'"
17104         fi
17105
17106         # Parse trace file for discovery events:
17107         oalr_expect_event_count alr_log_add "${trace}" 1
17108         oalr_expect_event_count alr_log_eof "${trace}" 1
17109         oalr_expect_event_count alr_log_free "${trace}" 1
17110 }
17111 run_test 165a "ofd access log discovery"
17112
17113 test_165b() {
17114         local trace="/tmp/${tfile}.trace"
17115         local file="${DIR}/${tfile}"
17116         local pfid1
17117         local pfid2
17118         local -a entry
17119         local rc
17120         local count
17121         local size
17122         local flags
17123
17124         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
17125                 skip "OFD access log unsupported"
17126
17127         setup_165
17128         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
17129         sleep 5
17130
17131         do_facet ost1 ofd_access_log_reader --list
17132
17133         lfs setstripe -c 1 -i 0 "${file}"
17134         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
17135                 error "cannot create '${file}'"
17136
17137         sleep 5
17138         do_facet ost1 killall -TERM ofd_access_log_reader
17139         wait
17140         rc=$?
17141
17142         if ((rc != 0)); then
17143                 error "ofd_access_log_reader exited with rc = '${rc}'"
17144         fi
17145
17146         oalr_expect_event_count alr_log_entry "${trace}" 1
17147
17148         pfid1=$($LFS path2fid "${file}")
17149
17150         # 1     2             3   4    5     6   7    8    9     10
17151         # TRACE alr_log_entry OST PFID BEGIN END TIME SIZE COUNT FLAGS
17152         entry=( - $(awk -v pfid="${pfid}" '$1 == "TRACE" && $2 == "alr_log_entry"' "${trace}" ) )
17153
17154         echo "entry = '${entry[*]}'" >&2
17155
17156         pfid2=${entry[4]}
17157         if [[ "${pfid1}" != "${pfid2}" ]]; then
17158                 error "entry '${entry[*]}' has invalid PFID '${pfid2}', expected ${pfid1}"
17159         fi
17160
17161         size=${entry[8]}
17162         if ((size != 1048576)); then
17163                 error "entry '${entry[*]}' has invalid io size '${size}', expected 1048576"
17164         fi
17165
17166         flags=${entry[10]}
17167         if [[ "${flags}" != "w" ]]; then
17168                 error "entry '${entry[*]}' has invalid io flags '${flags}', expected 'w'"
17169         fi
17170
17171         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
17172         sleep 5
17173
17174         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r524288c ||
17175                 error "cannot read '${file}'"
17176         sleep 5
17177
17178         do_facet ost1 killall -TERM ofd_access_log_reader
17179         wait
17180         rc=$?
17181
17182         if ((rc != 0)); then
17183                 error "ofd_access_log_reader exited with rc = '${rc}'"
17184         fi
17185
17186         oalr_expect_event_count alr_log_entry "${trace}" 1
17187
17188         entry=( - $(awk -v pfid="${pfid}" '$1 == "TRACE" && $2 == "alr_log_entry"' "${trace}" ) )
17189         echo "entry = '${entry[*]}'" >&2
17190
17191         pfid2=${entry[4]}
17192         if [[ "${pfid1}" != "${pfid2}" ]]; then
17193                 error "entry '${entry[*]}' has invalid PFID '${pfid2}', expected ${pfid1}"
17194         fi
17195
17196         size=${entry[8]}
17197         if ((size != 524288)); then
17198                 error "entry '${entry[*]}' has invalid io size '${size}', 524288"
17199         fi
17200
17201         flags=${entry[10]}
17202         if [[ "${flags}" != "r" ]]; then
17203                 error "entry '${entry[*]}' has invalid io flags '${flags}', expected 'r'"
17204         fi
17205 }
17206 run_test 165b "ofd access log entries are produced and consumed"
17207
17208 test_165c() {
17209         local trace="/tmp/${tfile}.trace"
17210         local file="${DIR}/${tdir}/${tfile}"
17211
17212         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
17213                 skip "OFD access log unsupported"
17214
17215         test_mkdir "${DIR}/${tdir}"
17216
17217         setup_165
17218         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
17219         sleep 5
17220
17221         lfs setstripe -c 1 -i 0 "${DIR}/${tdir}"
17222
17223         # 4096 / 64 = 64. Create twice as many entries.
17224         for ((i = 0; i < 128; i++)); do
17225                 $MULTIOP "${file}-${i}" oO_CREAT:O_WRONLY:w512c ||
17226                         error "cannot create file"
17227         done
17228
17229         sync
17230
17231         do_facet ost1 killall -TERM ofd_access_log_reader
17232         wait
17233         rc=$?
17234         if ((rc != 0)); then
17235                 error "ofd_access_log_reader exited with rc = '${rc}'"
17236         fi
17237
17238         unlinkmany  "${file}-%d" 128
17239 }
17240 run_test 165c "full ofd access logs do not block IOs"
17241
17242 oal_get_read_count() {
17243         local stats="$1"
17244
17245         # STATS lustre-OST0001 alr_read_count 1
17246
17247         do_facet ost1 cat "${stats}" |
17248         awk '$1 == "STATS" && $3 == "alr_read_count" { count = $4; }
17249              END { print count; }'
17250 }
17251
17252 oal_expect_read_count() {
17253         local stats="$1"
17254         local count
17255         local expect="$2"
17256
17257         # Ask ofd_access_log_reader to write stats.
17258         do_facet ost1 killall -USR1 ofd_access_log_reader
17259
17260         # Allow some time for things to happen.
17261         sleep 1
17262
17263         count=$(oal_get_read_count "${stats}")
17264         if ((count == expect)); then
17265                 return 0
17266         fi
17267
17268         error_noexit "bad read count, got ${count}, expected ${expect}"
17269         do_facet ost1 cat "${stats}" >&2
17270         exit 1
17271 }
17272
17273 test_165d() {
17274         local stats="/tmp/${tfile}.stats"
17275         local file="${DIR}/${tdir}/${tfile}"
17276         local param="obdfilter.${FSNAME}-OST0000.access_log_mask"
17277
17278         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
17279                 skip "OFD access log unsupported"
17280
17281         test_mkdir "${DIR}/${tdir}"
17282
17283         setup_165
17284         do_facet ost1 ofd_access_log_reader --stats="${stats}" &
17285         sleep 5
17286
17287         lfs setstripe -c 1 -i 0 "${file}"
17288
17289         do_facet ost1 lctl set_param "${param}=rw"
17290         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
17291                 error "cannot create '${file}'"
17292         oal_expect_read_count "${stats}" 1
17293
17294         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
17295                 error "cannot read '${file}'"
17296         oal_expect_read_count "${stats}" 2
17297
17298         do_facet ost1 lctl set_param "${param}=r"
17299         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
17300                 error "cannot create '${file}'"
17301         oal_expect_read_count "${stats}" 2
17302
17303         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
17304                 error "cannot read '${file}'"
17305         oal_expect_read_count "${stats}" 3
17306
17307         do_facet ost1 lctl set_param "${param}=w"
17308         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
17309                 error "cannot create '${file}'"
17310         oal_expect_read_count "${stats}" 4
17311
17312         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
17313                 error "cannot read '${file}'"
17314         oal_expect_read_count "${stats}" 4
17315
17316         do_facet ost1 lctl set_param "${param}=0"
17317         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
17318                 error "cannot create '${file}'"
17319         oal_expect_read_count "${stats}" 4
17320
17321         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
17322                 error "cannot read '${file}'"
17323         oal_expect_read_count "${stats}" 4
17324
17325         do_facet ost1 killall -TERM ofd_access_log_reader
17326         wait
17327         rc=$?
17328         if ((rc != 0)); then
17329                 error "ofd_access_log_reader exited with rc = '${rc}'"
17330         fi
17331 }
17332 run_test 165d "ofd_access_log mask works"
17333
17334 test_165e() {
17335         local stats="/tmp/${tfile}.stats"
17336         local file0="${DIR}/${tdir}-0/${tfile}"
17337         local file1="${DIR}/${tdir}-1/${tfile}"
17338
17339         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
17340                 skip "OFD access log unsupported"
17341
17342         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
17343
17344         test_mkdir -c 1 -i 0 "${DIR}/${tdir}-0"
17345         test_mkdir -c 1 -i 1 "${DIR}/${tdir}-1"
17346
17347         lfs setstripe -c 1 -i 0 "${file0}"
17348         lfs setstripe -c 1 -i 0 "${file1}"
17349
17350         setup_165
17351         do_facet ost1 ofd_access_log_reader -I 1 --stats="${stats}" &
17352         sleep 5
17353
17354         $MULTIOP "${file0}" oO_CREAT:O_WRONLY:w512c ||
17355                 error "cannot create '${file0}'"
17356         sync
17357         oal_expect_read_count "${stats}" 0
17358
17359         $MULTIOP "${file1}" oO_CREAT:O_WRONLY:w512c ||
17360                 error "cannot create '${file1}'"
17361         sync
17362         oal_expect_read_count "${stats}" 1
17363
17364         do_facet ost1 killall -TERM ofd_access_log_reader
17365         wait
17366         rc=$?
17367         if ((rc != 0)); then
17368                 error "ofd_access_log_reader exited with rc = '${rc}'"
17369         fi
17370 }
17371 run_test 165e "ofd_access_log MDT index filter works"
17372
17373 test_165f() {
17374         local trace="/tmp/${tfile}.trace"
17375         local rc
17376         local count
17377
17378         setup_165
17379         do_facet ost1 timeout 60 ofd_access_log_reader \
17380                 --exit-on-close --debug=- --trace=- > "${trace}" &
17381         sleep 5
17382         stop ost1
17383
17384         wait
17385         rc=$?
17386
17387         if ((rc != 0)); then
17388                 error_noexit "ofd_access_log_reader exited with rc = '${rc}'"
17389                 cat "${trace}"
17390                 exit 1
17391         fi
17392 }
17393 run_test 165f "ofd_access_log_reader --exit-on-close works"
17394
17395 test_169() {
17396         # do directio so as not to populate the page cache
17397         log "creating a 10 Mb file"
17398         $MULTIOP $DIR/$tfile oO_CREAT:O_DIRECT:O_RDWR:w$((10*1048576))c ||
17399                 error "multiop failed while creating a file"
17400         log "starting reads"
17401         dd if=$DIR/$tfile of=/dev/null bs=4096 &
17402         log "truncating the file"
17403         $MULTIOP $DIR/$tfile oO_TRUNC:c ||
17404                 error "multiop failed while truncating the file"
17405         log "killing dd"
17406         kill %+ || true # reads might have finished
17407         echo "wait until dd is finished"
17408         wait
17409         log "removing the temporary file"
17410         rm -rf $DIR/$tfile || error "tmp file removal failed"
17411 }
17412 run_test 169 "parallel read and truncate should not deadlock"
17413
17414 test_170() {
17415         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17416
17417         $LCTL clear     # bug 18514
17418         $LCTL debug_daemon start $TMP/${tfile}_log_good
17419         touch $DIR/$tfile
17420         $LCTL debug_daemon stop
17421         sed -e "s/^...../a/g" $TMP/${tfile}_log_good > $TMP/${tfile}_log_bad ||
17422                 error "sed failed to read log_good"
17423
17424         $LCTL debug_daemon start $TMP/${tfile}_log_good
17425         rm -rf $DIR/$tfile
17426         $LCTL debug_daemon stop
17427
17428         $LCTL df $TMP/${tfile}_log_bad > $TMP/${tfile}_log_bad.out 2>&1 ||
17429                error "lctl df log_bad failed"
17430
17431         local bad_line=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $9}')
17432         local good_line1=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $5}')
17433
17434         $LCTL df $TMP/${tfile}_log_good > $TMP/${tfile}_log_good.out 2>&1
17435         local good_line2=$(tail -n 1 $TMP/${tfile}_log_good.out | awk '{print $5}')
17436
17437         [ "$bad_line" ] && [ "$good_line1" ] && [ "$good_line2" ] ||
17438                 error "bad_line good_line1 good_line2 are empty"
17439
17440         cat $TMP/${tfile}_log_good >> $TMP/${tfile}_logs_corrupt
17441         cat $TMP/${tfile}_log_bad >> $TMP/${tfile}_logs_corrupt
17442         cat $TMP/${tfile}_log_good >> $TMP/${tfile}_logs_corrupt
17443
17444         $LCTL df $TMP/${tfile}_logs_corrupt > $TMP/${tfile}_log_bad.out 2>&1
17445         local bad_line_new=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $9}')
17446         local good_line_new=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $5}')
17447
17448         [ "$bad_line_new" ] && [ "$good_line_new" ] ||
17449                 error "bad_line_new good_line_new are empty"
17450
17451         local expected_good=$((good_line1 + good_line2*2))
17452
17453         rm -f $TMP/${tfile}*
17454         # LU-231, short malformed line may not be counted into bad lines
17455         if [ $bad_line -ne $bad_line_new ] &&
17456                    [ $bad_line -ne $((bad_line_new - 1)) ]; then
17457                 error "expected $bad_line bad lines, but got $bad_line_new"
17458                 return 1
17459         fi
17460
17461         if [ $expected_good -ne $good_line_new ]; then
17462                 error "expected $expected_good good lines, but got $good_line_new"
17463                 return 2
17464         fi
17465         true
17466 }
17467 run_test 170 "test lctl df to handle corrupted log ====================="
17468
17469 test_171() { # bug20592
17470         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17471
17472         #define OBD_FAIL_PTLRPC_DUMP_LOG         0x50e
17473         $LCTL set_param fail_loc=0x50e
17474         $LCTL set_param fail_val=3000
17475         multiop_bg_pause $DIR/$tfile O_s || true
17476         local MULTIPID=$!
17477         kill -USR1 $MULTIPID
17478         # cause log dump
17479         sleep 3
17480         wait $MULTIPID
17481         if dmesg | grep "recursive fault"; then
17482                 error "caught a recursive fault"
17483         fi
17484         $LCTL set_param fail_loc=0
17485         true
17486 }
17487 run_test 171 "test libcfs_debug_dumplog_thread stuck in do_exit() ======"
17488
17489 # it would be good to share it with obdfilter-survey/iokit-libecho code
17490 setup_obdecho_osc () {
17491         local rc=0
17492         local ost_nid=$1
17493         local obdfilter_name=$2
17494         echo "Creating new osc for $obdfilter_name on $ost_nid"
17495         # make sure we can find loopback nid
17496         $LCTL add_uuid $ost_nid $ost_nid >/dev/null 2>&1
17497
17498         [ $rc -eq 0 ] && { $LCTL attach osc ${obdfilter_name}_osc     \
17499                            ${obdfilter_name}_osc_UUID || rc=2; }
17500         [ $rc -eq 0 ] && { $LCTL --device ${obdfilter_name}_osc setup \
17501                            ${obdfilter_name}_UUID  $ost_nid || rc=3; }
17502         return $rc
17503 }
17504
17505 cleanup_obdecho_osc () {
17506         local obdfilter_name=$1
17507         $LCTL --device ${obdfilter_name}_osc cleanup >/dev/null
17508         $LCTL --device ${obdfilter_name}_osc detach  >/dev/null
17509         return 0
17510 }
17511
17512 obdecho_test() {
17513         local OBD=$1
17514         local node=$2
17515         local pages=${3:-64}
17516         local rc=0
17517         local id
17518
17519         local count=10
17520         local obd_size=$(get_obd_size $node $OBD)
17521         local page_size=$(get_page_size $node)
17522         if [[ -n "$obd_size" ]]; then
17523                 local new_count=$((obd_size / (pages * page_size / 1024)))
17524                 [[ $new_count -ge $count ]] || count=$new_count
17525         fi
17526
17527         do_facet $node "$LCTL attach echo_client ec ec_uuid" || rc=1
17528         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec setup $OBD" ||
17529                            rc=2; }
17530         if [ $rc -eq 0 ]; then
17531             id=$(do_facet $node "$LCTL --device ec create 1"  | awk '/object id/ {print $6}')
17532             [ ${PIPESTATUS[0]} -eq 0 -a -n "$id" ] || rc=3
17533         fi
17534         echo "New object id is $id"
17535         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec getattr $id" ||
17536                            rc=4; }
17537         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec "                 \
17538                            "test_brw $count w v $pages $id" || rc=4; }
17539         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec destroy $id 1" ||
17540                            rc=4; }
17541         [ $rc -eq 0 ] || [ $rc -gt 2 ] &&
17542                 { do_facet $node "$LCTL --device ec cleanup" || rc=5; }
17543         [ $rc -eq 0 ] || [ $rc -gt 1 ] &&
17544                 { do_facet $node "$LCTL --device ec detach" || rc=6; }
17545         [ $rc -ne 0 ] && echo "obecho_create_test failed: $rc"
17546         return $rc
17547 }
17548
17549 test_180a() {
17550         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17551
17552         if ! [ -d /sys/fs/lustre/echo_client ] &&
17553            ! module_loaded obdecho; then
17554                 load_module obdecho/obdecho &&
17555                         stack_trap "rmmod obdecho" EXIT ||
17556                         error "unable to load obdecho on client"
17557         fi
17558
17559         local osc=$($LCTL dl | grep -v mdt | awk '$3 == "osc" {print $4; exit}')
17560         local host=$($LCTL get_param -n osc.$osc.import |
17561                      awk '/current_connection:/ { print $2 }' )
17562         local target=$($LCTL get_param -n osc.$osc.import |
17563                        awk '/target:/ { print $2 }' )
17564         target=${target%_UUID}
17565
17566         if [ -n "$target" ]; then
17567                 setup_obdecho_osc $host $target &&
17568                         stack_trap "cleanup_obdecho_osc $target" EXIT ||
17569                         { error "obdecho setup failed with $?"; return; }
17570
17571                 obdecho_test ${target}_osc client ||
17572                         error "obdecho_test failed on ${target}_osc"
17573         else
17574                 $LCTL get_param osc.$osc.import
17575                 error "there is no osc.$osc.import target"
17576         fi
17577 }
17578 run_test 180a "test obdecho on osc"
17579
17580 test_180b() {
17581         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17582         remote_ost_nodsh && skip "remote OST with nodsh"
17583
17584         do_rpc_nodes $(facet_active_host ost1) load_module obdecho/obdecho &&
17585                 stack_trap "do_facet ost1 rmmod obdecho" EXIT ||
17586                 error "failed to load module obdecho"
17587
17588         local target=$(do_facet ost1 $LCTL dl |
17589                        awk '/obdfilter/ { print $4; exit; }')
17590
17591         if [ -n "$target" ]; then
17592                 obdecho_test $target ost1 || error "obdecho_test failed with $?"
17593         else
17594                 do_facet ost1 $LCTL dl
17595                 error "there is no obdfilter target on ost1"
17596         fi
17597 }
17598 run_test 180b "test obdecho directly on obdfilter"
17599
17600 test_180c() { # LU-2598
17601         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17602         remote_ost_nodsh && skip "remote OST with nodsh"
17603         [[ $MDS1_VERSION -lt $(version_code 2.4.0) ]] &&
17604                 skip "Need MDS version at least 2.4.0"
17605
17606         do_rpc_nodes $(facet_active_host ost1) load_module obdecho/obdecho &&
17607                 stack_trap "do_facet ost1 rmmod obdecho" EXIT ||
17608                 error "failed to load module obdecho"
17609
17610         local target=$(do_facet ost1 $LCTL dl |
17611                        awk '/obdfilter/ { print $4; exit; }')
17612
17613         if [ -n "$target" ]; then
17614                 local pages=16384 # 64MB bulk I/O RPC size
17615
17616                 obdecho_test "$target" ost1 "$pages" ||
17617                         error "obdecho_test with pages=$pages failed with $?"
17618         else
17619                 do_facet ost1 $LCTL dl
17620                 error "there is no obdfilter target on ost1"
17621         fi
17622 }
17623 run_test 180c "test huge bulk I/O size on obdfilter, don't LASSERT"
17624
17625 test_181() { # bug 22177
17626         test_mkdir $DIR/$tdir
17627         # create enough files to index the directory
17628         createmany -o $DIR/$tdir/foobar 4000
17629         # print attributes for debug purpose
17630         lsattr -d .
17631         # open dir
17632         multiop_bg_pause $DIR/$tdir D_Sc || return 1
17633         MULTIPID=$!
17634         # remove the files & current working dir
17635         unlinkmany $DIR/$tdir/foobar 4000
17636         rmdir $DIR/$tdir
17637         kill -USR1 $MULTIPID
17638         wait $MULTIPID
17639         stat $DIR/$tdir && error "open-unlinked dir was not removed!"
17640         return 0
17641 }
17642 run_test 181 "Test open-unlinked dir ========================"
17643
17644 test_182() {
17645         local fcount=1000
17646         local tcount=10
17647
17648         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
17649
17650         $LCTL set_param mdc.*.rpc_stats=clear
17651
17652         for (( i = 0; i < $tcount; i++ )) ; do
17653                 mkdir $DIR/$tdir/$i
17654         done
17655
17656         for (( i = 0; i < $tcount; i++ )) ; do
17657                 createmany -o $DIR/$tdir/$i/f- $fcount &
17658         done
17659         wait
17660
17661         for (( i = 0; i < $tcount; i++ )) ; do
17662                 unlinkmany $DIR/$tdir/$i/f- $fcount &
17663         done
17664         wait
17665
17666         $LCTL get_param mdc.*.rpc_stats
17667
17668         rm -rf $DIR/$tdir
17669 }
17670 run_test 182 "Test parallel modify metadata operations ================"
17671
17672 test_183() { # LU-2275
17673         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17674         remote_mds_nodsh && skip "remote MDS with nodsh"
17675         [[ $MDS1_VERSION -lt $(version_code 2.3.56) ]] &&
17676                 skip "Need MDS version at least 2.3.56"
17677
17678         mkdir_on_mdt0 $DIR/$tdir || error "creating dir $DIR/$tdir"
17679         echo aaa > $DIR/$tdir/$tfile
17680
17681 #define OBD_FAIL_MDS_NEGATIVE_POSITIVE  0x148
17682         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x148
17683
17684         ls -l $DIR/$tdir && error "ls succeeded, should have failed"
17685         cat $DIR/$tdir/$tfile && error "cat succeeded, should have failed"
17686
17687         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
17688
17689         # Flush negative dentry cache
17690         touch $DIR/$tdir/$tfile
17691
17692         # We are not checking for any leaked references here, they'll
17693         # become evident next time we do cleanup with module unload.
17694         rm -rf $DIR/$tdir
17695 }
17696 run_test 183 "No crash or request leak in case of strange dispositions ========"
17697
17698 # test suite 184 is for LU-2016, LU-2017
17699 test_184a() {
17700         check_swap_layouts_support
17701
17702         dir0=$DIR/$tdir/$testnum
17703         test_mkdir -p -c1 $dir0
17704         ref1=/etc/passwd
17705         ref2=/etc/group
17706         file1=$dir0/f1
17707         file2=$dir0/f2
17708         $LFS setstripe -c1 $file1
17709         cp $ref1 $file1
17710         $LFS setstripe -c2 $file2
17711         cp $ref2 $file2
17712         gen1=$($LFS getstripe -g $file1)
17713         gen2=$($LFS getstripe -g $file2)
17714
17715         $LFS swap_layouts $file1 $file2 || error "swap of file layout failed"
17716         gen=$($LFS getstripe -g $file1)
17717         [[ $gen1 != $gen ]] ||
17718                 "Layout generation on $file1 does not change"
17719         gen=$($LFS getstripe -g $file2)
17720         [[ $gen2 != $gen ]] ||
17721                 "Layout generation on $file2 does not change"
17722
17723         cmp $ref1 $file2 || error "content compare failed ($ref1 != $file2)"
17724         cmp $ref2 $file1 || error "content compare failed ($ref2 != $file1)"
17725
17726         lfsck_verify_pfid $file1 $file2 || error "PFID are not transferred"
17727 }
17728 run_test 184a "Basic layout swap"
17729
17730 test_184b() {
17731         check_swap_layouts_support
17732
17733         dir0=$DIR/$tdir/$testnum
17734         mkdir -p $dir0 || error "creating dir $dir0"
17735         file1=$dir0/f1
17736         file2=$dir0/f2
17737         file3=$dir0/f3
17738         dir1=$dir0/d1
17739         dir2=$dir0/d2
17740         mkdir $dir1 $dir2
17741         $LFS setstripe -c1 $file1
17742         $LFS setstripe -c2 $file2
17743         $LFS setstripe -c1 $file3
17744         chown $RUNAS_ID $file3
17745         gen1=$($LFS getstripe -g $file1)
17746         gen2=$($LFS getstripe -g $file2)
17747
17748         $LFS swap_layouts $dir1 $dir2 &&
17749                 error "swap of directories layouts should fail"
17750         $LFS swap_layouts $dir1 $file1 &&
17751                 error "swap of directory and file layouts should fail"
17752         $RUNAS $LFS swap_layouts $file1 $file2 &&
17753                 error "swap of file we cannot write should fail"
17754         $LFS swap_layouts $file1 $file3 &&
17755                 error "swap of file with different owner should fail"
17756         /bin/true # to clear error code
17757 }
17758 run_test 184b "Forbidden layout swap (will generate errors)"
17759
17760 test_184c() {
17761         local cmpn_arg=$(cmp -n 2>&1 | grep "invalid option")
17762         [ -n "$cmpn_arg" ] && skip_env "cmp does not support -n"
17763         check_swap_layouts_support
17764         check_swap_layout_no_dom $DIR
17765
17766         local dir0=$DIR/$tdir/$testnum
17767         mkdir -p $dir0 || error "creating dir $dir0"
17768
17769         local ref1=$dir0/ref1
17770         local ref2=$dir0/ref2
17771         local file1=$dir0/file1
17772         local file2=$dir0/file2
17773         # create a file large enough for the concurrent test
17774         dd if=/dev/urandom of=$ref1 bs=1M count=$((RANDOM % 50 + 20))
17775         dd if=/dev/urandom of=$ref2 bs=1M count=$((RANDOM % 50 + 20))
17776         echo "ref file size: ref1($(stat -c %s $ref1))," \
17777              "ref2($(stat -c %s $ref2))"
17778
17779         cp $ref2 $file2
17780         dd if=$ref1 of=$file1 bs=16k &
17781         local DD_PID=$!
17782
17783         # Make sure dd starts to copy file, but wait at most 5 seconds
17784         local loops=0
17785         while [ ! -s $file1 -a $((loops++)) -lt 50 ]; do sleep 0.1; done
17786
17787         $LFS swap_layouts $file1 $file2
17788         local rc=$?
17789         wait $DD_PID
17790         [[ $? == 0 ]] || error "concurrent write on $file1 failed"
17791         [[ $rc == 0 ]] || error "swap of $file1 and $file2 failed"
17792
17793         # how many bytes copied before swapping layout
17794         local copied=$(stat -c %s $file2)
17795         local remaining=$(stat -c %s $ref1)
17796         remaining=$((remaining - copied))
17797         echo "Copied $copied bytes before swapping layout..."
17798
17799         cmp -n $copied $file1 $ref2 | grep differ &&
17800                 error "Content mismatch [0, $copied) of ref2 and file1"
17801         cmp -n $copied $file2 $ref1 ||
17802                 error "Content mismatch [0, $copied) of ref1 and file2"
17803         cmp -i $copied:$copied -n $remaining $file1 $ref1 ||
17804                 error "Content mismatch [$copied, EOF) of ref1 and file1"
17805
17806         # clean up
17807         rm -f $ref1 $ref2 $file1 $file2
17808 }
17809 run_test 184c "Concurrent write and layout swap"
17810
17811 test_184d() {
17812         check_swap_layouts_support
17813         check_swap_layout_no_dom $DIR
17814         [ -z "$(which getfattr 2>/dev/null)" ] &&
17815                 skip_env "no getfattr command"
17816
17817         local file1=$DIR/$tdir/$tfile-1
17818         local file2=$DIR/$tdir/$tfile-2
17819         local file3=$DIR/$tdir/$tfile-3
17820         local lovea1
17821         local lovea2
17822
17823         mkdir -p $DIR/$tdir
17824         touch $file1 || error "create $file1 failed"
17825         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file2 ||
17826                 error "create $file2 failed"
17827         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file3 ||
17828                 error "create $file3 failed"
17829         lovea1=$(get_layout_param $file1)
17830
17831         $LFS swap_layouts $file2 $file3 ||
17832                 error "swap $file2 $file3 layouts failed"
17833         $LFS swap_layouts $file1 $file2 ||
17834                 error "swap $file1 $file2 layouts failed"
17835
17836         lovea2=$(get_layout_param $file2)
17837         echo "$lovea1"
17838         echo "$lovea2"
17839         [ "$lovea1" == "$lovea2" ] || error "lovea $lovea1 != $lovea2"
17840
17841         lovea1=$(getfattr -n trusted.lov $file1 | grep ^trusted)
17842         [[ -z "$lovea1" ]] || error "$file1 shouldn't have lovea"
17843 }
17844 run_test 184d "allow stripeless layouts swap"
17845
17846 test_184e() {
17847         [[ $MDS1_VERSION -ge $(version_code 2.6.94) ]] ||
17848                 skip "Need MDS version at least 2.6.94"
17849         check_swap_layouts_support
17850         check_swap_layout_no_dom $DIR
17851         [ -z "$(which getfattr 2>/dev/null)" ] &&
17852                 skip_env "no getfattr command"
17853
17854         local file1=$DIR/$tdir/$tfile-1
17855         local file2=$DIR/$tdir/$tfile-2
17856         local file3=$DIR/$tdir/$tfile-3
17857         local lovea
17858
17859         mkdir -p $DIR/$tdir
17860         touch $file1 || error "create $file1 failed"
17861         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file2 ||
17862                 error "create $file2 failed"
17863         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file3 ||
17864                 error "create $file3 failed"
17865
17866         $LFS swap_layouts $file1 $file2 ||
17867                 error "swap $file1 $file2 layouts failed"
17868
17869         lovea=$(getfattr -n trusted.lov $file1 | grep ^trusted)
17870         [[ -z "$lovea" ]] || error "$file1 shouldn't have lovea"
17871
17872         echo 123 > $file1 || error "Should be able to write into $file1"
17873
17874         $LFS swap_layouts $file1 $file3 ||
17875                 error "swap $file1 $file3 layouts failed"
17876
17877         echo 123 > $file1 || error "Should be able to write into $file1"
17878
17879         rm -rf $file1 $file2 $file3
17880 }
17881 run_test 184e "Recreate layout after stripeless layout swaps"
17882
17883 test_184f() {
17884         # Create a file with name longer than sizeof(struct stat) ==
17885         # 144 to see if we can get chars from the file name to appear
17886         # in the returned striping. Note that 'f' == 0x66.
17887         local file=$(for ((i = 0; i < 200; i++)); do echo -n f; done)
17888
17889         mkdir -p $DIR/$tdir
17890         mcreate $DIR/$tdir/$file
17891         if lfs find --stripe-count 0x6666 $DIR/$tdir | grep $file; then
17892                 error "IOC_MDC_GETFILEINFO returned garbage striping"
17893         fi
17894 }
17895 run_test 184f "IOC_MDC_GETFILEINFO for files with long names but no striping"
17896
17897 test_185() { # LU-2441
17898         # LU-3553 - no volatile file support in old servers
17899         [[ $MDS1_VERSION -ge $(version_code 2.3.60) ]] ||
17900                 skip "Need MDS version at least 2.3.60"
17901
17902         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
17903         touch $DIR/$tdir/spoo
17904         local mtime1=$(stat -c "%Y" $DIR/$tdir)
17905         local fid=$($MULTIOP $DIR/$tdir VFw4096c) ||
17906                 error "cannot create/write a volatile file"
17907         [ "$FILESET" == "" ] &&
17908         $CHECKSTAT -t file $MOUNT/.lustre/fid/$fid 2>/dev/null &&
17909                 error "FID is still valid after close"
17910
17911         multiop_bg_pause $DIR/$tdir vVw4096_c
17912         local multi_pid=$!
17913
17914         local OLD_IFS=$IFS
17915         IFS=":"
17916         local fidv=($fid)
17917         IFS=$OLD_IFS
17918         # assume that the next FID for this client is sequential, since stdout
17919         # is unfortunately eaten by multiop_bg_pause
17920         local n=$((${fidv[1]} + 1))
17921         local next_fid="${fidv[0]}:$(printf "0x%x" $n):${fidv[2]}"
17922         if [ "$FILESET" == "" ]; then
17923                 $CHECKSTAT -t file $MOUNT/.lustre/fid/$next_fid ||
17924                         error "FID is missing before close"
17925         fi
17926         kill -USR1 $multi_pid
17927         # 1 second delay, so if mtime change we will see it
17928         sleep 1
17929         local mtime2=$(stat -c "%Y" $DIR/$tdir)
17930         [[ $mtime1 == $mtime2 ]] || error "mtime has changed"
17931 }
17932 run_test 185 "Volatile file support"
17933
17934 function create_check_volatile() {
17935         local idx=$1
17936         local tgt
17937
17938         $MULTIOP $MOUNT/.lustre/fid V${idx}Fw4096_c >&/tmp/${tfile}.fid &
17939         local PID=$!
17940         sleep 1
17941         local FID=$(cat /tmp/${tfile}.fid)
17942         [ "$FID" == "" ] && error "can't get FID for volatile"
17943         $CHECKSTAT -t file $MOUNT/.lustre/fid/$FID || error "can't stat $FID"
17944         tgt=$($LFS getstripe -m $MOUNT/.lustre/fid/$FID)
17945         [ "$tgt" != "$idx" ] && error "wrong MDS $tgt, expected $idx"
17946         kill -USR1 $PID
17947         wait
17948         sleep 1
17949         cancel_lru_locks mdc # flush opencache
17950         $CHECKSTAT -t file $MOUNT/.lustre/fid/$FID && error "can stat $FID"
17951         return 0
17952 }
17953
17954 test_185a(){
17955         # LU-12516 - volatile creation via .lustre
17956         [[ $MDS1_VERSION -ge $(version_code 2.12.55) ]] ||
17957                 skip "Need MDS version at least 2.3.55"
17958
17959         create_check_volatile 0
17960         [ $MDSCOUNT -lt 2 ] && return 0
17961
17962         # DNE case
17963         create_check_volatile 1
17964
17965         return 0
17966 }
17967 run_test 185a "Volatile file creation in .lustre/fid/"
17968
17969 test_187a() {
17970         remote_mds_nodsh && skip "remote MDS with nodsh"
17971         [ $MDS1_VERSION -lt $(version_code 2.3.0) ] &&
17972                 skip "Need MDS version at least 2.3.0"
17973
17974         local dir0=$DIR/$tdir/$testnum
17975         mkdir -p $dir0 || error "creating dir $dir0"
17976
17977         local file=$dir0/file1
17978         dd if=/dev/urandom of=$file count=10 bs=1M conv=fsync
17979         local dv1=$($LFS data_version $file)
17980         dd if=/dev/urandom of=$file seek=10 count=1 bs=1M conv=fsync
17981         local dv2=$($LFS data_version $file)
17982         [[ $dv1 != $dv2 ]] ||
17983                 error "data version did not change on write $dv1 == $dv2"
17984
17985         # clean up
17986         rm -f $file1
17987 }
17988 run_test 187a "Test data version change"
17989
17990 test_187b() {
17991         remote_mds_nodsh && skip "remote MDS with nodsh"
17992         [ $MDS1_VERSION -lt $(version_code 2.3.0) ] &&
17993                 skip "Need MDS version at least 2.3.0"
17994
17995         local dir0=$DIR/$tdir/$testnum
17996         mkdir -p $dir0 || error "creating dir $dir0"
17997
17998         declare -a DV=$($MULTIOP $dir0 Vw1000xYw1000xY | cut -f3 -d" ")
17999         [[ ${DV[0]} != ${DV[1]} ]] ||
18000                 error "data version did not change on write"\
18001                       " ${DV[0]} == ${DV[1]}"
18002
18003         # clean up
18004         rm -f $file1
18005 }
18006 run_test 187b "Test data version change on volatile file"
18007
18008 test_200() {
18009         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18010         remote_mgs_nodsh && skip "remote MGS with nodsh"
18011         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
18012
18013         local POOL=${POOL:-cea1}
18014         local POOL_ROOT=${POOL_ROOT:-$DIR/d200.pools}
18015         local POOL_DIR_NAME=${POOL_DIR_NAME:-dir_tst}
18016         # Pool OST targets
18017         local first_ost=0
18018         local last_ost=$(($OSTCOUNT - 1))
18019         local ost_step=2
18020         local ost_list=$(seq $first_ost $ost_step $last_ost)
18021         local ost_range="$first_ost $last_ost $ost_step"
18022         local test_path=$POOL_ROOT/$POOL_DIR_NAME
18023         local file_dir=$POOL_ROOT/file_tst
18024         local subdir=$test_path/subdir
18025         local rc=0
18026
18027         while : ; do
18028                 # former test_200a test_200b
18029                 pool_add $POOL                          || { rc=$? ; break; }
18030                 pool_add_targets  $POOL $ost_range      || { rc=$? ; break; }
18031                 # former test_200c test_200d
18032                 mkdir -p $test_path
18033                 pool_set_dir      $POOL $test_path      || { rc=$? ; break; }
18034                 pool_check_dir    $POOL $test_path      || { rc=$? ; break; }
18035                 mkdir -p $subdir
18036                 pool_check_dir    $POOL $subdir         || { rc=$? ; break; }
18037                 pool_dir_rel_path $POOL $POOL_DIR_NAME $POOL_ROOT \
18038                                                         || { rc=$? ; break; }
18039                 # former test_200e test_200f
18040                 local files=$((OSTCOUNT*3))
18041                 pool_alloc_files  $POOL $test_path $files "$ost_list" \
18042                                                         || { rc=$? ; break; }
18043                 pool_create_files $POOL $file_dir $files "$ost_list" \
18044                                                         || { rc=$? ; break; }
18045                 # former test_200g test_200h
18046                 pool_lfs_df $POOL                       || { rc=$? ; break; }
18047                 pool_file_rel_path $POOL $test_path     || { rc=$? ; break; }
18048
18049                 # former test_201a test_201b test_201c
18050                 pool_remove_first_target $POOL          || { rc=$? ; break; }
18051
18052                 local f=$test_path/$tfile
18053                 pool_remove_all_targets $POOL $f        || { rc=$? ; break; }
18054                 pool_remove $POOL $f                    || { rc=$? ; break; }
18055                 break
18056         done
18057
18058         destroy_test_pools
18059
18060         return $rc
18061 }
18062 run_test 200 "OST pools"
18063
18064 # usage: default_attr <count | size | offset>
18065 default_attr() {
18066         $LCTL get_param -n lov.$FSNAME-clilov-\*.stripe${1}
18067 }
18068
18069 # usage: check_default_stripe_attr
18070 check_default_stripe_attr() {
18071         ACTUAL=$($LFS getstripe $* $DIR/$tdir)
18072         case $1 in
18073         --stripe-count|-c)
18074                 [ -n "$2" ] && EXPECTED=0 || EXPECTED=$(default_attr count);;
18075         --stripe-size|-S)
18076                 [ -n "$2" ] && EXPECTED=0 || EXPECTED=$(default_attr size);;
18077         --stripe-index|-i)
18078                 EXPECTED=-1;;
18079         *)
18080                 error "unknown getstripe attr '$1'"
18081         esac
18082
18083         [ $ACTUAL == $EXPECTED ] ||
18084                 error "$DIR/$tdir has $1 '$ACTUAL', not '$EXPECTED'"
18085 }
18086
18087 test_204a() {
18088         test_mkdir $DIR/$tdir
18089         $LFS setstripe --stripe-count 0 --stripe-size 0 --stripe-index -1 $DIR/$tdir
18090
18091         check_default_stripe_attr --stripe-count
18092         check_default_stripe_attr --stripe-size
18093         check_default_stripe_attr --stripe-index
18094 }
18095 run_test 204a "Print default stripe attributes"
18096
18097 test_204b() {
18098         test_mkdir $DIR/$tdir
18099         $LFS setstripe --stripe-count 1 $DIR/$tdir
18100
18101         check_default_stripe_attr --stripe-size
18102         check_default_stripe_attr --stripe-index
18103 }
18104 run_test 204b "Print default stripe size and offset"
18105
18106 test_204c() {
18107         test_mkdir $DIR/$tdir
18108         $LFS setstripe --stripe-size 65536 $DIR/$tdir
18109
18110         check_default_stripe_attr --stripe-count
18111         check_default_stripe_attr --stripe-index
18112 }
18113 run_test 204c "Print default stripe count and offset"
18114
18115 test_204d() {
18116         test_mkdir $DIR/$tdir
18117         $LFS setstripe --stripe-index 0 $DIR/$tdir
18118
18119         check_default_stripe_attr --stripe-count
18120         check_default_stripe_attr --stripe-size
18121 }
18122 run_test 204d "Print default stripe count and size"
18123
18124 test_204e() {
18125         test_mkdir $DIR/$tdir
18126         $LFS setstripe -d $DIR/$tdir
18127
18128         check_default_stripe_attr --stripe-count --raw
18129         check_default_stripe_attr --stripe-size --raw
18130         check_default_stripe_attr --stripe-index --raw
18131 }
18132 run_test 204e "Print raw stripe attributes"
18133
18134 test_204f() {
18135         test_mkdir $DIR/$tdir
18136         $LFS setstripe --stripe-count 1 $DIR/$tdir
18137
18138         check_default_stripe_attr --stripe-size --raw
18139         check_default_stripe_attr --stripe-index --raw
18140 }
18141 run_test 204f "Print raw stripe size and offset"
18142
18143 test_204g() {
18144         test_mkdir $DIR/$tdir
18145         $LFS setstripe --stripe-size 65536 $DIR/$tdir
18146
18147         check_default_stripe_attr --stripe-count --raw
18148         check_default_stripe_attr --stripe-index --raw
18149 }
18150 run_test 204g "Print raw stripe count and offset"
18151
18152 test_204h() {
18153         test_mkdir $DIR/$tdir
18154         $LFS setstripe --stripe-index 0 $DIR/$tdir
18155
18156         check_default_stripe_attr --stripe-count --raw
18157         check_default_stripe_attr --stripe-size --raw
18158 }
18159 run_test 204h "Print raw stripe count and size"
18160
18161 # Figure out which job scheduler is being used, if any,
18162 # or use a fake one
18163 if [ -n "$SLURM_JOB_ID" ]; then # SLURM
18164         JOBENV=SLURM_JOB_ID
18165 elif [ -n "$LSB_JOBID" ]; then # Load Sharing Facility
18166         JOBENV=LSB_JOBID
18167 elif [ -n "$PBS_JOBID" ]; then # PBS/Maui/Moab
18168         JOBENV=PBS_JOBID
18169 elif [ -n "$LOADL_STEPID" ]; then # LoadLeveller
18170         JOBENV=LOADL_STEP_ID
18171 elif [ -n "$JOB_ID" ]; then # Sun Grid Engine
18172         JOBENV=JOB_ID
18173 else
18174         $LCTL list_param jobid_name > /dev/null 2>&1
18175         if [ $? -eq 0 ]; then
18176                 JOBENV=nodelocal
18177         else
18178                 JOBENV=FAKE_JOBID
18179         fi
18180 fi
18181 LUSTRE_JOBID_SIZE=31 # plus NUL terminator
18182
18183 verify_jobstats() {
18184         local cmd=($1)
18185         shift
18186         local facets="$@"
18187
18188 # we don't really need to clear the stats for this test to work, since each
18189 # command has a unique jobid, but it makes debugging easier if needed.
18190 #       for facet in $facets; do
18191 #               local dev=$(convert_facet2label $facet)
18192 #               # clear old jobstats
18193 #               do_facet $facet lctl set_param *.$dev.job_stats="clear"
18194 #       done
18195
18196         # use a new JobID for each test, or we might see an old one
18197         [ "$JOBENV" = "FAKE_JOBID" ] &&
18198                 FAKE_JOBID=id.$testnum.$(basename ${cmd[0]}).$RANDOM
18199
18200         JOBVAL=${!JOBENV:0:$LUSTRE_JOBID_SIZE}
18201
18202         [ "$JOBENV" = "nodelocal" ] && {
18203                 FAKE_JOBID=id.$testnum.%e.$RANDOM
18204                 $LCTL set_param jobid_name=$FAKE_JOBID
18205                 JOBVAL=${FAKE_JOBID/\%e/$(basename ${cmd[0]})}
18206         }
18207
18208         log "Test: ${cmd[*]}"
18209         log "Using JobID environment $($LCTL get_param -n jobid_var)=$JOBVAL"
18210
18211         if [ $JOBENV = "FAKE_JOBID" ]; then
18212                 FAKE_JOBID=$JOBVAL ${cmd[*]}
18213         else
18214                 ${cmd[*]}
18215         fi
18216
18217         # all files are created on OST0000
18218         for facet in $facets; do
18219                 local stats="*.$(convert_facet2label $facet).job_stats"
18220
18221                 # strip out libtool wrappers for in-tree executables
18222                 if [ $(do_facet $facet lctl get_param $stats |
18223                        sed -e 's/\.lt-/./' | grep -c $JOBVAL) -ne 1 ]; then
18224                         do_facet $facet lctl get_param $stats
18225                         error "No jobstats for $JOBVAL found on $facet::$stats"
18226                 fi
18227         done
18228 }
18229
18230 jobstats_set() {
18231         local new_jobenv=$1
18232
18233         set_persistent_param_and_check client "jobid_var" \
18234                 "$FSNAME.sys.jobid_var" $new_jobenv
18235 }
18236
18237 test_205a() { # Job stats
18238         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18239         [[ $MDS1_VERSION -ge $(version_code 2.7.1) ]] ||
18240                 skip "Need MDS version with at least 2.7.1"
18241         remote_mgs_nodsh && skip "remote MGS with nodsh"
18242         remote_mds_nodsh && skip "remote MDS with nodsh"
18243         remote_ost_nodsh && skip "remote OST with nodsh"
18244         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep jobstats)" ] &&
18245                 skip "Server doesn't support jobstats"
18246         [[ $JOBID_VAR = disable ]] && skip_env "jobstats is disabled"
18247
18248         local old_jobenv=$($LCTL get_param -n jobid_var)
18249         [ $old_jobenv != $JOBENV ] && jobstats_set $JOBENV
18250
18251         if [[ $PERM_CMD == *"set_param -P"* ]]; then
18252                 stack_trap "do_facet mgs $PERM_CMD jobid_var=$old_jobenv" EXIT
18253         else
18254                 stack_trap "do_facet mgs $PERM_CMD \
18255                         $FSNAME.sys.jobid_var=$old_jobenv" EXIT
18256         fi
18257         changelog_register
18258
18259         local old_interval=$(do_facet $SINGLEMDS lctl get_param -n \
18260                                 mdt.*.job_cleanup_interval | head -n 1)
18261         local new_interval=5
18262         do_facet $SINGLEMDS \
18263                 $LCTL set_param mdt.*.job_cleanup_interval=$new_interval
18264         stack_trap "do_facet $SINGLEMDS \
18265                 $LCTL set_param mdt.*.job_cleanup_interval=$old_interval" EXIT
18266         local start=$SECONDS
18267
18268         local cmd
18269         # mkdir
18270         cmd="$LFS mkdir -i 0 -c 1 $DIR/$tdir"
18271         verify_jobstats "$cmd" "$SINGLEMDS"
18272         # rmdir
18273         cmd="rmdir $DIR/$tdir"
18274         verify_jobstats "$cmd" "$SINGLEMDS"
18275         # mkdir on secondary MDT
18276         if [ $MDSCOUNT -gt 1 ]; then
18277                 cmd="lfs mkdir -i 1 $DIR/$tdir.remote"
18278                 verify_jobstats "$cmd" "mds2"
18279         fi
18280         # mknod
18281         cmd="mknod $DIR/$tfile c 1 3"
18282         verify_jobstats "$cmd" "$SINGLEMDS"
18283         # unlink
18284         cmd="rm -f $DIR/$tfile"
18285         verify_jobstats "$cmd" "$SINGLEMDS"
18286         # create all files on OST0000 so verify_jobstats can find OST stats
18287         # open & close
18288         cmd="$LFS setstripe -i 0 -c 1 $DIR/$tfile"
18289         verify_jobstats "$cmd" "$SINGLEMDS"
18290         # setattr
18291         cmd="touch $DIR/$tfile"
18292         verify_jobstats "$cmd" "$SINGLEMDS ost1"
18293         # write
18294         cmd="dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=sync"
18295         verify_jobstats "$cmd" "ost1"
18296         # read
18297         cancel_lru_locks osc
18298         cmd="dd if=$DIR/$tfile of=/dev/null bs=1M count=1 iflag=direct"
18299         verify_jobstats "$cmd" "ost1"
18300         # truncate
18301         cmd="$TRUNCATE $DIR/$tfile 0"
18302         verify_jobstats "$cmd" "$SINGLEMDS ost1"
18303         # rename
18304         cmd="mv -f $DIR/$tfile $DIR/$tdir.rename"
18305         verify_jobstats "$cmd" "$SINGLEMDS"
18306         # jobstats expiry - sleep until old stats should be expired
18307         local left=$((new_interval + 5 - (SECONDS - start)))
18308         [ $left -ge 0 ] && wait_update_facet $SINGLEMDS \
18309                 "lctl get_param *.*.job_stats | grep -c 'job_id.*mkdir'" \
18310                         "0" $left
18311         cmd="$LFS mkdir -i 0 -c 1 $DIR/$tdir.expire"
18312         verify_jobstats "$cmd" "$SINGLEMDS"
18313         [ $(do_facet $SINGLEMDS lctl get_param *.*.job_stats |
18314             grep -c "job_id.*mkdir") -gt 1 ] && error "old jobstats not expired"
18315
18316         # Ensure that jobid are present in changelog (if supported by MDS)
18317         if [ $MDS1_VERSION -ge $(version_code 2.6.52) ];then
18318                 changelog_dump | tail -10
18319                 jobids=$(changelog_dump | tail -9 | grep -c "j=")
18320                 [ $jobids -eq 9 ] ||
18321                         error "Wrong changelog jobid count $jobids != 9"
18322
18323                 # LU-5862
18324                 JOBENV="disable"
18325                 jobstats_set $JOBENV
18326                 touch $DIR/$tfile
18327                 changelog_dump | grep $tfile
18328                 jobids=$(changelog_dump | grep $tfile | tail -1 | grep -c "j=")
18329                 [ $jobids -eq 0 ] ||
18330                         error "Unexpected jobids when jobid_var=$JOBENV"
18331         fi
18332
18333         # test '%j' access to environment variable - if supported
18334         if lctl set_param jobid_var=USER jobid_name="S.%j.%e.%u.%h.E"; then
18335                 JOBENV="JOBCOMPLEX"
18336                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname).E"
18337
18338                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
18339         fi
18340
18341         if lctl set_param jobid_var=USER jobid_name="S.%j.%e.%u.%H.E"; then
18342                 JOBENV="JOBCOMPLEX"
18343                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname -s).E"
18344
18345                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
18346         fi
18347
18348         # test '%j' access to per-session jobid - if supported
18349         if lctl list_param jobid_this_session > /dev/null 2>&1
18350         then
18351                 lctl set_param jobid_var=session jobid_name="S.%j.%e.%u.%h.E"
18352                 lctl set_param jobid_this_session=$USER
18353
18354                 JOBENV="JOBCOMPLEX"
18355                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname).E"
18356
18357                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
18358         fi
18359 }
18360 run_test 205a "Verify job stats"
18361
18362 # LU-13117, LU-13597
18363 test_205b() {
18364         (( $MDS1_VERSION >= $(version_code 2.13.54.91) )) ||
18365                 skip "Need MDS version at least 2.13.54.91"
18366
18367         job_stats="mdt.*.job_stats"
18368         $LCTL set_param $job_stats=clear
18369         # Setting jobid_var to USER might not be supported
18370         $LCTL set_param jobid_var=USER || true
18371         $LCTL set_param jobid_name="%e.%u"
18372         env -i USERTESTJOBSTATS=foolish touch $DIR/$tfile.1
18373         do_facet $SINGLEMDS $LCTL get_param $job_stats |
18374                 grep "job_id:.*foolish" &&
18375                         error "Unexpected jobid found"
18376         do_facet $SINGLEMDS $LCTL get_param $job_stats |
18377                 grep "open:.*min.*max.*sum" ||
18378                         error "wrong job_stats format found"
18379 }
18380 run_test 205b "Verify job stats jobid and output format"
18381
18382 # LU-13733
18383 test_205c() {
18384         $LCTL set_param llite.*.stats=0
18385         dd if=/dev/zero of=$DIR/$tfile.1 bs=4k count=1
18386         $LCTL get_param llite.*.stats
18387         $LCTL get_param llite.*.stats | grep \
18388                 "write_bytes *1 samples \[bytes\] 4096 4096 4096 16777216" ||
18389                         error "wrong client stats format found"
18390 }
18391 run_test 205c "Verify client stats format"
18392
18393 # LU-1480, LU-1773 and LU-1657
18394 test_206() {
18395         mkdir -p $DIR/$tdir
18396         $LFS setstripe -c -1 $DIR/$tdir
18397 #define OBD_FAIL_LOV_INIT 0x1403
18398         $LCTL set_param fail_loc=0xa0001403
18399         $LCTL set_param fail_val=1
18400         touch $DIR/$tdir/$tfile || true
18401 }
18402 run_test 206 "fail lov_init_raid0() doesn't lbug"
18403
18404 test_207a() {
18405         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((RANDOM%10+1))
18406         local fsz=`stat -c %s $DIR/$tfile`
18407         cancel_lru_locks mdc
18408
18409         # do not return layout in getattr intent
18410 #define OBD_FAIL_MDS_NO_LL_GETATTR 0x170
18411         $LCTL set_param fail_loc=0x170
18412         local sz=`stat -c %s $DIR/$tfile`
18413
18414         [ $fsz -eq $sz ] || error "file size expected $fsz, actual $sz"
18415
18416         rm -rf $DIR/$tfile
18417 }
18418 run_test 207a "can refresh layout at glimpse"
18419
18420 test_207b() {
18421         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((RANDOM%10+1))
18422         local cksum=`md5sum $DIR/$tfile`
18423         local fsz=`stat -c %s $DIR/$tfile`
18424         cancel_lru_locks mdc
18425         cancel_lru_locks osc
18426
18427         # do not return layout in getattr intent
18428 #define OBD_FAIL_MDS_NO_LL_OPEN 0x171
18429         $LCTL set_param fail_loc=0x171
18430
18431         # it will refresh layout after the file is opened but before read issues
18432         echo checksum is "$cksum"
18433         echo "$cksum" |md5sum -c --quiet || error "file differs"
18434
18435         rm -rf $DIR/$tfile
18436 }
18437 run_test 207b "can refresh layout at open"
18438
18439 test_208() {
18440         # FIXME: in this test suite, only RD lease is used. This is okay
18441         # for now as only exclusive open is supported. After generic lease
18442         # is done, this test suite should be revised. - Jinshan
18443
18444         remote_mds_nodsh && skip "remote MDS with nodsh"
18445         [[ $MDS1_VERSION -ge $(version_code 2.4.52) ]] ||
18446                 skip "Need MDS version at least 2.4.52"
18447
18448         echo "==== test 1: verify get lease work"
18449         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:eRE+eU || error "get lease error"
18450
18451         echo "==== test 2: verify lease can be broken by upcoming open"
18452         $MULTIOP $DIR/$tfile oO_RDWR:eR_E-eUc &
18453         local PID=$!
18454         sleep 1
18455
18456         $MULTIOP $DIR/$tfile oO_RDWR:c
18457         kill -USR1 $PID && wait $PID || error "break lease error"
18458
18459         echo "==== test 3: verify lease can't be granted if an open already exists"
18460         $MULTIOP $DIR/$tfile oO_RDWR:_c &
18461         local PID=$!
18462         sleep 1
18463
18464         $MULTIOP $DIR/$tfile oO_RDWR:eReUc && error "apply lease should fail"
18465         kill -USR1 $PID && wait $PID || error "open file error"
18466
18467         echo "==== test 4: lease can sustain over recovery"
18468         $MULTIOP $DIR/$tfile oO_RDWR:eR_E+eUc &
18469         PID=$!
18470         sleep 1
18471
18472         fail mds1
18473
18474         kill -USR1 $PID && wait $PID || error "lease broken over recovery"
18475
18476         echo "==== test 5: lease broken can't be regained by replay"
18477         $MULTIOP $DIR/$tfile oO_RDWR:eR_E-eUc &
18478         PID=$!
18479         sleep 1
18480
18481         # open file to break lease and then recovery
18482         $MULTIOP $DIR/$tfile oO_RDWR:c || error "open file error"
18483         fail mds1
18484
18485         kill -USR1 $PID && wait $PID || error "lease not broken over recovery"
18486
18487         rm -f $DIR/$tfile
18488 }
18489 run_test 208 "Exclusive open"
18490
18491 test_209() {
18492         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep disp_stripe)" ] &&
18493                 skip_env "must have disp_stripe"
18494
18495         touch $DIR/$tfile
18496         sync; sleep 5; sync;
18497
18498         echo 3 > /proc/sys/vm/drop_caches
18499         [ -f /sys/kernel/slab/ptlrpc_cache/shrink ] &&
18500                 echo 1 > /sys/kernel/slab/ptlrpc_cache/shrink
18501         req_before=$(awk '/ptlrpc_cache / { print $2 }' /proc/slabinfo)
18502
18503         # open/close 500 times
18504         for i in $(seq 500); do
18505                 cat $DIR/$tfile
18506         done
18507
18508         echo 3 > /proc/sys/vm/drop_caches
18509         [ -f /sys/kernel/slab/ptlrpc_cache/shrink ] &&
18510                 echo 1 > /sys/kernel/slab/ptlrpc_cache/shrink
18511         req_after=$(awk '/ptlrpc_cache / { print $2 }' /proc/slabinfo)
18512
18513         echo "before: $req_before, after: $req_after"
18514         [ $((req_after - req_before)) -ge 300 ] &&
18515                 error "open/close requests are not freed"
18516         return 0
18517 }
18518 run_test 209 "read-only open/close requests should be freed promptly"
18519
18520 test_210() {
18521         local pid
18522
18523         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:eW_E+eUc &
18524         pid=$!
18525         sleep 1
18526
18527         $LFS getstripe $DIR/$tfile
18528         kill -USR1 $pid
18529         wait $pid || error "multiop failed"
18530
18531         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E+eUc &
18532         pid=$!
18533         sleep 1
18534
18535         $LFS getstripe $DIR/$tfile
18536         kill -USR1 $pid
18537         wait $pid || error "multiop failed"
18538 }
18539 run_test 210 "lfs getstripe does not break leases"
18540
18541 test_212() {
18542         size=`date +%s`
18543         size=$((size % 8192 + 1))
18544         dd if=/dev/urandom of=$DIR/f212 bs=1k count=$size
18545         sendfile $DIR/f212 $DIR/f212.xyz || error "sendfile wrong"
18546         rm -f $DIR/f212 $DIR/f212.xyz
18547 }
18548 run_test 212 "Sendfile test ============================================"
18549
18550 test_213() {
18551         dd if=/dev/zero of=$DIR/$tfile bs=4k count=4
18552         cancel_lru_locks osc
18553         lctl set_param fail_loc=0x8000040f
18554         # generate a read lock
18555         cat $DIR/$tfile > /dev/null
18556         # write to the file, it will try to cancel the above read lock.
18557         cat /etc/hosts >> $DIR/$tfile
18558 }
18559 run_test 213 "OSC lock completion and cancel race don't crash - bug 18829"
18560
18561 test_214() { # for bug 20133
18562         mkdir -p $DIR/$tdir/d214c || error "mkdir $DIR/$tdir/d214c failed"
18563         for (( i=0; i < 340; i++ )) ; do
18564                 touch $DIR/$tdir/d214c/a$i
18565         done
18566
18567         ls -l $DIR/$tdir || error "ls -l $DIR/d214p failed"
18568         mv $DIR/$tdir/d214c $DIR/ || error "mv $DIR/d214p/d214c $DIR/ failed"
18569         ls $DIR/d214c || error "ls $DIR/d214c failed"
18570         rm -rf $DIR/$tdir || error "rm -rf $DIR/d214* failed"
18571         rm -rf $DIR/d214* || error "rm -rf $DIR/d214* failed"
18572 }
18573 run_test 214 "hash-indexed directory test - bug 20133"
18574
18575 # having "abc" as 1st arg, creates $TMP/lnet_abc.out and $TMP/lnet_abc.sys
18576 create_lnet_proc_files() {
18577         lctl get_param -n $1 >$TMP/lnet_$1.sys || error "cannot read lnet.$1"
18578 }
18579
18580 # counterpart of create_lnet_proc_files
18581 remove_lnet_proc_files() {
18582         rm -f $TMP/lnet_$1.sys
18583 }
18584
18585 # uses 1st arg as trailing part of filename, 2nd arg as description for reports,
18586 # 3rd arg as regexp for body
18587 check_lnet_proc_stats() {
18588         local l=$(cat "$TMP/lnet_$1" |wc -l)
18589         [ $l = 1 ] || (cat "$TMP/lnet_$1" && error "$2 is not of 1 line: $l")
18590
18591         grep -E "$3" "$TMP/lnet_$1" || (cat "$TMP/lnet_$1" && error "$2 misformatted")
18592 }
18593
18594 # uses 1st arg as trailing part of filename, 2nd arg as description for reports,
18595 # 3rd arg as regexp for body, 4th arg as regexp for 1st line, 5th arg is
18596 # optional and can be regexp for 2nd line (lnet.routes case)
18597 check_lnet_proc_entry() {
18598         local blp=2          # blp stands for 'position of 1st line of body'
18599         [ -z "$5" ] || blp=3 # lnet.routes case
18600
18601         local l=$(cat "$TMP/lnet_$1" |wc -l)
18602         # subtracting one from $blp because the body can be empty
18603         [ "$l" -ge "$(($blp - 1))" ] || (cat "$TMP/lnet_$1" && error "$2 is too short: $l")
18604
18605         sed -n '1 p' "$TMP/lnet_$1" |grep -E "$4" >/dev/null ||
18606                 (cat "$TMP/lnet_$1" && error "1st line of $2 misformatted")
18607
18608         [ "$5" = "" ] || sed -n '2 p' "$TMP/lnet_$1" |grep -E "$5" >/dev/null ||
18609                 (cat "$TMP/lnet_$1" && error "2nd line of $2 misformatted")
18610
18611         # bail out if any unexpected line happened
18612         sed -n "$blp p" "$TMP/lnet_$1" | grep -Ev "$3"
18613         [ "$?" != 0 ] || error "$2 misformatted"
18614 }
18615
18616 test_215() { # for bugs 18102, 21079, 21517
18617         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18618
18619         local N='(0|[1-9][0-9]*)'       # non-negative numeric
18620         local P='[1-9][0-9]*'           # positive numeric
18621         local I='(0|-?[1-9][0-9]*|NA)'  # any numeric (0 | >0 | <0) or NA if no value
18622         local NET='[a-z][a-z0-9]*'      # LNET net like o2ib2
18623         local ADDR='[0-9.]+'            # LNET addr like 10.0.0.1
18624         local NID="$ADDR@$NET"          # LNET nid like 10.0.0.1@o2ib2
18625
18626         local L1 # regexp for 1st line
18627         local L2 # regexp for 2nd line (optional)
18628         local BR # regexp for the rest (body)
18629
18630         # lnet.stats should look as 11 space-separated non-negative numerics
18631         BR="^$N $N $N $N $N $N $N $N $N $N $N$"
18632         create_lnet_proc_files "stats"
18633         check_lnet_proc_stats "stats.sys" "lnet.stats" "$BR"
18634         remove_lnet_proc_files "stats"
18635
18636         # lnet.routes should look like this:
18637         # Routing disabled/enabled
18638         # net hops priority state router
18639         # where net is a string like tcp0, hops > 0, priority >= 0,
18640         # state is up/down,
18641         # router is a string like 192.168.1.1@tcp2
18642         L1="^Routing (disabled|enabled)$"
18643         L2="^net +hops +priority +state +router$"
18644         BR="^$NET +$N +(0|1) +(up|down) +$NID$"
18645         create_lnet_proc_files "routes"
18646         check_lnet_proc_entry "routes.sys" "lnet.routes" "$BR" "$L1" "$L2"
18647         remove_lnet_proc_files "routes"
18648
18649         # lnet.routers should look like this:
18650         # ref rtr_ref alive_cnt state last_ping ping_sent deadline down_ni router
18651         # where ref > 0, rtr_ref > 0, alive_cnt >= 0, state is up/down,
18652         # last_ping >= 0, ping_sent is boolean (0/1), deadline and down_ni are
18653         # numeric (0 or >0 or <0), router is a string like 192.168.1.1@tcp2
18654         L1="^ref +rtr_ref +alive +router$"
18655         BR="^$P +$P +(up|down) +$NID$"
18656         create_lnet_proc_files "routers"
18657         check_lnet_proc_entry "routers.sys" "lnet.routers" "$BR" "$L1"
18658         remove_lnet_proc_files "routers"
18659
18660         # lnet.peers should look like this:
18661         # nid refs state last max rtr min tx min queue
18662         # where nid is a string like 192.168.1.1@tcp2, refs > 0,
18663         # state is up/down/NA, max >= 0. last, rtr, min, tx, min are
18664         # numeric (0 or >0 or <0), queue >= 0.
18665         L1="^nid +refs +state +last +max +rtr +min +tx +min +queue$"
18666         BR="^$NID +$P +(up|down|NA) +$I +$N +$I +$I +$I +$I +$N$"
18667         create_lnet_proc_files "peers"
18668         check_lnet_proc_entry "peers.sys" "lnet.peers" "$BR" "$L1"
18669         remove_lnet_proc_files "peers"
18670
18671         # lnet.buffers  should look like this:
18672         # pages count credits min
18673         # where pages >=0, count >=0, credits and min are numeric (0 or >0 or <0)
18674         L1="^pages +count +credits +min$"
18675         BR="^ +$N +$N +$I +$I$"
18676         create_lnet_proc_files "buffers"
18677         check_lnet_proc_entry "buffers.sys" "lnet.buffers" "$BR" "$L1"
18678         remove_lnet_proc_files "buffers"
18679
18680         # lnet.nis should look like this:
18681         # nid status alive refs peer rtr max tx min
18682         # where nid is a string like 192.168.1.1@tcp2, status is up/down,
18683         # alive is numeric (0 or >0 or <0), refs >= 0, peer >= 0,
18684         # rtr >= 0, max >=0, tx and min are numeric (0 or >0 or <0).
18685         L1="^nid +status +alive +refs +peer +rtr +max +tx +min$"
18686         BR="^$NID +(up|down) +$I +$N +$N +$N +$N +$I +$I$"
18687         create_lnet_proc_files "nis"
18688         check_lnet_proc_entry "nis.sys" "lnet.nis" "$BR" "$L1"
18689         remove_lnet_proc_files "nis"
18690
18691         # can we successfully write to lnet.stats?
18692         lctl set_param -n stats=0 || error "cannot write to lnet.stats"
18693 }
18694 run_test 215 "lnet exists and has proper content - bugs 18102, 21079, 21517"
18695
18696 test_216() { # bug 20317
18697         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18698         remote_ost_nodsh && skip "remote OST with nodsh"
18699
18700         local node
18701         local facets=$(get_facets OST)
18702         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
18703
18704         save_lustre_params client "osc.*.contention_seconds" > $p
18705         save_lustre_params $facets \
18706                 "ldlm.namespaces.filter-*.max_nolock_bytes" >> $p
18707         save_lustre_params $facets \
18708                 "ldlm.namespaces.filter-*.contended_locks" >> $p
18709         save_lustre_params $facets \
18710                 "ldlm.namespaces.filter-*.contention_seconds" >> $p
18711         clear_stats osc.*.osc_stats
18712
18713         # agressive lockless i/o settings
18714         do_nodes $(comma_list $(osts_nodes)) \
18715                 "lctl set_param -n ldlm.namespaces.*.max_nolock_bytes=2000000 \
18716                         ldlm.namespaces.filter-*.contended_locks=0 \
18717                         ldlm.namespaces.filter-*.contention_seconds=60"
18718         lctl set_param -n osc.*.contention_seconds=60
18719
18720         $DIRECTIO write $DIR/$tfile 0 10 4096
18721         $CHECKSTAT -s 40960 $DIR/$tfile
18722
18723         # disable lockless i/o
18724         do_nodes $(comma_list $(osts_nodes)) \
18725                 "lctl set_param -n ldlm.namespaces.filter-*.max_nolock_bytes=0 \
18726                         ldlm.namespaces.filter-*.contended_locks=32 \
18727                         ldlm.namespaces.filter-*.contention_seconds=0"
18728         lctl set_param -n osc.*.contention_seconds=0
18729         clear_stats osc.*.osc_stats
18730
18731         dd if=/dev/zero of=$DIR/$tfile count=0
18732         $CHECKSTAT -s 0 $DIR/$tfile
18733
18734         restore_lustre_params <$p
18735         rm -f $p
18736         rm $DIR/$tfile
18737 }
18738 run_test 216 "check lockless direct write updates file size and kms correctly"
18739
18740 test_217() { # bug 22430
18741         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18742
18743         local node
18744         local nid
18745
18746         for node in $(nodes_list); do
18747                 nid=$(host_nids_address $node $NETTYPE)
18748                 if [[ $nid = *-* ]] ; then
18749                         echo "lctl ping $(h2nettype $nid)"
18750                         lctl ping $(h2nettype $nid)
18751                 else
18752                         echo "skipping $node (no hyphen detected)"
18753                 fi
18754         done
18755 }
18756 run_test 217 "check lctl ping for hostnames with hiphen ('-')"
18757
18758 test_218() {
18759        # do directio so as not to populate the page cache
18760        log "creating a 10 Mb file"
18761        $MULTIOP $DIR/$tfile oO_CREAT:O_DIRECT:O_RDWR:w$((10*1048576))c || error "multiop failed while creating a file"
18762        log "starting reads"
18763        dd if=$DIR/$tfile of=/dev/null bs=4096 &
18764        log "truncating the file"
18765        $MULTIOP $DIR/$tfile oO_TRUNC:c || error "multiop failed while truncating the file"
18766        log "killing dd"
18767        kill %+ || true # reads might have finished
18768        echo "wait until dd is finished"
18769        wait
18770        log "removing the temporary file"
18771        rm -rf $DIR/$tfile || error "tmp file removal failed"
18772 }
18773 run_test 218 "parallel read and truncate should not deadlock"
18774
18775 test_219() {
18776         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18777
18778         # write one partial page
18779         dd if=/dev/zero of=$DIR/$tfile bs=1024 count=1
18780         # set no grant so vvp_io_commit_write will do sync write
18781         $LCTL set_param fail_loc=0x411
18782         # write a full page at the end of file
18783         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 seek=1 conv=notrunc
18784
18785         $LCTL set_param fail_loc=0
18786         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 seek=3
18787         $LCTL set_param fail_loc=0x411
18788         dd if=/dev/zero of=$DIR/$tfile bs=1024 count=1 seek=2 conv=notrunc
18789
18790         # LU-4201
18791         dd if=/dev/zero of=$DIR/$tfile-2 bs=1024 count=1
18792         $CHECKSTAT -s 1024 $DIR/$tfile-2 || error "checkstat wrong size"
18793 }
18794 run_test 219 "LU-394: Write partial won't cause uncontiguous pages vec at LND"
18795
18796 test_220() { #LU-325
18797         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18798         remote_ost_nodsh && skip "remote OST with nodsh"
18799         remote_mds_nodsh && skip "remote MDS with nodsh"
18800         remote_mgs_nodsh && skip "remote MGS with nodsh"
18801
18802         local OSTIDX=0
18803
18804         # create on MDT0000 so the last_id and next_id are correct
18805         mkdir_on_mdt0 $DIR/$tdir
18806         local OST=$($LFS df $DIR | awk '/OST:'$OSTIDX'/ { print $1 }')
18807         OST=${OST%_UUID}
18808
18809         # on the mdt's osc
18810         local mdtosc_proc1=$(get_mdtosc_proc_path $SINGLEMDS $OST)
18811         local last_id=$(do_facet $SINGLEMDS lctl get_param -n \
18812                         osp.$mdtosc_proc1.prealloc_last_id)
18813         local next_id=$(do_facet $SINGLEMDS lctl get_param -n \
18814                         osp.$mdtosc_proc1.prealloc_next_id)
18815
18816         $LFS df -i
18817
18818         do_facet ost$((OSTIDX + 1)) lctl set_param fail_val=-1
18819         #define OBD_FAIL_OST_ENOINO              0x229
18820         do_facet ost$((OSTIDX + 1)) lctl set_param fail_loc=0x229
18821         create_pool $FSNAME.$TESTNAME || return 1
18822         do_facet mgs $LCTL pool_add $FSNAME.$TESTNAME $OST || return 2
18823
18824         $LFS setstripe $DIR/$tdir -i $OSTIDX -c 1 -p $FSNAME.$TESTNAME
18825
18826         MDSOBJS=$((last_id - next_id))
18827         echo "preallocated objects on MDS is $MDSOBJS" "($last_id - $next_id)"
18828
18829         blocks=$($LFS df $MOUNT | awk '($1 == '$OSTIDX') { print $4 }')
18830         echo "OST still has $count kbytes free"
18831
18832         echo "create $MDSOBJS files @next_id..."
18833         createmany -o $DIR/$tdir/f $MDSOBJS || return 3
18834
18835         local last_id2=$(do_facet mds${MDSIDX} lctl get_param -n \
18836                         osp.$mdtosc_proc1.prealloc_last_id)
18837         local next_id2=$(do_facet mds${MDSIDX} lctl get_param -n \
18838                         osp.$mdtosc_proc1.prealloc_next_id)
18839
18840         echo "after creation, last_id=$last_id2, next_id=$next_id2"
18841         $LFS df -i
18842
18843         echo "cleanup..."
18844
18845         do_facet ost$((OSTIDX + 1)) lctl set_param fail_val=0
18846         do_facet ost$((OSTIDX + 1)) lctl set_param fail_loc=0
18847
18848         do_facet mgs $LCTL pool_remove $FSNAME.$TESTNAME $OST ||
18849                 error "$LCTL pool_remove $FSNAME.$TESTNAME $OST failed"
18850         do_facet mgs $LCTL pool_destroy $FSNAME.$TESTNAME ||
18851                 error "$LCTL pool_destroy $FSNAME.$TESTNAME failed"
18852         echo "unlink $MDSOBJS files @$next_id..."
18853         unlinkmany $DIR/$tdir/f $MDSOBJS || error "unlinkmany failed"
18854 }
18855 run_test 220 "preallocated MDS objects still used if ENOSPC from OST"
18856
18857 test_221() {
18858         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18859
18860         dd if=`which date` of=$MOUNT/date oflag=sync
18861         chmod +x $MOUNT/date
18862
18863         #define OBD_FAIL_LLITE_FAULT_TRUNC_RACE  0x1401
18864         $LCTL set_param fail_loc=0x80001401
18865
18866         $MOUNT/date > /dev/null
18867         rm -f $MOUNT/date
18868 }
18869 run_test 221 "make sure fault and truncate race to not cause OOM"
18870
18871 test_222a () {
18872         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18873
18874         rm -rf $DIR/$tdir
18875         test_mkdir $DIR/$tdir
18876         $LFS setstripe -c 1 -i 0 $DIR/$tdir
18877         createmany -o $DIR/$tdir/$tfile 10
18878         cancel_lru_locks mdc
18879         cancel_lru_locks osc
18880         #define OBD_FAIL_LDLM_AGL_DELAY           0x31a
18881         $LCTL set_param fail_loc=0x31a
18882         ls -l $DIR/$tdir > /dev/null || error "AGL for ls failed"
18883         $LCTL set_param fail_loc=0
18884         rm -r $DIR/$tdir
18885 }
18886 run_test 222a "AGL for ls should not trigger CLIO lock failure"
18887
18888 test_222b () {
18889         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18890
18891         rm -rf $DIR/$tdir
18892         test_mkdir $DIR/$tdir
18893         $LFS setstripe -c 1 -i 0 $DIR/$tdir
18894         createmany -o $DIR/$tdir/$tfile 10
18895         cancel_lru_locks mdc
18896         cancel_lru_locks osc
18897         #define OBD_FAIL_LDLM_AGL_DELAY           0x31a
18898         $LCTL set_param fail_loc=0x31a
18899         rm -r $DIR/$tdir || error "AGL for rmdir failed"
18900         $LCTL set_param fail_loc=0
18901 }
18902 run_test 222b "AGL for rmdir should not trigger CLIO lock failure"
18903
18904 test_223 () {
18905         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18906
18907         rm -rf $DIR/$tdir
18908         test_mkdir $DIR/$tdir
18909         $LFS setstripe -c 1 -i 0 $DIR/$tdir
18910         createmany -o $DIR/$tdir/$tfile 10
18911         cancel_lru_locks mdc
18912         cancel_lru_locks osc
18913         #define OBD_FAIL_LDLM_AGL_NOLOCK          0x31b
18914         $LCTL set_param fail_loc=0x31b
18915         ls -l $DIR/$tdir > /dev/null || error "reenqueue failed"
18916         $LCTL set_param fail_loc=0
18917         rm -r $DIR/$tdir
18918 }
18919 run_test 223 "osc reenqueue if without AGL lock granted ======================="
18920
18921 test_224a() { # LU-1039, MRP-303
18922         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18923         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB   0x508
18924         $LCTL set_param fail_loc=0x508
18925         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 conv=fsync
18926         $LCTL set_param fail_loc=0
18927         df $DIR
18928 }
18929 run_test 224a "Don't panic on bulk IO failure"
18930
18931 test_224bd_sub() { # LU-1039, MRP-303
18932         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18933         local timeout=$1
18934
18935         shift
18936         dd if=/dev/urandom of=$TMP/$tfile bs=1M count=1
18937
18938         $LFS setstripe -c 1 -i 0 $DIR/$tfile
18939
18940         dd if=$TMP/$tfile of=$DIR/$tfile bs=1M count=1
18941         cancel_lru_locks osc
18942         set_checksums 0
18943         stack_trap "set_checksums $ORIG_CSUM" EXIT
18944         local at_max_saved=0
18945
18946         # adaptive timeouts may prevent seeing the issue
18947         if at_is_enabled; then
18948                 at_max_saved=$(at_max_get mds)
18949                 at_max_set 0 mds client
18950                 stack_trap "at_max_set $at_max_saved mds client" EXIT
18951         fi
18952
18953         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB2   0x515
18954         do_facet ost1 $LCTL set_param fail_val=$timeout fail_loc=0x80000515
18955         dd of=$TMP/$tfile.new if=$DIR/$tfile bs=1M count=1 || "$@"
18956
18957         do_facet ost1 $LCTL set_param fail_loc=0
18958         cmp $TMP/$tfile $TMP/$tfile.new || error "file contents wrong"
18959         df $DIR
18960 }
18961
18962 test_224b() {
18963         test_224bd_sub 3 error "dd failed"
18964 }
18965 run_test 224b "Don't panic on bulk IO failure"
18966
18967 test_224c() { # LU-6441
18968         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18969         remote_mds_nodsh && skip "remote MDS with nodsh"
18970
18971         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
18972         save_writethrough $p
18973         set_cache writethrough on
18974
18975         local pages_per_rpc=$($LCTL get_param osc.*.max_pages_per_rpc)
18976         local at_max=$($LCTL get_param -n at_max)
18977         local timeout=$($LCTL get_param -n timeout)
18978         local test_at="at_max"
18979         local param_at="$FSNAME.sys.at_max"
18980         local test_timeout="timeout"
18981         local param_timeout="$FSNAME.sys.timeout"
18982
18983         $LCTL set_param -n osc.*.max_pages_per_rpc=1024
18984
18985         set_persistent_param_and_check client "$test_at" "$param_at" 0
18986         set_persistent_param_and_check client "$test_timeout" "$param_timeout" 5
18987
18988         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB3 0x520
18989         do_facet ost1 "$LCTL set_param fail_loc=0x520"
18990         $LFS setstripe -c 1 -i 0 $DIR/$tfile
18991         dd if=/dev/zero of=$DIR/$tfile bs=8MB count=1
18992         sync
18993         do_facet ost1 "$LCTL set_param fail_loc=0"
18994
18995         set_persistent_param_and_check client "$test_at" "$param_at" $at_max
18996         set_persistent_param_and_check client "$test_timeout" "$param_timeout" \
18997                 $timeout
18998
18999         $LCTL set_param -n $pages_per_rpc
19000         restore_lustre_params < $p
19001         rm -f $p
19002 }
19003 run_test 224c "Don't hang if one of md lost during large bulk RPC"
19004
19005 test_224d() { # LU-11169
19006         test_224bd_sub $((TIMEOUT + 2)) error "dd failed"
19007 }
19008 run_test 224d "Don't corrupt data on bulk IO timeout"
19009
19010 MDSSURVEY=${MDSSURVEY:-$(which mds-survey 2>/dev/null || true)}
19011 test_225a () {
19012         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19013         if [ -z ${MDSSURVEY} ]; then
19014                 skip_env "mds-survey not found"
19015         fi
19016         [ $MDS1_VERSION -ge $(version_code 2.2.51) ] ||
19017                 skip "Need MDS version at least 2.2.51"
19018
19019         local mds=$(facet_host $SINGLEMDS)
19020         local target=$(do_nodes $mds 'lctl dl' |
19021                        awk '{ if ($2 == "UP" && $3 == "mdt") { print $4 }}')
19022
19023         local cmd1="file_count=1000 thrhi=4"
19024         local cmd2="dir_count=2 layer=mdd stripe_count=0"
19025         local cmd3="rslt_loc=${TMP} targets=\"$mds:$target\" $MDSSURVEY"
19026         local cmd="$cmd1 $cmd2 $cmd3"
19027
19028         rm -f ${TMP}/mds_survey*
19029         echo + $cmd
19030         eval $cmd || error "mds-survey with zero-stripe failed"
19031         cat ${TMP}/mds_survey*
19032         rm -f ${TMP}/mds_survey*
19033 }
19034 run_test 225a "Metadata survey sanity with zero-stripe"
19035
19036 test_225b () {
19037         if [ -z ${MDSSURVEY} ]; then
19038                 skip_env "mds-survey not found"
19039         fi
19040         [ $MDS1_VERSION -ge $(version_code 2.2.51) ] ||
19041                 skip "Need MDS version at least 2.2.51"
19042         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19043         remote_mds_nodsh && skip "remote MDS with nodsh"
19044         if [ $($LCTL dl | grep -c osc) -eq 0 ]; then
19045                 skip_env "Need to mount OST to test"
19046         fi
19047
19048         local mds=$(facet_host $SINGLEMDS)
19049         local target=$(do_nodes $mds 'lctl dl' |
19050                        awk '{ if ($2 == "UP" && $3 == "mdt") { print $4 }}')
19051
19052         local cmd1="file_count=1000 thrhi=4"
19053         local cmd2="dir_count=2 layer=mdd stripe_count=1"
19054         local cmd3="rslt_loc=${TMP} targets=\"$mds:$target\" $MDSSURVEY"
19055         local cmd="$cmd1 $cmd2 $cmd3"
19056
19057         rm -f ${TMP}/mds_survey*
19058         echo + $cmd
19059         eval $cmd || error "mds-survey with stripe_count failed"
19060         cat ${TMP}/mds_survey*
19061         rm -f ${TMP}/mds_survey*
19062 }
19063 run_test 225b "Metadata survey sanity with stripe_count = 1"
19064
19065 mcreate_path2fid () {
19066         local mode=$1
19067         local major=$2
19068         local minor=$3
19069         local name=$4
19070         local desc=$5
19071         local path=$DIR/$tdir/$name
19072         local fid
19073         local rc
19074         local fid_path
19075
19076         $MCREATE --mode=$1 --major=$2 --minor=$3 $path ||
19077                 error "cannot create $desc"
19078
19079         fid=$($LFS path2fid $path | tr -d '[' | tr -d ']')
19080         rc=$?
19081         [ $rc -ne 0 ] && error "cannot get fid of a $desc"
19082
19083         fid_path=$($LFS fid2path $MOUNT $fid)
19084         rc=$?
19085         [ $rc -ne 0 ] && error "cannot get path of $desc by $DIR $path $fid"
19086
19087         [ "$path" == "$fid_path" ] ||
19088                 error "fid2path returned $fid_path, expected $path"
19089
19090         echo "pass with $path and $fid"
19091 }
19092
19093 test_226a () {
19094         rm -rf $DIR/$tdir
19095         mkdir -p $DIR/$tdir
19096
19097         mcreate_path2fid 0010666 0 0 fifo "FIFO"
19098         mcreate_path2fid 0020666 1 3 null "character special file (null)"
19099         mcreate_path2fid 0020666 1 255 none "character special file (no device)"
19100         mcreate_path2fid 0040666 0 0 dir "directory"
19101         mcreate_path2fid 0060666 7 0 loop0 "block special file (loop)"
19102         mcreate_path2fid 0100666 0 0 file "regular file"
19103         mcreate_path2fid 0120666 0 0 link "symbolic link"
19104         mcreate_path2fid 0140666 0 0 sock "socket"
19105 }
19106 run_test 226a "call path2fid and fid2path on files of all type"
19107
19108 test_226b () {
19109         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19110
19111         local MDTIDX=1
19112
19113         rm -rf $DIR/$tdir
19114         mkdir -p $DIR/$tdir
19115         $LFS setdirstripe -i $MDTIDX $DIR/$tdir/remote_dir ||
19116                 error "create remote directory failed"
19117         mcreate_path2fid 0010666 0 0 "remote_dir/fifo" "FIFO"
19118         mcreate_path2fid 0020666 1 3 "remote_dir/null" \
19119                                 "character special file (null)"
19120         mcreate_path2fid 0020666 1 255 "remote_dir/none" \
19121                                 "character special file (no device)"
19122         mcreate_path2fid 0040666 0 0 "remote_dir/dir" "directory"
19123         mcreate_path2fid 0060666 7 0 "remote_dir/loop0" \
19124                                 "block special file (loop)"
19125         mcreate_path2fid 0100666 0 0 "remote_dir/file" "regular file"
19126         mcreate_path2fid 0120666 0 0 "remote_dir/link" "symbolic link"
19127         mcreate_path2fid 0140666 0 0 "remote_dir/sock" "socket"
19128 }
19129 run_test 226b "call path2fid and fid2path on files of all type under remote dir"
19130
19131 test_226c () {
19132         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19133         [[ $MDS1_VERSION -ge $(version_code 2.13.55) ]] ||
19134                 skip "Need MDS version at least 2.13.55"
19135
19136         local submnt=/mnt/submnt
19137         local srcfile=/etc/passwd
19138         local dstfile=$submnt/passwd
19139         local path
19140         local fid
19141
19142         rm -rf $DIR/$tdir
19143         rm -rf $submnt
19144         $LFS setdirstripe -c -1 -i 1 $DIR/$tdir ||
19145                 error "create remote directory failed"
19146         mkdir -p $submnt || error "create $submnt failed"
19147         $MOUNT_CMD $MGSNID:/$FSNAME/$tdir $submnt ||
19148                 error "mount $submnt failed"
19149         stack_trap "umount $submnt" EXIT
19150
19151         cp $srcfile $dstfile
19152         fid=$($LFS path2fid $dstfile)
19153         path=$($LFS fid2path $submnt "$fid")
19154         [ "$path" = "$dstfile" ] ||
19155                 error "fid2path $submnt $fid failed ($path != $dstfile)"
19156 }
19157 run_test 226c "call path2fid and fid2path under remote dir with subdir mount"
19158
19159 # LU-1299 Executing or running ldd on a truncated executable does not
19160 # cause an out-of-memory condition.
19161 test_227() {
19162         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19163         [ -z "$(which ldd)" ] && skip_env "should have ldd tool"
19164
19165         dd if=$(which date) of=$MOUNT/date bs=1k count=1
19166         chmod +x $MOUNT/date
19167
19168         $MOUNT/date > /dev/null
19169         ldd $MOUNT/date > /dev/null
19170         rm -f $MOUNT/date
19171 }
19172 run_test 227 "running truncated executable does not cause OOM"
19173
19174 # LU-1512 try to reuse idle OI blocks
19175 test_228a() {
19176         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19177         remote_mds_nodsh && skip "remote MDS with nodsh"
19178         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
19179
19180         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
19181         local myDIR=$DIR/$tdir
19182
19183         mkdir -p $myDIR
19184         #define OBD_FAIL_SEQ_EXHAUST             0x1002
19185         $LCTL set_param fail_loc=0x80001002
19186         createmany -o $myDIR/t- 10000
19187         $LCTL set_param fail_loc=0
19188         # The guard is current the largest FID holder
19189         touch $myDIR/guard
19190         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
19191                     tr -d '[')
19192         local IDX=$(($SEQ % 64))
19193
19194         do_facet $SINGLEMDS sync
19195         # Make sure journal flushed.
19196         sleep 6
19197         local blk1=$(do_facet $SINGLEMDS \
19198                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
19199                      grep Blockcount | awk '{print $4}')
19200
19201         # Remove old files, some OI blocks will become idle.
19202         unlinkmany $myDIR/t- 10000
19203         # Create new files, idle OI blocks should be reused.
19204         createmany -o $myDIR/t- 2000
19205         do_facet $SINGLEMDS sync
19206         # Make sure journal flushed.
19207         sleep 6
19208         local blk2=$(do_facet $SINGLEMDS \
19209                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
19210                      grep Blockcount | awk '{print $4}')
19211
19212         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
19213 }
19214 run_test 228a "try to reuse idle OI blocks"
19215
19216 test_228b() {
19217         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19218         remote_mds_nodsh && skip "remote MDS with nodsh"
19219         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
19220
19221         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
19222         local myDIR=$DIR/$tdir
19223
19224         mkdir -p $myDIR
19225         #define OBD_FAIL_SEQ_EXHAUST             0x1002
19226         $LCTL set_param fail_loc=0x80001002
19227         createmany -o $myDIR/t- 10000
19228         $LCTL set_param fail_loc=0
19229         # The guard is current the largest FID holder
19230         touch $myDIR/guard
19231         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
19232                     tr -d '[')
19233         local IDX=$(($SEQ % 64))
19234
19235         do_facet $SINGLEMDS sync
19236         # Make sure journal flushed.
19237         sleep 6
19238         local blk1=$(do_facet $SINGLEMDS \
19239                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
19240                      grep Blockcount | awk '{print $4}')
19241
19242         # Remove old files, some OI blocks will become idle.
19243         unlinkmany $myDIR/t- 10000
19244
19245         # stop the MDT
19246         stop $SINGLEMDS || error "Fail to stop MDT."
19247         # remount the MDT
19248         start $SINGLEMDS $MDT_DEV $MDS_MOUNT_OPTS || error "Fail to start MDT."
19249
19250         df $MOUNT || error "Fail to df."
19251         # Create new files, idle OI blocks should be reused.
19252         createmany -o $myDIR/t- 2000
19253         do_facet $SINGLEMDS sync
19254         # Make sure journal flushed.
19255         sleep 6
19256         local blk2=$(do_facet $SINGLEMDS \
19257                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
19258                      grep Blockcount | awk '{print $4}')
19259
19260         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
19261 }
19262 run_test 228b "idle OI blocks can be reused after MDT restart"
19263
19264 #LU-1881
19265 test_228c() {
19266         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19267         remote_mds_nodsh && skip "remote MDS with nodsh"
19268         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
19269
19270         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
19271         local myDIR=$DIR/$tdir
19272
19273         mkdir -p $myDIR
19274         #define OBD_FAIL_SEQ_EXHAUST             0x1002
19275         $LCTL set_param fail_loc=0x80001002
19276         # 20000 files can guarantee there are index nodes in the OI file
19277         createmany -o $myDIR/t- 20000
19278         $LCTL set_param fail_loc=0
19279         # The guard is current the largest FID holder
19280         touch $myDIR/guard
19281         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
19282                     tr -d '[')
19283         local IDX=$(($SEQ % 64))
19284
19285         do_facet $SINGLEMDS sync
19286         # Make sure journal flushed.
19287         sleep 6
19288         local blk1=$(do_facet $SINGLEMDS \
19289                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
19290                      grep Blockcount | awk '{print $4}')
19291
19292         # Remove old files, some OI blocks will become idle.
19293         unlinkmany $myDIR/t- 20000
19294         rm -f $myDIR/guard
19295         # The OI file should become empty now
19296
19297         # Create new files, idle OI blocks should be reused.
19298         createmany -o $myDIR/t- 2000
19299         do_facet $SINGLEMDS sync
19300         # Make sure journal flushed.
19301         sleep 6
19302         local blk2=$(do_facet $SINGLEMDS \
19303                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
19304                      grep Blockcount | awk '{print $4}')
19305
19306         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
19307 }
19308 run_test 228c "NOT shrink the last entry in OI index node to recycle idle leaf"
19309
19310 test_229() { # LU-2482, LU-3448
19311         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19312         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
19313         [ $MDS1_VERSION -lt $(version_code 2.4.53) ] &&
19314                 skip "No HSM $(lustre_build_version $SINGLEMDS) MDS < 2.4.53"
19315
19316         rm -f $DIR/$tfile
19317
19318         # Create a file with a released layout and stripe count 2.
19319         $MULTIOP $DIR/$tfile H2c ||
19320                 error "failed to create file with released layout"
19321
19322         $LFS getstripe -v $DIR/$tfile
19323
19324         local pattern=$($LFS getstripe -L $DIR/$tfile)
19325         [ X"$pattern" = X"released" ] || error "pattern error ($pattern)"
19326
19327         local stripe_count=$($LFS getstripe -c $DIR/$tfile) ||
19328                 error "getstripe"
19329         [ $stripe_count -eq 2 ] || error "stripe count not 2 ($stripe_count)"
19330         stat $DIR/$tfile || error "failed to stat released file"
19331
19332         chown $RUNAS_ID $DIR/$tfile ||
19333                 error "chown $RUNAS_ID $DIR/$tfile failed"
19334
19335         chgrp $RUNAS_ID $DIR/$tfile ||
19336                 error "chgrp $RUNAS_ID $DIR/$tfile failed"
19337
19338         touch $DIR/$tfile || error "touch $DIR/$tfile failed"
19339         rm $DIR/$tfile || error "failed to remove released file"
19340 }
19341 run_test 229 "getstripe/stat/rm/attr changes work on released files"
19342
19343 test_230a() {
19344         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19345         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19346         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
19347                 skip "Need MDS version at least 2.11.52"
19348
19349         local MDTIDX=1
19350
19351         test_mkdir $DIR/$tdir
19352         test_mkdir -i0 -c1 $DIR/$tdir/test_230_local
19353         local mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230_local)
19354         [ $mdt_idx -ne 0 ] &&
19355                 error "create local directory on wrong MDT $mdt_idx"
19356
19357         $LFS mkdir -i $MDTIDX $DIR/$tdir/test_230 ||
19358                         error "create remote directory failed"
19359         local mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230)
19360         [ $mdt_idx -ne $MDTIDX ] &&
19361                 error "create remote directory on wrong MDT $mdt_idx"
19362
19363         createmany -o $DIR/$tdir/test_230/t- 10 ||
19364                 error "create files on remote directory failed"
19365         mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230/t-0)
19366         [ $mdt_idx -ne $MDTIDX ] && error "create files on wrong MDT $mdt_idx"
19367         rm -r $DIR/$tdir || error "unlink remote directory failed"
19368 }
19369 run_test 230a "Create remote directory and files under the remote directory"
19370
19371 test_230b() {
19372         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19373         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19374         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
19375                 skip "Need MDS version at least 2.11.52"
19376
19377         local MDTIDX=1
19378         local mdt_index
19379         local i
19380         local file
19381         local pid
19382         local stripe_count
19383         local migrate_dir=$DIR/$tdir/migrate_dir
19384         local other_dir=$DIR/$tdir/other_dir
19385
19386         test_mkdir $DIR/$tdir
19387         test_mkdir -i0 -c1 $migrate_dir
19388         test_mkdir -i0 -c1 $other_dir
19389         for ((i=0; i<10; i++)); do
19390                 mkdir -p $migrate_dir/dir_${i}
19391                 createmany -o $migrate_dir/dir_${i}/f 10 ||
19392                         error "create files under remote dir failed $i"
19393         done
19394
19395         cp /etc/passwd $migrate_dir/$tfile
19396         cp /etc/passwd $other_dir/$tfile
19397         chattr +SAD $migrate_dir
19398         chattr +SAD $migrate_dir/$tfile
19399
19400         local old_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
19401         local old_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
19402         local old_dir_mode=$(stat -c%f $migrate_dir)
19403         local old_file_mode=$(stat -c%f $migrate_dir/$tfile)
19404
19405         mkdir -p $migrate_dir/dir_default_stripe2
19406         $LFS setstripe -c 2 $migrate_dir/dir_default_stripe2
19407         $LFS setstripe -c 2 $migrate_dir/${tfile}_stripe2
19408
19409         mkdir -p $other_dir
19410         ln $migrate_dir/$tfile $other_dir/luna
19411         ln $migrate_dir/$tfile $migrate_dir/sofia
19412         ln $other_dir/$tfile $migrate_dir/david
19413         ln -s $migrate_dir/$tfile $other_dir/zachary
19414         ln -s $migrate_dir/$tfile $migrate_dir/${tfile}_ln
19415         ln -s $other_dir/$tfile $migrate_dir/${tfile}_ln_other
19416
19417         local len
19418         local lnktgt
19419
19420         # inline symlink
19421         for len in 58 59 60; do
19422                 lnktgt=$(str_repeat 'l' $len)
19423                 touch $migrate_dir/$lnktgt
19424                 ln -s $lnktgt $migrate_dir/${len}char_ln
19425         done
19426
19427         # PATH_MAX
19428         for len in 4094 4095; do
19429                 lnktgt=$(str_repeat 'l' $len)
19430                 ln -s $lnktgt $migrate_dir/${len}char_ln
19431         done
19432
19433         # NAME_MAX
19434         for len in 254 255; do
19435                 touch $migrate_dir/$(str_repeat 'l' $len)
19436         done
19437
19438         $LFS migrate -m $MDTIDX $migrate_dir ||
19439                 error "fails on migrating remote dir to MDT1"
19440
19441         echo "migratate to MDT1, then checking.."
19442         for ((i = 0; i < 10; i++)); do
19443                 for file in $(find $migrate_dir/dir_${i}); do
19444                         mdt_index=$($LFS getstripe -m $file)
19445                         # broken symlink getstripe will fail
19446                         [ $mdt_index -ne $MDTIDX ] && stat -L $file &&
19447                                 error "$file is not on MDT${MDTIDX}"
19448                 done
19449         done
19450
19451         # the multiple link file should still in MDT0
19452         mdt_index=$($LFS getstripe -m $migrate_dir/$tfile)
19453         [ $mdt_index == 0 ] ||
19454                 error "$file is not on MDT${MDTIDX}"
19455
19456         local new_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
19457         [ "$old_dir_flag" = "$new_dir_flag" ] ||
19458                 error " expect $old_dir_flag get $new_dir_flag"
19459
19460         local new_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
19461         [ "$old_file_flag" = "$new_file_flag" ] ||
19462                 error " expect $old_file_flag get $new_file_flag"
19463
19464         local new_dir_mode=$(stat -c%f $migrate_dir)
19465         [ "$old_dir_mode" = "$new_dir_mode" ] ||
19466                 error "expect mode $old_dir_mode get $new_dir_mode"
19467
19468         local new_file_mode=$(stat -c%f $migrate_dir/$tfile)
19469         [ "$old_file_mode" = "$new_file_mode" ] ||
19470                 error "expect mode $old_file_mode get $new_file_mode"
19471
19472         diff /etc/passwd $migrate_dir/$tfile ||
19473                 error "$tfile different after migration"
19474
19475         diff /etc/passwd $other_dir/luna ||
19476                 error "luna different after migration"
19477
19478         diff /etc/passwd $migrate_dir/sofia ||
19479                 error "sofia different after migration"
19480
19481         diff /etc/passwd $migrate_dir/david ||
19482                 error "david different after migration"
19483
19484         diff /etc/passwd $other_dir/zachary ||
19485                 error "zachary different after migration"
19486
19487         diff /etc/passwd $migrate_dir/${tfile}_ln ||
19488                 error "${tfile}_ln different after migration"
19489
19490         diff /etc/passwd $migrate_dir/${tfile}_ln_other ||
19491                 error "${tfile}_ln_other different after migration"
19492
19493         stripe_count=$($LFS getstripe -c $migrate_dir/dir_default_stripe2)
19494         [ $stripe_count = 2 ] ||
19495                 error "dir strpe_count $d != 2 after migration."
19496
19497         stripe_count=$($LFS getstripe -c $migrate_dir/${tfile}_stripe2)
19498         [ $stripe_count = 2 ] ||
19499                 error "file strpe_count $d != 2 after migration."
19500
19501         #migrate back to MDT0
19502         MDTIDX=0
19503
19504         $LFS migrate -m $MDTIDX $migrate_dir ||
19505                 error "fails on migrating remote dir to MDT0"
19506
19507         echo "migrate back to MDT0, checking.."
19508         for file in $(find $migrate_dir); do
19509                 mdt_index=$($LFS getstripe -m $file)
19510                 [ $mdt_index -ne $MDTIDX ] && stat -L $file &&
19511                         error "$file is not on MDT${MDTIDX}"
19512         done
19513
19514         local new_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
19515         [ "$old_dir_flag" = "$new_dir_flag" ] ||
19516                 error " expect $old_dir_flag get $new_dir_flag"
19517
19518         local new_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
19519         [ "$old_file_flag" = "$new_file_flag" ] ||
19520                 error " expect $old_file_flag get $new_file_flag"
19521
19522         local new_dir_mode=$(stat -c%f $migrate_dir)
19523         [ "$old_dir_mode" = "$new_dir_mode" ] ||
19524                 error "expect mode $old_dir_mode get $new_dir_mode"
19525
19526         local new_file_mode=$(stat -c%f $migrate_dir/$tfile)
19527         [ "$old_file_mode" = "$new_file_mode" ] ||
19528                 error "expect mode $old_file_mode get $new_file_mode"
19529
19530         diff /etc/passwd ${migrate_dir}/$tfile ||
19531                 error "$tfile different after migration"
19532
19533         diff /etc/passwd ${other_dir}/luna ||
19534                 error "luna different after migration"
19535
19536         diff /etc/passwd ${migrate_dir}/sofia ||
19537                 error "sofia different after migration"
19538
19539         diff /etc/passwd ${other_dir}/zachary ||
19540                 error "zachary different after migration"
19541
19542         diff /etc/passwd $migrate_dir/${tfile}_ln ||
19543                 error "${tfile}_ln different after migration"
19544
19545         diff /etc/passwd $migrate_dir/${tfile}_ln_other ||
19546                 error "${tfile}_ln_other different after migration"
19547
19548         stripe_count=$($LFS getstripe -c ${migrate_dir}/dir_default_stripe2)
19549         [ $stripe_count = 2 ] ||
19550                 error "dir strpe_count $d != 2 after migration."
19551
19552         stripe_count=$($LFS getstripe -c ${migrate_dir}/${tfile}_stripe2)
19553         [ $stripe_count = 2 ] ||
19554                 error "file strpe_count $d != 2 after migration."
19555
19556         rm -rf $DIR/$tdir || error "rm dir failed after migration"
19557 }
19558 run_test 230b "migrate directory"
19559
19560 test_230c() {
19561         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19562         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19563         remote_mds_nodsh && skip "remote MDS with nodsh"
19564         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
19565                 skip "Need MDS version at least 2.11.52"
19566
19567         local MDTIDX=1
19568         local total=3
19569         local mdt_index
19570         local file
19571         local migrate_dir=$DIR/$tdir/migrate_dir
19572
19573         #If migrating directory fails in the middle, all entries of
19574         #the directory is still accessiable.
19575         test_mkdir $DIR/$tdir
19576         test_mkdir -i0 -c1 $migrate_dir
19577         test_mkdir -i1 -c1 $DIR/$tdir/remote_dir
19578         stat $migrate_dir
19579         createmany -o $migrate_dir/f $total ||
19580                 error "create files under ${migrate_dir} failed"
19581
19582         # fail after migrating top dir, and this will fail only once, so the
19583         # first sub file migration will fail (currently f3), others succeed.
19584         #OBD_FAIL_MIGRATE_ENTRIES       0x1801
19585         do_facet mds1 lctl set_param fail_loc=0x1801
19586         local t=$(ls $migrate_dir | wc -l)
19587         $LFS migrate --mdt-index $MDTIDX $migrate_dir &&
19588                 error "migrate should fail"
19589         local u=$(ls $migrate_dir | wc -l)
19590         [ "$u" == "$t" ] || error "$u != $t during migration"
19591
19592         # add new dir/file should succeed
19593         mkdir $migrate_dir/dir ||
19594                 error "mkdir failed under migrating directory"
19595         touch $migrate_dir/file ||
19596                 error "create file failed under migrating directory"
19597
19598         # add file with existing name should fail
19599         for file in $migrate_dir/f*; do
19600                 stat $file > /dev/null || error "stat $file failed"
19601                 $OPENFILE -f O_CREAT:O_EXCL $file &&
19602                         error "open(O_CREAT|O_EXCL) $file should fail"
19603                 $MULTIOP $file m && error "create $file should fail"
19604                 touch $DIR/$tdir/remote_dir/$tfile ||
19605                         error "touch $tfile failed"
19606                 ln $DIR/$tdir/remote_dir/$tfile $file &&
19607                         error "link $file should fail"
19608                 mdt_index=$($LFS getstripe -m $file)
19609                 if [ $mdt_index == 0 ]; then
19610                         # file failed to migrate is not allowed to rename to
19611                         mv $DIR/$tdir/remote_dir/$tfile $file &&
19612                                 error "rename to $file should fail"
19613                 else
19614                         mv $DIR/$tdir/remote_dir/$tfile $file ||
19615                                 error "rename to $file failed"
19616                 fi
19617                 echo hello >> $file || error "write $file failed"
19618         done
19619
19620         # resume migration with different options should fail
19621         $LFS migrate -m 0 $migrate_dir &&
19622                 error "migrate -m 0 $migrate_dir should fail"
19623
19624         $LFS migrate -m $MDTIDX -c 2 $migrate_dir &&
19625                 error "migrate -c 2 $migrate_dir should fail"
19626
19627         # resume migration should succeed
19628         $LFS migrate -m $MDTIDX $migrate_dir ||
19629                 error "migrate $migrate_dir failed"
19630
19631         echo "Finish migration, then checking.."
19632         for file in $(find $migrate_dir); do
19633                 mdt_index=$($LFS getstripe -m $file)
19634                 [ $mdt_index == $MDTIDX ] ||
19635                         error "$file is not on MDT${MDTIDX}"
19636         done
19637
19638         rm -rf $DIR/$tdir || error "rm dir failed after migration"
19639 }
19640 run_test 230c "check directory accessiblity if migration failed"
19641
19642 test_230d() {
19643         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19644         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19645         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
19646                 skip "Need MDS version at least 2.11.52"
19647         # LU-11235
19648         [ "$mds1_FSTYPE" == "zfs" ] && skip "skip ZFS backend"
19649
19650         local migrate_dir=$DIR/$tdir/migrate_dir
19651         local old_index
19652         local new_index
19653         local old_count
19654         local new_count
19655         local new_hash
19656         local mdt_index
19657         local i
19658         local j
19659
19660         old_index=$((RANDOM % MDSCOUNT))
19661         old_count=$((MDSCOUNT - old_index))
19662         new_index=$((RANDOM % MDSCOUNT))
19663         new_count=$((MDSCOUNT - new_index))
19664         new_hash=1 # for all_char
19665
19666         [ $old_count -gt 1 ] && old_count=$((old_count - RANDOM % old_count))
19667         [ $new_count -gt 1 ] && new_count=$((new_count - RANDOM % new_count))
19668
19669         test_mkdir $DIR/$tdir
19670         test_mkdir -i $old_index -c $old_count $migrate_dir
19671
19672         for ((i=0; i<100; i++)); do
19673                 test_mkdir -i0 -c1 $migrate_dir/dir_${i}
19674                 createmany -o $migrate_dir/dir_${i}/f 100 ||
19675                         error "create files under remote dir failed $i"
19676         done
19677
19678         echo -n "Migrate from MDT$old_index "
19679         [ $old_count -gt 1 ] && echo -n "... MDT$((old_index + old_count - 1)) "
19680         echo -n "to MDT$new_index"
19681         [ $new_count -gt 1 ] && echo -n " ... MDT$((new_index + new_count - 1))"
19682         echo
19683
19684         echo "$LFS migrate -m$new_index -c$new_count -H $new_hash $migrate_dir"
19685         $LFS migrate -m $new_index -c $new_count -H $new_hash $migrate_dir ||
19686                 error "migrate remote dir error"
19687
19688         echo "Finish migration, then checking.."
19689         for file in $(find $migrate_dir -maxdepth 1); do
19690                 mdt_index=$($LFS getstripe -m $file)
19691                 if [ $mdt_index -lt $new_index ] ||
19692                    [ $mdt_index -gt $((new_index + new_count - 1)) ]; then
19693                         error "$file is on MDT$mdt_index"
19694                 fi
19695         done
19696
19697         rm -rf $DIR/$tdir || error "rm dir failed after migration"
19698 }
19699 run_test 230d "check migrate big directory"
19700
19701 test_230e() {
19702         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19703         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19704         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
19705                 skip "Need MDS version at least 2.11.52"
19706
19707         local i
19708         local j
19709         local a_fid
19710         local b_fid
19711
19712         mkdir_on_mdt0 $DIR/$tdir
19713         mkdir $DIR/$tdir/migrate_dir
19714         mkdir $DIR/$tdir/other_dir
19715         touch $DIR/$tdir/migrate_dir/a
19716         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/b
19717         ls $DIR/$tdir/other_dir
19718
19719         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
19720                 error "migrate dir fails"
19721
19722         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir)
19723         [ $mdt_index == 1 ] || error "migrate_dir is not on MDT1"
19724
19725         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
19726         [ $mdt_index == 0 ] || error "a is not on MDT0"
19727
19728         $LFS migrate -m 1 $DIR/$tdir/other_dir ||
19729                 error "migrate dir fails"
19730
19731         mdt_index=$($LFS getstripe -m $DIR/$tdir/other_dir)
19732         [ $mdt_index == 1 ] || error "other_dir is not on MDT1"
19733
19734         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
19735         [ $mdt_index == 1 ] || error "a is not on MDT1"
19736
19737         mdt_index=$($LFS getstripe -m $DIR/$tdir/other_dir/b)
19738         [ $mdt_index == 1 ] || error "b is not on MDT1"
19739
19740         a_fid=$($LFS path2fid $DIR/$tdir/migrate_dir/a)
19741         b_fid=$($LFS path2fid $DIR/$tdir/other_dir/b)
19742
19743         [ "$a_fid" = "$b_fid" ] || error "different fid after migration"
19744
19745         rm -rf $DIR/$tdir || error "rm dir failed after migration"
19746 }
19747 run_test 230e "migrate mulitple local link files"
19748
19749 test_230f() {
19750         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19751         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19752         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
19753                 skip "Need MDS version at least 2.11.52"
19754
19755         local a_fid
19756         local ln_fid
19757
19758         mkdir -p $DIR/$tdir
19759         mkdir $DIR/$tdir/migrate_dir
19760         $LFS mkdir -i1 $DIR/$tdir/other_dir
19761         touch $DIR/$tdir/migrate_dir/a
19762         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/ln1
19763         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/ln2
19764         ls $DIR/$tdir/other_dir
19765
19766         # a should be migrated to MDT1, since no other links on MDT0
19767         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
19768                 error "#1 migrate dir fails"
19769         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir)
19770         [ $mdt_index == 1 ] || error "migrate_dir is not on MDT1"
19771         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
19772         [ $mdt_index == 1 ] || error "a is not on MDT1"
19773
19774         # a should stay on MDT1, because it is a mulitple link file
19775         $LFS migrate -m 0 $DIR/$tdir/migrate_dir ||
19776                 error "#2 migrate dir fails"
19777         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
19778         [ $mdt_index == 1 ] || error "a is not on MDT1"
19779
19780         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
19781                 error "#3 migrate dir fails"
19782
19783         a_fid=$($LFS path2fid $DIR/$tdir/migrate_dir/a)
19784         ln_fid=$($LFS path2fid $DIR/$tdir/other_dir/ln1)
19785         [ "$a_fid" = "$ln_fid" ] || error "different fid after migrate to MDT1"
19786
19787         rm -rf $DIR/$tdir/other_dir/ln1 || error "unlink ln1 fails"
19788         rm -rf $DIR/$tdir/other_dir/ln2 || error "unlink ln2 fails"
19789
19790         # a should be migrated to MDT0, since no other links on MDT1
19791         $LFS migrate -m 0 $DIR/$tdir/migrate_dir ||
19792                 error "#4 migrate dir fails"
19793         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
19794         [ $mdt_index == 0 ] || error "a is not on MDT0"
19795
19796         rm -rf $DIR/$tdir || error "rm dir failed after migration"
19797 }
19798 run_test 230f "migrate mulitple remote link files"
19799
19800 test_230g() {
19801         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19802         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19803         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
19804                 skip "Need MDS version at least 2.11.52"
19805
19806         mkdir -p $DIR/$tdir/migrate_dir
19807
19808         $LFS migrate -m 1000 $DIR/$tdir/migrate_dir &&
19809                 error "migrating dir to non-exist MDT succeeds"
19810         true
19811 }
19812 run_test 230g "migrate dir to non-exist MDT"
19813
19814 test_230h() {
19815         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19816         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19817         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
19818                 skip "Need MDS version at least 2.11.52"
19819
19820         local mdt_index
19821
19822         mkdir -p $DIR/$tdir/migrate_dir
19823
19824         $LFS migrate -m1 $DIR &&
19825                 error "migrating mountpoint1 should fail"
19826
19827         $LFS migrate -m1 $DIR/$tdir/.. &&
19828                 error "migrating mountpoint2 should fail"
19829
19830         # same as mv
19831         $LFS migrate -m1 $DIR/$tdir/migrate_dir/.. &&
19832                 error "migrating $tdir/migrate_dir/.. should fail"
19833
19834         true
19835 }
19836 run_test 230h "migrate .. and root"
19837
19838 test_230i() {
19839         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19840         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19841         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
19842                 skip "Need MDS version at least 2.11.52"
19843
19844         mkdir -p $DIR/$tdir/migrate_dir
19845
19846         $LFS migrate -m 1 $DIR/$tdir/migrate_dir/ ||
19847                 error "migration fails with a tailing slash"
19848
19849         $LFS migrate -m 0 $DIR/$tdir/migrate_dir// ||
19850                 error "migration fails with two tailing slashes"
19851 }
19852 run_test 230i "lfs migrate -m tolerates trailing slashes"
19853
19854 test_230j() {
19855         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
19856         [ $MDS1_VERSION -lt $(version_code 2.13.52) ] &&
19857                 skip "Need MDS version at least 2.11.52"
19858
19859         $LFS mkdir -m 0 -c 1 $DIR/$tdir || error "mkdir $tdir failed"
19860         $LFS setstripe -E 1M -L mdt $DIR/$tdir/$tfile ||
19861                 error "create $tfile failed"
19862         cat /etc/passwd > $DIR/$tdir/$tfile
19863
19864         $LFS migrate -m 1 $DIR/$tdir || error "migrate failed"
19865
19866         cmp /etc/passwd $DIR/$tdir/$tfile ||
19867                 error "DoM file mismatch after migration"
19868 }
19869 run_test 230j "DoM file data not changed after dir migration"
19870
19871 test_230k() {
19872         [ $MDSCOUNT -lt 4 ] && skip "needs >= 4 MDTs"
19873         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
19874                 skip "Need MDS version at least 2.11.56"
19875
19876         local total=20
19877         local files_on_starting_mdt=0
19878
19879         $LFS mkdir -i -1 -c 2 $DIR/$tdir || error "mkdir failed"
19880         $LFS getdirstripe $DIR/$tdir
19881         for i in $(seq $total); do
19882                 echo $((i*i - i)) > $DIR/$tdir/$tfile.$i || error "write failed"
19883                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 0 ]] &&
19884                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
19885         done
19886
19887         echo "$files_on_starting_mdt files on MDT0"
19888
19889         $LFS migrate -m 1,3 $DIR/$tdir || error "migrate -m 1,3 failed"
19890         $LFS getdirstripe $DIR/$tdir
19891
19892         files_on_starting_mdt=0
19893         for i in $(seq $total); do
19894                 $(echo $((i*i - i)) | cmp $DIR/$tdir/$tfile.$i -) ||
19895                         error "file $tfile.$i mismatch after migration"
19896                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 1 ]] &&
19897                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
19898         done
19899
19900         echo "$files_on_starting_mdt files on MDT1 after migration"
19901         [[ $files_on_starting_mdt -eq $total ]] && error "all files on MDT1"
19902
19903         $LFS migrate -m 0 -c 2 $DIR/$tdir || error "migrate -m 0 -c 2 failed"
19904         $LFS getdirstripe $DIR/$tdir
19905
19906         files_on_starting_mdt=0
19907         for i in $(seq $total); do
19908                 $(echo $((i*i - i)) | cmp $DIR/$tdir/$tfile.$i -) ||
19909                         error "file $tfile.$i mismatch after 2nd migration"
19910                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 0 ]] &&
19911                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
19912         done
19913
19914         echo "$files_on_starting_mdt files on MDT0 after 2nd migration"
19915         [[ $files_on_starting_mdt -eq $total ]] && error "all files on MDT0"
19916
19917         true
19918 }
19919 run_test 230k "file data not changed after dir migration"
19920
19921 test_230l() {
19922         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
19923         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
19924                 skip "Need MDS version at least 2.11.56"
19925
19926         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "mkdir failed"
19927         createmany -o $DIR/$tdir/f___________________________________ 1000 ||
19928                 error "create files under remote dir failed $i"
19929         $LFS migrate -m 1 $DIR/$tdir || error "migrate failed"
19930 }
19931 run_test 230l "readdir between MDTs won't crash"
19932
19933 test_230m() {
19934         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
19935         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
19936                 skip "Need MDS version at least 2.11.56"
19937
19938         local MDTIDX=1
19939         local mig_dir=$DIR/$tdir/migrate_dir
19940         local longstr="aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
19941         local shortstr="b"
19942         local val
19943
19944         echo "Creating files and dirs with xattrs"
19945         test_mkdir $DIR/$tdir
19946         test_mkdir -i0 -c1 $mig_dir
19947         mkdir $mig_dir/dir
19948         setfattr -n user.attr1 -v $longstr $mig_dir/dir ||
19949                 error "cannot set xattr attr1 on dir"
19950         setfattr -n user.attr2 -v $shortstr $mig_dir/dir ||
19951                 error "cannot set xattr attr2 on dir"
19952         touch $mig_dir/dir/f0
19953         setfattr -n user.attr1 -v $longstr $mig_dir/dir/f0 ||
19954                 error "cannot set xattr attr1 on file"
19955         setfattr -n user.attr2 -v $shortstr $mig_dir/dir/f0 ||
19956                 error "cannot set xattr attr2 on file"
19957         sync ; sync ; echo 3 > /proc/sys/vm/drop_caches
19958         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir 2>/dev/null)
19959         [ "$val" = $longstr ] || error "xattr attr1 not set properly on dir"
19960         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir 2>/dev/null)
19961         [ "$val" = $shortstr ] || error "xattr attr2 not set properly on dir"
19962         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir/f0 2>/dev/null)
19963         [ "$val" = $longstr ] || error "xattr attr1 not set properly on file"
19964         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir/f0 2>/dev/null)
19965         [ "$val" = $shortstr ] || error "xattr attr2 not set properly on file"
19966
19967         echo "Migrating to MDT1"
19968         $LFS migrate -m $MDTIDX $mig_dir ||
19969                 error "fails on migrating dir to MDT1"
19970
19971         sync ; sync ; echo 3 > /proc/sys/vm/drop_caches
19972         echo "Checking xattrs"
19973         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir 2>/dev/null)
19974         [ "$val" = $longstr ] ||
19975                 error "expecting xattr1 $longstr on dir, found $val"
19976         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir 2>/dev/null)
19977         [ "$val" = $shortstr ] ||
19978                 error "expecting xattr2 $shortstr on dir, found $val"
19979         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir/f0 2>/dev/null)
19980         [ "$val" = $longstr ] ||
19981                 error "expecting xattr1 $longstr on file, found $val"
19982         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir/f0 2>/dev/null)
19983         [ "$val" = $shortstr ] ||
19984                 error "expecting xattr2 $shortstr on file, found $val"
19985 }
19986 run_test 230m "xattrs not changed after dir migration"
19987
19988 test_230n() {
19989         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
19990         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
19991                 skip "Need MDS version at least 2.13.53"
19992
19993         $LFS mkdir -i 0 $DIR/$tdir || error "mkdir $tdir failed"
19994         cat /etc/hosts > $DIR/$tdir/$tfile
19995         $LFS mirror extend -N1 $DIR/$tdir/$tfile || error "Mirroring failed"
19996         $LFS migrate -m 1 $DIR/$tdir || error "Migration failed"
19997
19998         cmp /etc/hosts $DIR/$tdir/$tfile ||
19999                 error "File data mismatch after migration"
20000 }
20001 run_test 230n "Dir migration with mirrored file"
20002
20003 test_230o() {
20004         [ $MDSCOUNT -ge 2 ] || skip "needs >= 2 MDTs"
20005         [ $MDS1_VERSION -ge $(version_code 2.13.52) ] ||
20006                 skip "Need MDS version at least 2.13.52"
20007
20008         local mdts=$(comma_list $(mdts_nodes))
20009         local timeout=100
20010         local restripe_status
20011         local delta
20012         local i
20013
20014         [[ $mds1_FSTYPE == zfs ]] && timeout=300
20015
20016         # in case "crush" hash type is not set
20017         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
20018
20019         restripe_status=$(do_facet mds1 $LCTL get_param -n \
20020                            mdt.*MDT0000.enable_dir_restripe)
20021         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=1"
20022         stack_trap "do_nodes $mdts $LCTL set_param \
20023                     mdt.*.enable_dir_restripe=$restripe_status"
20024
20025         mkdir $DIR/$tdir
20026         createmany -m $DIR/$tdir/f 100 ||
20027                 error "create files under remote dir failed $i"
20028         createmany -d $DIR/$tdir/d 100 ||
20029                 error "create dirs under remote dir failed $i"
20030
20031         for i in $(seq 2 $MDSCOUNT); do
20032                 do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear >/dev/null"
20033                 $LFS setdirstripe -c $i $DIR/$tdir ||
20034                         error "split -c $i $tdir failed"
20035                 wait_update $HOSTNAME \
20036                         "$LFS getdirstripe -H $DIR/$tdir" "crush" $timeout ||
20037                         error "dir split not finished"
20038                 delta=$(do_nodes $mdts "lctl get_param -n mdt.*MDT*.md_stats" |
20039                         awk '/migrate/ {sum += $2} END { print sum }')
20040                 echo "$delta migrated when dir split $((i - 1)) to $i stripes"
20041                 # delta is around total_files/stripe_count
20042                 (( $delta < 200 / (i - 1) + 4 )) ||
20043                         error "$delta files migrated >= $((200 / (i - 1) + 4))"
20044         done
20045 }
20046 run_test 230o "dir split"
20047
20048 test_230p() {
20049         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
20050         (( MDS1_VERSION >= $(version_code 2.13.52) )) ||
20051                 skip "Need MDS version at least 2.13.52"
20052
20053         local mdts=$(comma_list $(mdts_nodes))
20054         local timeout=100
20055         local restripe_status
20056         local delta
20057         local c
20058
20059         [[ $mds1_FSTYPE == zfs ]] && timeout=300
20060
20061         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
20062
20063         restripe_status=$(do_facet mds1 $LCTL get_param -n \
20064                            mdt.*MDT0000.enable_dir_restripe)
20065         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=1"
20066         stack_trap "do_nodes $mdts $LCTL set_param \
20067                     mdt.*.enable_dir_restripe=$restripe_status"
20068
20069         test_mkdir -c $MDSCOUNT -H crush $DIR/$tdir
20070         createmany -m $DIR/$tdir/f 100 ||
20071                 error "create files under remote dir failed"
20072         createmany -d $DIR/$tdir/d 100 ||
20073                 error "create dirs under remote dir failed"
20074
20075         for c in $(seq $((MDSCOUNT - 1)) -1 1); do
20076                 local mdt_hash="crush"
20077
20078                 do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear >/dev/null"
20079                 $LFS setdirstripe -c $c $DIR/$tdir ||
20080                         error "split -c $c $tdir failed"
20081                 if (( MDS1_VERSION >= $(version_code 2.14.51) )); then
20082                         mdt_hash="$mdt_hash,fixed"
20083                 elif [ $c -eq 1 ]; then
20084                         mdt_hash="none"
20085                 fi
20086                 wait_update $HOSTNAME \
20087                         "$LFS getdirstripe -H $DIR/$tdir" $mdt_hash $timeout ||
20088                         error "dir merge not finished"
20089                 delta=$(do_nodes $mdts "lctl get_param -n mdt.*MDT*.md_stats" |
20090                         awk '/migrate/ {sum += $2} END { print sum }')
20091                 echo "$delta migrated when dir merge $((c + 1)) to $c stripes"
20092                 # delta is around total_files/stripe_count
20093                 (( delta < 200 / c + 4 )) ||
20094                         error "$delta files migrated >= $((200 / c + 4))"
20095         done
20096 }
20097 run_test 230p "dir merge"
20098
20099 test_230q() {
20100         (( MDSCOUNT > 1)) || skip "needs >= 2 MDTs"
20101         (( MDS1_VERSION >= $(version_code 2.13.52) )) ||
20102                 skip "Need MDS version at least 2.13.52"
20103
20104         local mdts=$(comma_list $(mdts_nodes))
20105         local saved_threshold=$(do_facet mds1 \
20106                         $LCTL get_param -n mdt.*-MDT0000.dir_split_count)
20107         local saved_delta=$(do_facet mds1 \
20108                         $LCTL get_param -n mdt.*-MDT0000.dir_split_delta)
20109         local threshold=100
20110         local delta=2
20111         local total=0
20112         local stripe_count=0
20113         local stripe_index
20114         local nr_files
20115         local create
20116
20117         # test with fewer files on ZFS
20118         [ "$mds1_FSTYPE" == "zfs" ] && threshold=40
20119
20120         stack_trap "do_nodes $mdts $LCTL set_param \
20121                     mdt.*.dir_split_count=$saved_threshold"
20122         stack_trap "do_nodes $mdts $LCTL set_param \
20123                     mdt.*.dir_split_delta=$saved_delta"
20124         stack_trap "do_nodes $mdts $LCTL set_param mdt.*.dir_restripe_nsonly=1"
20125         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_auto_split=1"
20126         do_nodes $mdts "$LCTL set_param mdt.*.dir_split_count=$threshold"
20127         do_nodes $mdts "$LCTL set_param mdt.*.dir_split_delta=$delta"
20128         do_nodes $mdts "$LCTL set_param mdt.*.dir_restripe_nsonly=0"
20129         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
20130
20131         $LFS mkdir -i -1 -c 1 $DIR/$tdir || error "mkdir $tdir failed"
20132         stripe_index=$($LFS getdirstripe -i $DIR/$tdir)
20133
20134         create=$((threshold * 3 / 2))
20135         while [ $stripe_count -lt $MDSCOUNT ]; do
20136                 createmany -m $DIR/$tdir/f $total $create ||
20137                         error "create sub files failed"
20138                 stat $DIR/$tdir > /dev/null
20139                 total=$((total + create))
20140                 stripe_count=$((stripe_count + delta))
20141                 [ $stripe_count -gt $MDSCOUNT ] && stripe_count=$MDSCOUNT
20142
20143                 wait_update $HOSTNAME \
20144                         "$LFS getdirstripe -c $DIR/$tdir" "$stripe_count" 40 ||
20145                         error "stripe count $($LFS getdirstripe -c $DIR/$tdir) != $stripe_count"
20146
20147                 wait_update $HOSTNAME \
20148                         "$LFS getdirstripe -H $DIR/$tdir" "crush" 200 ||
20149                         error "stripe hash $($LFS getdirstripe -H $DIR/$tdir) != crush"
20150
20151                 nr_files=$($LFS find -m 1 $DIR/$tdir | grep -c -w $stripe_index)
20152                 echo "$nr_files/$total files on MDT$stripe_index after split"
20153                 # allow 10% margin of imbalance with crush hash
20154                 (( $nr_files <= $total / $stripe_count + $create / 10)) ||
20155                         error "$nr_files files on MDT$stripe_index after split"
20156
20157                 nr_files=$($LFS find -type f $DIR/$tdir | wc -l)
20158                 [ $nr_files -eq $total ] ||
20159                         error "total sub files $nr_files != $total"
20160         done
20161
20162         (( MDS1_VERSION >= $(version_code 2.14.51) )) || return 0
20163
20164         echo "fixed layout directory won't auto split"
20165         $LFS migrate -m 0 $DIR/$tdir || error "migrate $tdir failed"
20166         wait_update $HOSTNAME "$LFS getdirstripe -H $DIR/$tdir" "crush,fixed" \
20167                 10 || error "stripe hash $($LFS getdirstripe -H $DIR/$tdir)"
20168         wait_update $HOSTNAME "$LFS getdirstripe -c $DIR/$tdir" 1 10 ||
20169                 error "stripe count $($LFS getdirstripe -c $DIR/$tdir)"
20170 }
20171 run_test 230q "dir auto split"
20172
20173 test_230r() {
20174         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
20175         [[ $MDSCOUNT -ge 2 ]] || skip_env "needs >= 2 MDTs"
20176         [[ $MDS1_VERSION -ge $(version_code 2.13.54) ]] ||
20177                 skip "Need MDS version at least 2.13.54"
20178
20179         # maximum amount of local locks:
20180         # parent striped dir - 2 locks
20181         # new stripe in parent to migrate to - 1 lock
20182         # source and target - 2 locks
20183         # Total 5 locks for regular file
20184         mkdir -p $DIR/$tdir
20185         $LFS mkdir -i1 -c2 $DIR/$tdir/dir1
20186         touch $DIR/$tdir/dir1/eee
20187
20188         # create 4 hardlink for 4 more locks
20189         # Total: 9 locks > RS_MAX_LOCKS (8)
20190         $LFS mkdir -i1 -c1 $DIR/$tdir/dir2
20191         $LFS mkdir -i1 -c1 $DIR/$tdir/dir3
20192         $LFS mkdir -i1 -c1 $DIR/$tdir/dir4
20193         $LFS mkdir -i1 -c1 $DIR/$tdir/dir5
20194         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir2/eee
20195         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir3/eee
20196         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir4/eee
20197         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir5/eee
20198
20199         cancel_lru_locks mdc
20200
20201         $LFS migrate -m1 -c1 $DIR/$tdir/dir1 ||
20202                 error "migrate dir fails"
20203
20204         rm -rf $DIR/$tdir || error "rm dir failed after migration"
20205 }
20206 run_test 230r "migrate with too many local locks"
20207
20208 test_230s() {
20209         [ $MDS1_VERSION -ge $(version_code 2.13.57) ] ||
20210                 skip "Need MDS version at least 2.13.57"
20211
20212         local mdts=$(comma_list $(mdts_nodes))
20213         local restripe_status=$(do_facet mds1 $LCTL get_param -n \
20214                                 mdt.*MDT0000.enable_dir_restripe)
20215
20216         stack_trap "do_nodes $mdts $LCTL set_param \
20217                     mdt.*.enable_dir_restripe=$restripe_status"
20218
20219         local st
20220         for st in 0 1; do
20221                 do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=$st"
20222                 test_mkdir $DIR/$tdir
20223                 $LFS mkdir $DIR/$tdir |& grep "File exists" ||
20224                         error "$LFS mkdir doesn't return -EEXIST if target exists"
20225                 rmdir $DIR/$tdir
20226         done
20227 }
20228 run_test 230s "lfs mkdir should return -EEXIST if target exists"
20229
20230 test_230t()
20231 {
20232         [[ $MDSCOUNT -ge 2 ]] || skip_env "needs >= 2 MDTs"
20233         [[ $MDS1_VERSION -ge $(version_code 2.14.50) ]] ||
20234                 skip "Need MDS version at least 2.14.50"
20235
20236         test_mkdir $DIR/$tdir || error "mkdir $tdir failed"
20237         test_mkdir $DIR/$tdir/subdir || error "mkdir subdir failed"
20238         $LFS project -p 1 -s $DIR/$tdir ||
20239                 error "set $tdir project id failed"
20240         $LFS project -p 2 -s $DIR/$tdir/subdir ||
20241                 error "set subdir project id failed"
20242         $LFS migrate -m 1 -c $MDSCOUNT $DIR/$tdir || error "migrate failed"
20243 }
20244 run_test 230t "migrate directory with project ID set"
20245
20246 test_230u()
20247 {
20248         (( MDSCOUNT > 3 )) || skip_env "needs >= 4 MDTs"
20249         (( MDS1_VERSION >= $(version_code 2.14.53) )) ||
20250                 skip "Need MDS version at least 2.14.53"
20251
20252         local count
20253
20254         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
20255         mkdir $DIR/$tdir/sub{0..99} || error "mkdir sub failed"
20256         $LFS migrate -m -1 $DIR/$tdir/sub{0..99} || error "migrate sub failed"
20257         for i in $(seq 0 $((MDSCOUNT - 1))); do
20258                 count=$($LFS getstripe -m $DIR/$tdir/sub* | grep -c ^$i)
20259                 echo "$count dirs migrated to MDT$i"
20260         done
20261         count=$($LFS getstripe -m $DIR/$tdir/sub* | sort -u | wc -l)
20262         (( count >= MDSCOUNT - 1 )) || error "dirs migrated to $count MDTs"
20263 }
20264 run_test 230u "migrate directory by QOS"
20265
20266 test_230v()
20267 {
20268         (( MDSCOUNT > 3 )) || skip_env "needs >= 4 MDTs"
20269         (( MDS1_VERSION >= $(version_code 2.14.53) )) ||
20270                 skip "Need MDS version at least 2.14.53"
20271
20272         local count
20273
20274         mkdir $DIR/$tdir || error "mkdir $tdir failed"
20275         mkdir $DIR/$tdir/sub{0..99} || error "mkdir sub failed"
20276         $LFS migrate -m 0,2,1 $DIR/$tdir || error "migrate $tdir failed"
20277         for i in $(seq 0 $((MDSCOUNT - 1))); do
20278                 count=$($LFS getstripe -m $DIR/$tdir/sub* | grep -c ^$i)
20279                 echo "$count subdirs migrated to MDT$i"
20280                 (( i == 3 )) && (( count > 0 )) &&
20281                         error "subdir shouldn't be migrated to MDT3"
20282         done
20283         count=$($LFS getstripe -m $DIR/$tdir/sub* | sort -u | wc -l)
20284         (( count == 3 )) || error "dirs migrated to $count MDTs"
20285 }
20286 run_test 230v "subdir migrated to the MDT where its parent is located"
20287
20288 test_231a()
20289 {
20290         # For simplicity this test assumes that max_pages_per_rpc
20291         # is the same across all OSCs
20292         local max_pages=$($LCTL get_param -n osc.*.max_pages_per_rpc | head -n1)
20293         local bulk_size=$((max_pages * PAGE_SIZE))
20294         local brw_size=$(do_facet ost1 $LCTL get_param -n obdfilter.*.brw_size |
20295                                        head -n 1)
20296
20297         mkdir -p $DIR/$tdir
20298         $LFS setstripe -S ${brw_size}M $DIR/$tdir ||
20299                 error "failed to set stripe with -S ${brw_size}M option"
20300
20301         # clear the OSC stats
20302         $LCTL set_param osc.*.stats=0 &>/dev/null
20303         stop_writeback
20304
20305         # Client writes $bulk_size - there must be 1 rpc for $max_pages.
20306         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=$bulk_size count=1 \
20307                 oflag=direct &>/dev/null || error "dd failed"
20308
20309         sync; sleep 1; sync # just to be safe
20310         local nrpcs=$($LCTL get_param osc.*.stats |awk '/ost_write/ {print $2}')
20311         if [ x$nrpcs != "x1" ]; then
20312                 $LCTL get_param osc.*.stats
20313                 error "found $nrpcs ost_write RPCs, not 1 as expected"
20314         fi
20315
20316         start_writeback
20317         # Drop the OSC cache, otherwise we will read from it
20318         cancel_lru_locks osc
20319
20320         # clear the OSC stats
20321         $LCTL set_param osc.*.stats=0 &>/dev/null
20322
20323         # Client reads $bulk_size.
20324         dd if=$DIR/$tdir/$tfile of=/dev/null bs=$bulk_size count=1 \
20325                 iflag=direct &>/dev/null || error "dd failed"
20326
20327         nrpcs=$($LCTL get_param osc.*.stats | awk '/ost_read/ { print $2 }')
20328         if [ x$nrpcs != "x1" ]; then
20329                 $LCTL get_param osc.*.stats
20330                 error "found $nrpcs ost_read RPCs, not 1 as expected"
20331         fi
20332 }
20333 run_test 231a "checking that reading/writing of BRW RPC size results in one RPC"
20334
20335 test_231b() {
20336         mkdir -p $DIR/$tdir
20337         local i
20338         for i in {0..1023}; do
20339                 dd if=/dev/zero of=$DIR/$tdir/$tfile conv=notrunc \
20340                         seek=$((2 * i)) bs=4096 count=1 &>/dev/null ||
20341                         error "dd of=$DIR/$tdir/$tfile seek=$((2 * i)) failed"
20342         done
20343         sync
20344 }
20345 run_test 231b "must not assert on fully utilized OST request buffer"
20346
20347 test_232a() {
20348         mkdir -p $DIR/$tdir
20349         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
20350
20351         #define OBD_FAIL_LDLM_OST_LVB            0x31c
20352         do_facet ost1 $LCTL set_param fail_loc=0x31c
20353
20354         # ignore dd failure
20355         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=1 || true
20356
20357         do_facet ost1 $LCTL set_param fail_loc=0
20358         umount_client $MOUNT || error "umount failed"
20359         mount_client $MOUNT || error "mount failed"
20360         stop ost1 || error "cannot stop ost1"
20361         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
20362 }
20363 run_test 232a "failed lock should not block umount"
20364
20365 test_232b() {
20366         [ $MDS1_VERSION -ge $(version_code 2.10.58) ] ||
20367                 skip "Need MDS version at least 2.10.58"
20368
20369         mkdir -p $DIR/$tdir
20370         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
20371         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=1
20372         sync
20373         cancel_lru_locks osc
20374
20375         #define OBD_FAIL_LDLM_OST_LVB            0x31c
20376         do_facet ost1 $LCTL set_param fail_loc=0x31c
20377
20378         # ignore failure
20379         $LFS data_version $DIR/$tdir/$tfile || true
20380
20381         do_facet ost1 $LCTL set_param fail_loc=0
20382         umount_client $MOUNT || error "umount failed"
20383         mount_client $MOUNT || error "mount failed"
20384         stop ost1 || error "cannot stop ost1"
20385         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
20386 }
20387 run_test 232b "failed data version lock should not block umount"
20388
20389 test_233a() {
20390         [ $MDS1_VERSION -ge $(version_code 2.3.64) ] ||
20391                 skip "Need MDS version at least 2.3.64"
20392         [ -n "$FILESET" ] && skip_env "SKIP due to FILESET set"
20393
20394         local fid=$($LFS path2fid $MOUNT)
20395
20396         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
20397                 error "cannot access $MOUNT using its FID '$fid'"
20398 }
20399 run_test 233a "checking that OBF of the FS root succeeds"
20400
20401 test_233b() {
20402         [ $MDS1_VERSION -ge $(version_code 2.5.90) ] ||
20403                 skip "Need MDS version at least 2.5.90"
20404         [ -n "$FILESET" ] && skip_env "SKIP due to FILESET set"
20405
20406         local fid=$($LFS path2fid $MOUNT/.lustre)
20407
20408         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
20409                 error "cannot access $MOUNT/.lustre using its FID '$fid'"
20410
20411         fid=$($LFS path2fid $MOUNT/.lustre/fid)
20412         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
20413                 error "cannot access $MOUNT/.lustre/fid using its FID '$fid'"
20414 }
20415 run_test 233b "checking that OBF of the FS .lustre succeeds"
20416
20417 test_234() {
20418         local p="$TMP/sanityN-$TESTNAME.parameters"
20419         save_lustre_params client "llite.*.xattr_cache" > $p
20420         lctl set_param llite.*.xattr_cache 1 ||
20421                 skip_env "xattr cache is not supported"
20422
20423         mkdir -p $DIR/$tdir || error "mkdir failed"
20424         touch $DIR/$tdir/$tfile || error "touch failed"
20425         # OBD_FAIL_LLITE_XATTR_ENOMEM
20426         $LCTL set_param fail_loc=0x1405
20427         getfattr -n user.attr $DIR/$tdir/$tfile &&
20428                 error "getfattr should have failed with ENOMEM"
20429         $LCTL set_param fail_loc=0x0
20430         rm -rf $DIR/$tdir
20431
20432         restore_lustre_params < $p
20433         rm -f $p
20434 }
20435 run_test 234 "xattr cache should not crash on ENOMEM"
20436
20437 test_235() {
20438         [ $MDS1_VERSION -lt $(version_code 2.4.52) ] &&
20439                 skip "Need MDS version at least 2.4.52"
20440
20441         flock_deadlock $DIR/$tfile
20442         local RC=$?
20443         case $RC in
20444                 0)
20445                 ;;
20446                 124) error "process hangs on a deadlock"
20447                 ;;
20448                 *) error "error executing flock_deadlock $DIR/$tfile"
20449                 ;;
20450         esac
20451 }
20452 run_test 235 "LU-1715: flock deadlock detection does not work properly"
20453
20454 #LU-2935
20455 test_236() {
20456         check_swap_layouts_support
20457
20458         local ref1=/etc/passwd
20459         local ref2=/etc/group
20460         local file1=$DIR/$tdir/f1
20461         local file2=$DIR/$tdir/f2
20462
20463         test_mkdir -c1 $DIR/$tdir
20464         $LFS setstripe -c 1 $file1 || error "cannot setstripe on '$file1': rc = $?"
20465         cp $ref1 $file1 || error "cp $ref1 $file1 failed: rc = $?"
20466         $LFS setstripe -c 2 $file2 || error "cannot setstripe on '$file2': rc = $?"
20467         cp $ref2 $file2 || error "cp $ref2 $file2 failed: rc = $?"
20468         local fd=$(free_fd)
20469         local cmd="exec $fd<>$file2"
20470         eval $cmd
20471         rm $file2
20472         $LFS swap_layouts $file1 /proc/self/fd/${fd} ||
20473                 error "cannot swap layouts of '$file1' and /proc/self/fd/${fd}"
20474         cmd="exec $fd>&-"
20475         eval $cmd
20476         cmp $ref2 $file1 || error "content compare failed ($ref2 != $file1)"
20477
20478         #cleanup
20479         rm -rf $DIR/$tdir
20480 }
20481 run_test 236 "Layout swap on open unlinked file"
20482
20483 # LU-4659 linkea consistency
20484 test_238() {
20485         [[ $MDS1_VERSION -gt $(version_code 2.5.57) ]] ||
20486                 [[ $MDS1_VERSION -gt $(version_code 2.5.1) &&
20487                    $MDS1_VERSION -lt $(version_code 2.5.50) ]] ||
20488                 skip "Need MDS version at least 2.5.58 or 2.5.2+"
20489
20490         touch $DIR/$tfile
20491         ln $DIR/$tfile $DIR/$tfile.lnk
20492         touch $DIR/$tfile.new
20493         mv $DIR/$tfile.new $DIR/$tfile
20494         local fid1=$($LFS path2fid $DIR/$tfile)
20495         local fid2=$($LFS path2fid $DIR/$tfile.lnk)
20496         local path1=$($LFS fid2path $FSNAME "$fid1")
20497         [ $tfile == $path1 ] || error "linkea inconsistent: $tfile $fid1 $path1"
20498         local path2=$($LFS fid2path $FSNAME "$fid2")
20499         [ $tfile.lnk == $path2 ] ||
20500                 error "linkea inconsistent: $tfile.lnk $fid2 $path2!"
20501         rm -f $DIR/$tfile*
20502 }
20503 run_test 238 "Verify linkea consistency"
20504
20505 test_239A() { # was test_239
20506         [ $MDS1_VERSION -lt $(version_code 2.5.60) ] &&
20507                 skip "Need MDS version at least 2.5.60"
20508
20509         local list=$(comma_list $(mdts_nodes))
20510
20511         mkdir -p $DIR/$tdir
20512         createmany -o $DIR/$tdir/f- 5000
20513         unlinkmany $DIR/$tdir/f- 5000
20514         [ $MDS1_VERSION -gt $(version_code 2.10.4) ] &&
20515                 do_nodes $list "lctl set_param -n osp.*.force_sync=1"
20516         changes=$(do_nodes $list "lctl get_param -n osp.*MDT*.sync_changes \
20517                         osp.*MDT*.sync_in_flight" | calc_sum)
20518         [ "$changes" -eq 0 ] || error "$changes not synced"
20519 }
20520 run_test 239A "osp_sync test"
20521
20522 test_239a() { #LU-5297
20523         remote_mds_nodsh && skip "remote MDS with nodsh"
20524
20525         touch $DIR/$tfile
20526         #define OBD_FAIL_OSP_CHECK_INVALID_REC     0x2100
20527         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2100
20528         chgrp $RUNAS_GID $DIR/$tfile
20529         wait_delete_completed
20530 }
20531 run_test 239a "process invalid osp sync record correctly"
20532
20533 test_239b() { #LU-5297
20534         remote_mds_nodsh && skip "remote MDS with nodsh"
20535
20536         touch $DIR/$tfile1
20537         #define OBD_FAIL_OSP_CHECK_ENOMEM     0x2101
20538         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2101
20539         chgrp $RUNAS_GID $DIR/$tfile1
20540         wait_delete_completed
20541         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
20542         touch $DIR/$tfile2
20543         chgrp $RUNAS_GID $DIR/$tfile2
20544         wait_delete_completed
20545 }
20546 run_test 239b "process osp sync record with ENOMEM error correctly"
20547
20548 test_240() {
20549         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20550         remote_mds_nodsh && skip "remote MDS with nodsh"
20551
20552         mkdir -p $DIR/$tdir
20553
20554         $LFS mkdir -i 0 $DIR/$tdir/d0 ||
20555                 error "failed to mkdir $DIR/$tdir/d0 on MDT0"
20556         $LFS mkdir -i 1 $DIR/$tdir/d0/d1 ||
20557                 error "failed to mkdir $DIR/$tdir/d0/d1 on MDT1"
20558
20559         umount_client $MOUNT || error "umount failed"
20560         #define OBD_FAIL_TGT_DELAY_CONDITIONAL   0x713
20561         do_facet mds2 lctl set_param fail_loc=0x713 fail_val=1
20562         mount_client $MOUNT || error "failed to mount client"
20563
20564         echo "stat $DIR/$tdir/d0/d1, should not fail/ASSERT"
20565         stat $DIR/$tdir/d0/d1 || error "fail to stat $DIR/$tdir/d0/d1"
20566 }
20567 run_test 240 "race between ldlm enqueue and the connection RPC (no ASSERT)"
20568
20569 test_241_bio() {
20570         local count=$1
20571         local bsize=$2
20572
20573         for LOOP in $(seq $count); do
20574                 dd if=$DIR/$tfile of=/dev/null bs=$bsize count=1 2>/dev/null
20575                 cancel_lru_locks $OSC || true
20576         done
20577 }
20578
20579 test_241_dio() {
20580         local count=$1
20581         local bsize=$2
20582
20583         for LOOP in $(seq $1); do
20584                 dd if=$DIR/$tfile of=/dev/null bs=$bsize count=1 iflag=direct \
20585                         2>/dev/null
20586         done
20587 }
20588
20589 test_241a() { # was test_241
20590         local bsize=$PAGE_SIZE
20591
20592         (( bsize < 40960 )) && bsize=40960
20593         dd if=/dev/zero of=$DIR/$tfile count=1 bs=$bsize
20594         ls -la $DIR/$tfile
20595         cancel_lru_locks $OSC
20596         test_241_bio 1000 $bsize &
20597         PID=$!
20598         test_241_dio 1000 $bsize
20599         wait $PID
20600 }
20601 run_test 241a "bio vs dio"
20602
20603 test_241b() {
20604         local bsize=$PAGE_SIZE
20605
20606         (( bsize < 40960 )) && bsize=40960
20607         dd if=/dev/zero of=$DIR/$tfile count=1 bs=$bsize
20608         ls -la $DIR/$tfile
20609         test_241_dio 1000 $bsize &
20610         PID=$!
20611         test_241_dio 1000 $bsize
20612         wait $PID
20613 }
20614 run_test 241b "dio vs dio"
20615
20616 test_242() {
20617         remote_mds_nodsh && skip "remote MDS with nodsh"
20618
20619         mkdir_on_mdt0 $DIR/$tdir
20620         touch $DIR/$tdir/$tfile
20621
20622         #define OBD_FAIL_MDS_READPAGE_PACK      0x105
20623         do_facet mds1 lctl set_param fail_loc=0x105
20624         /bin/ls $DIR/$tdir && error "ls $DIR/$tdir should fail"
20625
20626         do_facet mds1 lctl set_param fail_loc=0
20627         /bin/ls $DIR/$tdir || error "ls $DIR/$tdir failed"
20628 }
20629 run_test 242 "mdt_readpage failure should not cause directory unreadable"
20630
20631 test_243()
20632 {
20633         test_mkdir $DIR/$tdir
20634         group_lock_test -d $DIR/$tdir || error "A group lock test failed"
20635 }
20636 run_test 243 "various group lock tests"
20637
20638 test_244a()
20639 {
20640         test_mkdir $DIR/$tdir
20641         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=35
20642         sendfile_grouplock $DIR/$tdir/$tfile || \
20643                 error "sendfile+grouplock failed"
20644         rm -rf $DIR/$tdir
20645 }
20646 run_test 244a "sendfile with group lock tests"
20647
20648 test_244b()
20649 {
20650         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
20651
20652         local threads=50
20653         local size=$((1024*1024))
20654
20655         test_mkdir $DIR/$tdir
20656         for i in $(seq 1 $threads); do
20657                 local file=$DIR/$tdir/file_$((i / 10))
20658                 $MULTIOP $file OG1234w$size_$((i % 3))w$size_$((i % 4))g1234c &
20659                 local pids[$i]=$!
20660         done
20661         for i in $(seq 1 $threads); do
20662                 wait ${pids[$i]}
20663         done
20664 }
20665 run_test 244b "multi-threaded write with group lock"
20666
20667 test_245() {
20668         local flagname="multi_mod_rpcs"
20669         local connect_data_name="max_mod_rpcs"
20670         local out
20671
20672         # check if multiple modify RPCs flag is set
20673         out=$($LCTL get_param mdc.$FSNAME-MDT0000-*.import |
20674                 grep "connect_flags:")
20675         echo "$out"
20676
20677         echo "$out" | grep -qw $flagname
20678         if [ $? -ne 0 ]; then
20679                 echo "connect flag $flagname is not set"
20680                 return
20681         fi
20682
20683         # check if multiple modify RPCs data is set
20684         out=$($LCTL get_param mdc.$FSNAME-MDT0000-*.import)
20685         echo "$out"
20686
20687         echo "$out" | grep -qw $connect_data_name ||
20688                 error "import should have connect data $connect_data_name"
20689 }
20690 run_test 245 "check mdc connection flag/data: multiple modify RPCs"
20691
20692 cleanup_247() {
20693         local submount=$1
20694
20695         trap 0
20696         umount_client $submount
20697         rmdir $submount
20698 }
20699
20700 test_247a() {
20701         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
20702                 grep -q subtree ||
20703                 skip_env "Fileset feature is not supported"
20704
20705         local submount=${MOUNT}_$tdir
20706
20707         mkdir $MOUNT/$tdir
20708         mkdir -p $submount || error "mkdir $submount failed"
20709         FILESET="$FILESET/$tdir" mount_client $submount ||
20710                 error "mount $submount failed"
20711         trap "cleanup_247 $submount" EXIT
20712         echo foo > $submount/$tfile || error "write $submount/$tfile failed"
20713         [ $(cat $MOUNT/$tdir/$tfile) = "foo" ] ||
20714                 error "read $MOUNT/$tdir/$tfile failed"
20715         cleanup_247 $submount
20716 }
20717 run_test 247a "mount subdir as fileset"
20718
20719 test_247b() {
20720         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
20721                 skip_env "Fileset feature is not supported"
20722
20723         local submount=${MOUNT}_$tdir
20724
20725         rm -rf $MOUNT/$tdir
20726         mkdir -p $submount || error "mkdir $submount failed"
20727         SKIP_FILESET=1
20728         FILESET="$FILESET/$tdir" mount_client $submount &&
20729                 error "mount $submount should fail"
20730         rmdir $submount
20731 }
20732 run_test 247b "mount subdir that dose not exist"
20733
20734 test_247c() {
20735         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
20736                 skip_env "Fileset feature is not supported"
20737
20738         local submount=${MOUNT}_$tdir
20739
20740         mkdir -p $MOUNT/$tdir/dir1
20741         mkdir -p $submount || error "mkdir $submount failed"
20742         trap "cleanup_247 $submount" EXIT
20743         FILESET="$FILESET/$tdir" mount_client $submount ||
20744                 error "mount $submount failed"
20745         local fid=$($LFS path2fid $MOUNT/)
20746         $LFS fid2path $submount $fid && error "fid2path should fail"
20747         cleanup_247 $submount
20748 }
20749 run_test 247c "running fid2path outside subdirectory root"
20750
20751 test_247d() {
20752         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
20753                 skip "Fileset feature is not supported"
20754
20755         local submount=${MOUNT}_$tdir
20756
20757         mkdir -p $MOUNT/$tdir/dir1
20758         mkdir -p $submount || error "mkdir $submount failed"
20759         FILESET="$FILESET/$tdir" mount_client $submount ||
20760                 error "mount $submount failed"
20761         trap "cleanup_247 $submount" EXIT
20762
20763         local td=$submount/dir1
20764         local fid=$($LFS path2fid $td)
20765         [ -z "$fid" ] && error "path2fid unable to get $td FID"
20766
20767         # check that we get the same pathname back
20768         local rootpath
20769         local found
20770         for rootpath in "$submount" "$submount///" "$submount/dir1"; do
20771                 echo "$rootpath $fid"
20772                 found=$($LFS fid2path $rootpath "$fid")
20773                 [ -n "found" ] || error "fid2path should succeed"
20774                 [ "$found" == "$td" ] || error "fid2path $found != $td"
20775         done
20776         # check wrong root path format
20777         rootpath=$submount"_wrong"
20778         found=$($LFS fid2path $rootpath "$fid")
20779         [ -z "$found" ] || error "fid2path should fail ($rootpath != $submount)"
20780
20781         cleanup_247 $submount
20782 }
20783 run_test 247d "running fid2path inside subdirectory root"
20784
20785 # LU-8037
20786 test_247e() {
20787         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
20788                 grep -q subtree ||
20789                 skip "Fileset feature is not supported"
20790
20791         local submount=${MOUNT}_$tdir
20792
20793         mkdir $MOUNT/$tdir
20794         mkdir -p $submount || error "mkdir $submount failed"
20795         FILESET="$FILESET/.." mount_client $submount &&
20796                 error "mount $submount should fail"
20797         rmdir $submount
20798 }
20799 run_test 247e "mount .. as fileset"
20800
20801 test_247f() {
20802         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20803         [ $MDS1_VERSION -lt $(version_code 2.13.52) ] &&
20804                 skip "Need at least version 2.13.52"
20805         [ $CLIENT_VERSION -lt $(version_code 2.14.50) ] &&
20806                 skip "Need at least version 2.14.50"
20807         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
20808                 grep -q subtree ||
20809                 skip "Fileset feature is not supported"
20810
20811         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
20812         $LFS mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir/remote ||
20813                 error "mkdir remote failed"
20814         $LFS mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir/remote/subdir ||
20815                 error "mkdir remote/subdir failed"
20816         $LFS mkdir -i 0 -c $MDSCOUNT $DIR/$tdir/striped ||
20817                 error "mkdir striped failed"
20818         mkdir $DIR/$tdir/striped/subdir || error "mkdir striped/subdir failed"
20819
20820         local submount=${MOUNT}_$tdir
20821
20822         mkdir -p $submount || error "mkdir $submount failed"
20823         stack_trap "rmdir $submount"
20824
20825         local dir
20826         local stat
20827         local fileset=$FILESET
20828         local mdts=$(comma_list $(mdts_nodes))
20829
20830         stat=$(do_facet mds1 $LCTL get_param -n \
20831                 mdt.*MDT0000.enable_remote_subdir_mount)
20832         stack_trap "do_nodes $mdts $LCTL set_param \
20833                 mdt.*.enable_remote_subdir_mount=$stat"
20834
20835         do_nodes $mdts "$LCTL set_param mdt.*.enable_remote_subdir_mount=0"
20836         stack_trap "umount_client $submount"
20837         FILESET="$fileset/$tdir/remote" mount_client $submount &&
20838                 error "mount remote dir $dir should fail"
20839
20840         for dir in $tdir/remote/subdir $tdir/striped $tdir/striped/subdir \
20841                 $tdir/striped/. ; do
20842                 FILESET="$fileset/$dir" mount_client $submount ||
20843                         error "mount $dir failed"
20844                 umount_client $submount
20845         done
20846
20847         do_nodes $mdts "$LCTL set_param mdt.*.enable_remote_subdir_mount=1"
20848         FILESET="$fileset/$tdir/remote" mount_client $submount ||
20849                 error "mount $tdir/remote failed"
20850 }
20851 run_test 247f "mount striped or remote directory as fileset"
20852
20853 test_247g() {
20854         [ $MDSCOUNT -lt 4 ] && skip_env "needs >= 4 MDTs"
20855         [ $CLIENT_VERSION -lt $(version_code 2.14.50) ] &&
20856                 skip "Need at least version 2.14.50"
20857
20858         $LFS mkdir -i 0 -c 4 -H fnv_1a_64 $DIR/$tdir ||
20859                 error "mkdir $tdir failed"
20860         touch $DIR/$tdir/$tfile || error "touch $tfile failed"
20861
20862         local submount=${MOUNT}_$tdir
20863
20864         mkdir -p $submount || error "mkdir $submount failed"
20865         stack_trap "rmdir $submount"
20866
20867         FILESET="$fileset/$tdir" mount_client $submount ||
20868                 error "mount $dir failed"
20869         stack_trap "umount $submount"
20870
20871         local mdts=$(comma_list $(mdts_nodes))
20872
20873         local nrpcs
20874
20875         stat $submount > /dev/null
20876         cancel_lru_locks $MDC
20877         stat $submount > /dev/null
20878         stat $submount/$tfile > /dev/null
20879         do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear > /dev/null"
20880         stat $submount/$tfile > /dev/null
20881         nrpcs=$(do_nodes $mdts "lctl get_param -n mdt.*.md_stats" |
20882                 awk '/getattr/ {sum += $2} END {print sum}')
20883
20884         [ -z "$nrpcs" ] || error "$nrpcs extra getattr sent"
20885 }
20886 run_test 247g "mount striped directory as fileset caches ROOT lookup lock"
20887
20888 test_248a() {
20889         local fast_read_sav=$($LCTL get_param -n llite.*.fast_read 2>/dev/null)
20890         [ -z "$fast_read_sav" ] && skip "no fast read support"
20891
20892         # create a large file for fast read verification
20893         dd if=/dev/zero of=$DIR/$tfile bs=1M count=128 > /dev/null 2>&1
20894
20895         # make sure the file is created correctly
20896         $CHECKSTAT -s $((128*1024*1024)) $DIR/$tfile ||
20897                 { rm -f $DIR/$tfile; skip "file creation error"; }
20898
20899         echo "Test 1: verify that fast read is 4 times faster on cache read"
20900
20901         # small read with fast read enabled
20902         $LCTL set_param -n llite.*.fast_read=1
20903         local t_fast=$(dd if=$DIR/$tfile of=/dev/null bs=4k 2>&1 |
20904                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
20905                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
20906         # small read with fast read disabled
20907         $LCTL set_param -n llite.*.fast_read=0
20908         local t_slow=$(dd if=$DIR/$tfile of=/dev/null bs=4k 2>&1 |
20909                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
20910                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
20911
20912         # verify that fast read is 4 times faster for cache read
20913         [ $(bc <<< "4 * $t_fast < $t_slow") -eq 1 ] ||
20914                 error_not_in_vm "fast read was not 4 times faster: " \
20915                            "$t_fast vs $t_slow"
20916
20917         echo "Test 2: verify the performance between big and small read"
20918         $LCTL set_param -n llite.*.fast_read=1
20919
20920         # 1k non-cache read
20921         cancel_lru_locks osc
20922         local t_1k=$(dd if=$DIR/$tfile of=/dev/null bs=1k 2>&1 |
20923                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
20924                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
20925
20926         # 1M non-cache read
20927         cancel_lru_locks osc
20928         local t_1m=$(dd if=$DIR/$tfile of=/dev/null bs=1k 2>&1 |
20929                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
20930                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
20931
20932         # verify that big IO is not 4 times faster than small IO
20933         [ $(bc <<< "4 * $t_1k >= $t_1m") -eq 1 ] ||
20934                 error_not_in_vm "bigger IO is way too fast: $t_1k vs $t_1m"
20935
20936         $LCTL set_param -n llite.*.fast_read=$fast_read_sav
20937         rm -f $DIR/$tfile
20938 }
20939 run_test 248a "fast read verification"
20940
20941 test_248b() {
20942         # Default short_io_bytes=16384, try both smaller and larger sizes.
20943         # Lustre O_DIRECT read and write needs to be a multiple of PAGE_SIZE.
20944         # 6017024 = 2^12*13*113 = 47008*128 = 11752*512 = 4096*1469 = 53248*113
20945         echo "bs=53248 count=113 normal buffered write"
20946         dd if=/dev/urandom of=$TMP/$tfile.0 bs=53248 count=113 ||
20947                 error "dd of initial data file failed"
20948         stack_trap "rm -f $DIR/$tfile.[0-3] $TMP/$tfile.[0-3]" EXIT
20949
20950         echo "bs=47008 count=128 oflag=dsync normal write $tfile.0"
20951         dd if=$TMP/$tfile.0 of=$DIR/$tfile.0 bs=47008 count=128 oflag=dsync ||
20952                 error "dd with sync normal writes failed"
20953         cmp $TMP/$tfile.0 $DIR/$tfile.0 || error "compare $DIR/$tfile.0 failed"
20954
20955         echo "bs=11752 count=512 oflag=dsync small write $tfile.1"
20956         dd if=$TMP/$tfile.0 of=$DIR/$tfile.1 bs=11752 count=512 oflag=dsync ||
20957                 error "dd with sync small writes failed"
20958         cmp $TMP/$tfile.0 $DIR/$tfile.1 || error "compare $DIR/$tfile.1 failed"
20959
20960         cancel_lru_locks osc
20961
20962         # calculate the small O_DIRECT size and count for the client PAGE_SIZE
20963         local num=$((13 * 113 / (PAGE_SIZE / 4096)))
20964         echo "bs=$PAGE_SIZE count=$num iflag=direct small read $tfile.1"
20965         dd if=$DIR/$tfile.1 of=$TMP/$tfile.1 bs=$PAGE_SIZE count=$num \
20966                 iflag=direct || error "dd with O_DIRECT small read failed"
20967         # adjust bytes checked to handle larger PAGE_SIZE for ARM/PPC
20968         cmp --bytes=$((PAGE_SIZE * num)) $TMP/$tfile.0 $TMP/$tfile.1 ||
20969                 error "compare $TMP/$tfile.1 failed"
20970
20971         local save=$($LCTL get_param -n osc.*OST000*.short_io_bytes | head -n 1)
20972         stack_trap "$LCTL set_param osc.$FSNAME-*.short_io_bytes=$save" EXIT
20973
20974         # just to see what the maximum tunable value is, and test parsing
20975         echo "test invalid parameter 2MB"
20976         $LCTL set_param osc.$FSNAME-OST0000*.short_io_bytes=2M &&
20977                 error "too-large short_io_bytes allowed"
20978         echo "test maximum parameter 512KB"
20979         # if we can set a larger short_io_bytes, run test regardless of version
20980         if ! $LCTL set_param osc.$FSNAME-OST0000*.short_io_bytes=512K; then
20981                 # older clients may not allow setting it this large, that's OK
20982                 [ $CLIENT_VERSION -ge $(version_code 2.13.50) ] ||
20983                         skip "Need at least client version 2.13.50"
20984                 error "medium short_io_bytes failed"
20985         fi
20986         $LCTL get_param osc.$FSNAME-OST0000*.short_io_bytes
20987         size=$($LCTL get_param -n osc.$FSNAME-OST0000*.short_io_bytes)
20988
20989         echo "test large parameter 64KB"
20990         $LCTL set_param osc.$FSNAME-*.short_io_bytes=65536
20991         $LCTL get_param osc.$FSNAME-OST0000*.short_io_bytes
20992
20993         echo "bs=47008 count=128 oflag=dsync large write $tfile.2"
20994         dd if=$TMP/$tfile.0 of=$DIR/$tfile.2 bs=47008 count=128 oflag=dsync ||
20995                 error "dd with sync large writes failed"
20996         cmp $TMP/$tfile.0 $DIR/$tfile.2 || error "compare $DIR/$tfile.2 failed"
20997
20998         # calculate the large O_DIRECT size and count for the client PAGE_SIZE
20999         local size=$(((4096 * 13 + PAGE_SIZE - 1) / PAGE_SIZE * PAGE_SIZE))
21000         num=$((113 * 4096 / PAGE_SIZE))
21001         echo "bs=$size count=$num oflag=direct large write $tfile.3"
21002         dd if=$TMP/$tfile.0 of=$DIR/$tfile.3 bs=$size count=$num oflag=direct ||
21003                 error "dd with O_DIRECT large writes failed"
21004         cmp --bytes=$((size * num)) $TMP/$tfile.0 $DIR/$tfile.3 ||
21005                 error "compare $DIR/$tfile.3 failed"
21006
21007         cancel_lru_locks osc
21008
21009         echo "bs=$size count=$num iflag=direct large read $tfile.2"
21010         dd if=$DIR/$tfile.2 of=$TMP/$tfile.2 bs=$size count=$num iflag=direct ||
21011                 error "dd with O_DIRECT large read failed"
21012         cmp --bytes=$((size * num)) $TMP/$tfile.0 $TMP/$tfile.2 ||
21013                 error "compare $TMP/$tfile.2 failed"
21014
21015         echo "bs=$size count=$num iflag=direct large read $tfile.3"
21016         dd if=$DIR/$tfile.3 of=$TMP/$tfile.3 bs=$size count=$num iflag=direct ||
21017                 error "dd with O_DIRECT large read failed"
21018         cmp --bytes=$((size * num)) $TMP/$tfile.0 $TMP/$tfile.3 ||
21019                 error "compare $TMP/$tfile.3 failed"
21020 }
21021 run_test 248b "test short_io read and write for both small and large sizes"
21022
21023 test_249() { # LU-7890
21024         [ $MDS1_VERSION -lt $(version_code 2.8.53) ] &&
21025                 skip "Need at least version 2.8.54"
21026
21027         rm -f $DIR/$tfile
21028         $LFS setstripe -c 1 $DIR/$tfile
21029         # Offset 2T == 4k * 512M
21030         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 seek=512M ||
21031                 error "dd to 2T offset failed"
21032 }
21033 run_test 249 "Write above 2T file size"
21034
21035 test_250() {
21036         [ "$(facet_fstype ost$(($($LFS getstripe -i $DIR/$tfile) + 1)))" = "zfs" ] \
21037          && skip "no 16TB file size limit on ZFS"
21038
21039         $LFS setstripe -c 1 $DIR/$tfile
21040         # ldiskfs extent file size limit is (16TB - 4KB - 1) bytes
21041         local size=$((16 * 1024 * 1024 * 1024 * 1024 - 4096 - 1))
21042         $TRUNCATE $DIR/$tfile $size || error "truncate $tfile to $size failed"
21043         dd if=/dev/zero of=$DIR/$tfile bs=10 count=1 oflag=append \
21044                 conv=notrunc,fsync && error "append succeeded"
21045         return 0
21046 }
21047 run_test 250 "Write above 16T limit"
21048
21049 test_251() {
21050         $LFS setstripe -c -1 -S 1048576 $DIR/$tfile
21051
21052         #define OBD_FAIL_LLITE_LOST_LAYOUT 0x1407
21053         #Skip once - writing the first stripe will succeed
21054         $LCTL set_param fail_loc=0xa0001407 fail_val=1
21055         $MULTIOP $DIR/$tfile o:O_RDWR:w2097152c 2>&1 | grep -q "short write" &&
21056                 error "short write happened"
21057
21058         $LCTL set_param fail_loc=0xa0001407 fail_val=1
21059         $MULTIOP $DIR/$tfile or2097152c 2>&1 | grep -q "short read" &&
21060                 error "short read happened"
21061
21062         rm -f $DIR/$tfile
21063 }
21064 run_test 251 "Handling short read and write correctly"
21065
21066 test_252() {
21067         remote_mds_nodsh && skip "remote MDS with nodsh"
21068         remote_ost_nodsh && skip "remote OST with nodsh"
21069         if [ "$ost1_FSTYPE" != ldiskfs ] || [ "$mds1_FSTYPE" != ldiskfs ]; then
21070                 skip_env "ldiskfs only test"
21071         fi
21072
21073         local tgt
21074         local dev
21075         local out
21076         local uuid
21077         local num
21078         local gen
21079
21080         # check lr_reader on OST0000
21081         tgt=ost1
21082         dev=$(facet_device $tgt)
21083         out=$(do_facet $tgt $LR_READER $dev)
21084         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
21085         echo "$out"
21086         uuid=$(echo "$out" | grep -i uuid | awk '{ print $2 }')
21087         [ "$uuid" == "$(ostuuid_from_index 0)" ] ||
21088                 error "Invalid uuid returned by $LR_READER on target $tgt"
21089         echo -e "uuid returned by $LR_READER is '$uuid'\n"
21090
21091         # check lr_reader -c on MDT0000
21092         tgt=mds1
21093         dev=$(facet_device $tgt)
21094         if ! do_facet $tgt $LR_READER -h | grep -q OPTIONS; then
21095                 skip "$LR_READER does not support additional options"
21096         fi
21097         out=$(do_facet $tgt $LR_READER -c $dev)
21098         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
21099         echo "$out"
21100         num=$(echo "$out" | grep -c "mdtlov")
21101         [ "$num" -eq $((MDSCOUNT - 1)) ] ||
21102                 error "Invalid number of mdtlov clients returned by $LR_READER"
21103         echo -e "Number of mdtlov clients returned by $LR_READER is '$num'\n"
21104
21105         # check lr_reader -cr on MDT0000
21106         out=$(do_facet $tgt $LR_READER -cr $dev)
21107         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
21108         echo "$out"
21109         echo "$out" | grep -q "^reply_data:$" ||
21110                 error "$LR_READER should have returned 'reply_data' section"
21111         num=$(echo "$out" | grep -c "client_generation")
21112         echo -e "Number of reply data returned by $LR_READER is '$num'\n"
21113 }
21114 run_test 252 "check lr_reader tool"
21115
21116 test_253() {
21117         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21118         remote_mds_nodsh && skip "remote MDS with nodsh"
21119         remote_mgs_nodsh && skip "remote MGS with nodsh"
21120
21121         local ostidx=0
21122         local rc=0
21123         local ost_name=$(ostname_from_index $ostidx)
21124
21125         # on the mdt's osc
21126         local mdtosc_proc1=$(get_mdtosc_proc_path $SINGLEMDS $ost_name)
21127         do_facet $SINGLEMDS $LCTL get_param -n \
21128                 osp.$mdtosc_proc1.reserved_mb_high ||
21129                 skip  "remote MDS does not support reserved_mb_high"
21130
21131         rm -rf $DIR/$tdir
21132         wait_mds_ost_sync
21133         wait_delete_completed
21134         mkdir $DIR/$tdir
21135
21136         pool_add $TESTNAME || error "Pool creation failed"
21137         pool_add_targets $TESTNAME 0 || error "Pool add targets failed"
21138
21139         $LFS setstripe $DIR/$tdir -i $ostidx -c 1 -p $FSNAME.$TESTNAME ||
21140                 error "Setstripe failed"
21141
21142         dd if=/dev/zero of=$DIR/$tdir/$tfile.0 bs=1M count=10
21143
21144         local wms=$(ost_watermarks_set_enospc $tfile $ostidx |
21145                     grep "watermarks")
21146         stack_trap "ost_watermarks_clear_enospc $tfile $ostidx $wms" EXIT
21147
21148         local oa_status=$(do_facet $SINGLEMDS $LCTL get_param -n \
21149                         osp.$mdtosc_proc1.prealloc_status)
21150         echo "prealloc_status $oa_status"
21151
21152         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=1M count=1 &&
21153                 error "File creation should fail"
21154
21155         #object allocation was stopped, but we still able to append files
21156         dd if=/dev/zero of=$DIR/$tdir/$tfile.0 bs=1M seek=6 count=5 \
21157                 oflag=append || error "Append failed"
21158
21159         rm -f $DIR/$tdir/$tfile.0
21160
21161         # For this test, we want to delete the files we created to go out of
21162         # space but leave the watermark, so we remain nearly out of space
21163         ost_watermarks_enospc_delete_files $tfile $ostidx
21164
21165         wait_delete_completed
21166
21167         sleep_maxage
21168
21169         for i in $(seq 10 12); do
21170                 dd if=/dev/zero of=$DIR/$tdir/$tfile.$i bs=1M count=1 \
21171                         2>/dev/null || error "File creation failed after rm"
21172         done
21173
21174         oa_status=$(do_facet $SINGLEMDS $LCTL get_param -n \
21175                         osp.$mdtosc_proc1.prealloc_status)
21176         echo "prealloc_status $oa_status"
21177
21178         if (( oa_status != 0 )); then
21179                 error "Object allocation still disable after rm"
21180         fi
21181 }
21182 run_test 253 "Check object allocation limit"
21183
21184 test_254() {
21185         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21186         remote_mds_nodsh && skip "remote MDS with nodsh"
21187
21188         local mdt=$(facet_svc $SINGLEMDS)
21189
21190         do_facet $SINGLEMDS $LCTL get_param -n mdd.$mdt.changelog_size ||
21191                 skip "MDS does not support changelog_size"
21192
21193         local cl_user
21194
21195         changelog_register || error "changelog_register failed"
21196
21197         changelog_clear 0 || error "changelog_clear failed"
21198
21199         local size1=$(do_facet $SINGLEMDS \
21200                       $LCTL get_param -n mdd.$mdt.changelog_size)
21201         echo "Changelog size $size1"
21202
21203         rm -rf $DIR/$tdir
21204         $LFS mkdir -i 0 $DIR/$tdir
21205         # change something
21206         mkdir -p $DIR/$tdir/pics/2008/zachy
21207         touch $DIR/$tdir/pics/2008/zachy/timestamp
21208         cp /etc/hosts $DIR/$tdir/pics/2008/zachy/pic1.jpg
21209         mv $DIR/$tdir/pics/2008/zachy $DIR/$tdir/pics/zach
21210         ln $DIR/$tdir/pics/zach/pic1.jpg $DIR/$tdir/pics/2008/portland.jpg
21211         ln -s $DIR/$tdir/pics/2008/portland.jpg $DIR/$tdir/pics/desktop.jpg
21212         rm $DIR/$tdir/pics/desktop.jpg
21213
21214         local size2=$(do_facet $SINGLEMDS \
21215                       $LCTL get_param -n mdd.$mdt.changelog_size)
21216         echo "Changelog size after work $size2"
21217
21218         (( $size2 > $size1 )) ||
21219                 error "new Changelog size=$size2 less than old size=$size1"
21220 }
21221 run_test 254 "Check changelog size"
21222
21223 ladvise_no_type()
21224 {
21225         local type=$1
21226         local file=$2
21227
21228         lfs ladvise -a invalid $file 2>&1 | grep "Valid types" |
21229                 awk -F: '{print $2}' | grep $type > /dev/null
21230         if [ $? -ne 0 ]; then
21231                 return 0
21232         fi
21233         return 1
21234 }
21235
21236 ladvise_no_ioctl()
21237 {
21238         local file=$1
21239
21240         lfs ladvise -a willread $file > /dev/null 2>&1
21241         if [ $? -eq 0 ]; then
21242                 return 1
21243         fi
21244
21245         lfs ladvise -a willread $file 2>&1 |
21246                 grep "Inappropriate ioctl for device" > /dev/null
21247         if [ $? -eq 0 ]; then
21248                 return 0
21249         fi
21250         return 1
21251 }
21252
21253 percent() {
21254         bc <<<"scale=2; ($1 - $2) * 100 / $2"
21255 }
21256
21257 # run a random read IO workload
21258 # usage: random_read_iops <filename> <filesize> <iosize>
21259 random_read_iops() {
21260         local file=$1
21261         local fsize=$2
21262         local iosize=${3:-4096}
21263
21264         $READS -f $file -s $fsize -b $iosize -n $((fsize / iosize)) -t 60 |
21265                 sed -e '/^$/d' -e 's#.*s, ##' -e 's#MB/s##'
21266 }
21267
21268 drop_file_oss_cache() {
21269         local file="$1"
21270         local nodes="$2"
21271
21272         $LFS ladvise -a dontneed $file 2>/dev/null ||
21273                 do_nodes $nodes "echo 3 > /proc/sys/vm/drop_caches"
21274 }
21275
21276 ladvise_willread_performance()
21277 {
21278         local repeat=10
21279         local average_origin=0
21280         local average_cache=0
21281         local average_ladvise=0
21282
21283         for ((i = 1; i <= $repeat; i++)); do
21284                 echo "Iter $i/$repeat: reading without willread hint"
21285                 cancel_lru_locks osc
21286                 drop_file_oss_cache $DIR/$tfile $(comma_list $(osts_nodes))
21287                 local speed_origin=$(random_read_iops $DIR/$tfile $size)
21288                 echo "Iter $i/$repeat: uncached speed: $speed_origin"
21289                 average_origin=$(bc <<<"$average_origin + $speed_origin")
21290
21291                 cancel_lru_locks osc
21292                 local speed_cache=$(random_read_iops $DIR/$tfile $size)
21293                 echo "Iter $i/$repeat: OSS cache speed: $speed_cache"
21294                 average_cache=$(bc <<<"$average_cache + $speed_cache")
21295
21296                 cancel_lru_locks osc
21297                 drop_file_oss_cache $DIR/$tfile $(comma_list $(osts_nodes))
21298                 $LFS ladvise -a willread $DIR/$tfile || error "ladvise failed"
21299                 local speed_ladvise=$(random_read_iops $DIR/$tfile $size)
21300                 echo "Iter $i/$repeat: ladvise speed: $speed_ladvise"
21301                 average_ladvise=$(bc <<<"$average_ladvise + $speed_ladvise")
21302         done
21303         average_origin=$(bc <<<"scale=2; $average_origin / $repeat")
21304         average_cache=$(bc <<<"scale=2; $average_cache / $repeat")
21305         average_ladvise=$(bc <<<"scale=2; $average_ladvise / $repeat")
21306
21307         speedup_cache=$(percent $average_cache $average_origin)
21308         speedup_ladvise=$(percent $average_ladvise $average_origin)
21309
21310         echo "Average uncached read: $average_origin"
21311         echo "Average speedup with OSS cached read: " \
21312                 "$average_cache = +$speedup_cache%"
21313         echo "Average speedup with ladvise willread: " \
21314                 "$average_ladvise = +$speedup_ladvise%"
21315
21316         local lowest_speedup=20
21317         if [ ${average_cache%.*} -lt $lowest_speedup ]; then
21318                 echo "Speedup with OSS cached read less than $lowest_speedup%," \
21319                         "got $average_cache%. Skipping ladvise willread check."
21320                 return 0
21321         fi
21322
21323         # the test won't work on ZFS until it supports 'ladvise dontneed', but
21324         # it is still good to run until then to exercise 'ladvise willread'
21325         ! $LFS ladvise -a dontneed $DIR/$tfile &&
21326                 [ "$ost1_FSTYPE" = "zfs" ] &&
21327                 echo "osd-zfs does not support dontneed or drop_caches" &&
21328                 return 0
21329
21330         lowest_speedup=$(bc <<<"scale=2; $average_cache / 2")
21331         [[ ${average_ladvise%.*} > $lowest_speedup ]] ||
21332                 error_not_in_vm "Speedup with willread is less than " \
21333                         "$lowest_speedup%, got $average_ladvise%"
21334 }
21335
21336 test_255a() {
21337         [ $OST1_VERSION -lt $(version_code 2.8.54) ] &&
21338                 skip "lustre < 2.8.54 does not support ladvise "
21339         remote_ost_nodsh && skip "remote OST with nodsh"
21340
21341         stack_trap "rm -f $DIR/$tfile"
21342         lfs setstripe -c -1 -i 0 $DIR/$tfile || error "$tfile failed"
21343
21344         ladvise_no_type willread $DIR/$tfile &&
21345                 skip "willread ladvise is not supported"
21346
21347         ladvise_no_ioctl $DIR/$tfile &&
21348                 skip "ladvise ioctl is not supported"
21349
21350         local size_mb=100
21351         local size=$((size_mb * 1048576))
21352         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=$size_mb ||
21353                 error "dd to $DIR/$tfile failed"
21354
21355         lfs ladvise -a willread $DIR/$tfile ||
21356                 error "Ladvise failed with no range argument"
21357
21358         lfs ladvise -a willread -s 0 $DIR/$tfile ||
21359                 error "Ladvise failed with no -l or -e argument"
21360
21361         lfs ladvise -a willread -e 1 $DIR/$tfile ||
21362                 error "Ladvise failed with only -e argument"
21363
21364         lfs ladvise -a willread -l 1 $DIR/$tfile ||
21365                 error "Ladvise failed with only -l argument"
21366
21367         lfs ladvise -a willread -s 2 -e 1 $DIR/$tfile &&
21368                 error "End offset should not be smaller than start offset"
21369
21370         lfs ladvise -a willread -s 2 -e 2 $DIR/$tfile &&
21371                 error "End offset should not be equal to start offset"
21372
21373         lfs ladvise -a willread -s $size -l 1 $DIR/$tfile ||
21374                 error "Ladvise failed with overflowing -s argument"
21375
21376         lfs ladvise -a willread -s 1 -e $((size + 1)) $DIR/$tfile ||
21377                 error "Ladvise failed with overflowing -e argument"
21378
21379         lfs ladvise -a willread -s 1 -l $size $DIR/$tfile ||
21380                 error "Ladvise failed with overflowing -l argument"
21381
21382         lfs ladvise -a willread -l 1 -e 2 $DIR/$tfile &&
21383                 error "Ladvise succeeded with conflicting -l and -e arguments"
21384
21385         echo "Synchronous ladvise should wait"
21386         local delay=4
21387 #define OBD_FAIL_OST_LADVISE_PAUSE       0x237
21388         do_nodes $(comma_list $(osts_nodes)) \
21389                 $LCTL set_param fail_val=$delay fail_loc=0x237
21390
21391         local start_ts=$SECONDS
21392         lfs ladvise -a willread $DIR/$tfile ||
21393                 error "Ladvise failed with no range argument"
21394         local end_ts=$SECONDS
21395         local inteval_ts=$((end_ts - start_ts))
21396
21397         if [ $inteval_ts -lt $(($delay - 1)) ]; then
21398                 error "Synchronous advice didn't wait reply"
21399         fi
21400
21401         echo "Asynchronous ladvise shouldn't wait"
21402         local start_ts=$SECONDS
21403         lfs ladvise -a willread -b $DIR/$tfile ||
21404                 error "Ladvise failed with no range argument"
21405         local end_ts=$SECONDS
21406         local inteval_ts=$((end_ts - start_ts))
21407
21408         if [ $inteval_ts -gt $(($delay / 2)) ]; then
21409                 error "Asynchronous advice blocked"
21410         fi
21411
21412         do_nodes $(comma_list $(osts_nodes)) $LCTL set_param fail_loc=0
21413         ladvise_willread_performance
21414 }
21415 run_test 255a "check 'lfs ladvise -a willread'"
21416
21417 facet_meminfo() {
21418         local facet=$1
21419         local info=$2
21420
21421         do_facet $facet "cat /proc/meminfo | grep ^${info}:" | awk '{print $2}'
21422 }
21423
21424 test_255b() {
21425         [ $OST1_VERSION -lt $(version_code 2.8.54) ] &&
21426                 skip "lustre < 2.8.54 does not support ladvise "
21427         remote_ost_nodsh && skip "remote OST with nodsh"
21428
21429         stack_trap "rm -f $DIR/$tfile"
21430         lfs setstripe -c 1 -i 0 $DIR/$tfile
21431
21432         ladvise_no_type dontneed $DIR/$tfile &&
21433                 skip "dontneed ladvise is not supported"
21434
21435         ladvise_no_ioctl $DIR/$tfile &&
21436                 skip "ladvise ioctl is not supported"
21437
21438         ! $LFS ladvise -a dontneed $DIR/$tfile &&
21439                 [ "$ost1_FSTYPE" = "zfs" ] &&
21440                 skip "zfs-osd does not support 'ladvise dontneed'"
21441
21442         local size_mb=100
21443         local size=$((size_mb * 1048576))
21444         # In order to prevent disturbance of other processes, only check 3/4
21445         # of the memory usage
21446         local kibibytes=$((size_mb * 1024 * 3 / 4))
21447
21448         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=$size_mb ||
21449                 error "dd to $DIR/$tfile failed"
21450
21451         #force write to complete before dropping OST cache & checking memory
21452         sync
21453
21454         local total=$(facet_meminfo ost1 MemTotal)
21455         echo "Total memory: $total KiB"
21456
21457         do_facet ost1 "sync && echo 3 > /proc/sys/vm/drop_caches"
21458         local before_read=$(facet_meminfo ost1 Cached)
21459         echo "Cache used before read: $before_read KiB"
21460
21461         lfs ladvise -a willread $DIR/$tfile ||
21462                 error "Ladvise willread failed"
21463         local after_read=$(facet_meminfo ost1 Cached)
21464         echo "Cache used after read: $after_read KiB"
21465
21466         lfs ladvise -a dontneed $DIR/$tfile ||
21467                 error "Ladvise dontneed again failed"
21468         local no_read=$(facet_meminfo ost1 Cached)
21469         echo "Cache used after dontneed ladvise: $no_read KiB"
21470
21471         if [ $total -lt $((before_read + kibibytes)) ]; then
21472                 echo "Memory is too small, abort checking"
21473                 return 0
21474         fi
21475
21476         if [ $((before_read + kibibytes)) -gt $after_read ]; then
21477                 error "Ladvise willread should use more memory" \
21478                         "than $kibibytes KiB"
21479         fi
21480
21481         if [ $((no_read + kibibytes)) -gt $after_read ]; then
21482                 error "Ladvise dontneed should release more memory" \
21483                         "than $kibibytes KiB"
21484         fi
21485 }
21486 run_test 255b "check 'lfs ladvise -a dontneed'"
21487
21488 test_255c() {
21489         [ $OST1_VERSION -lt $(version_code 2.10.50) ] &&
21490                 skip "lustre < 2.10.50 does not support lockahead"
21491
21492         local ost1_imp=$(get_osc_import_name client ost1)
21493         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
21494                          cut -d'.' -f2)
21495         local count
21496         local new_count
21497         local difference
21498         local i
21499         local rc
21500
21501         test_mkdir -p $DIR/$tdir
21502         $LFS setstripe -i 0 -c 1 $DIR/$tdir
21503
21504         #test 10 returns only success/failure
21505         i=10
21506         lockahead_test -d $DIR/$tdir -t $i -f $tfile
21507         rc=$?
21508         if [ $rc -eq 255 ]; then
21509                 error "Ladvise test${i} failed, ${rc}"
21510         fi
21511
21512         #test 11 counts lock enqueue requests, all others count new locks
21513         i=11
21514         count=$(do_facet ost1 \
21515                 $LCTL get_param -n ost.OSS.ost.stats)
21516         count=$(echo "$count" | grep ldlm_extent_enqueue | awk '{ print $2 }')
21517
21518         lockahead_test -d $DIR/$tdir -t $i -f $tfile
21519         rc=$?
21520         if [ $rc -eq 255 ]; then
21521                 error "Ladvise test${i} failed, ${rc}"
21522         fi
21523
21524         new_count=$(do_facet ost1 \
21525                 $LCTL get_param -n ost.OSS.ost.stats)
21526         new_count=$(echo "$new_count" | grep ldlm_extent_enqueue | \
21527                    awk '{ print $2 }')
21528
21529         difference="$((new_count - count))"
21530         if [ $difference -ne $rc ]; then
21531                 error "Ladvise test${i}, bad enqueue count, returned " \
21532                       "${rc}, actual ${difference}"
21533         fi
21534
21535         for i in $(seq 12 21); do
21536                 # If we do not do this, we run the risk of having too many
21537                 # locks and starting lock cancellation while we are checking
21538                 # lock counts.
21539                 cancel_lru_locks osc
21540
21541                 count=$($LCTL get_param -n \
21542                        ldlm.namespaces.$imp_name.lock_unused_count)
21543
21544                 lockahead_test -d $DIR/$tdir -t $i -f $tfile
21545                 rc=$?
21546                 if [ $rc -eq 255 ]; then
21547                         error "Ladvise test ${i} failed, ${rc}"
21548                 fi
21549
21550                 new_count=$($LCTL get_param -n \
21551                        ldlm.namespaces.$imp_name.lock_unused_count)
21552                 difference="$((new_count - count))"
21553
21554                 # Test 15 output is divided by 100 to map down to valid return
21555                 if [ $i -eq 15 ]; then
21556                         rc="$((rc * 100))"
21557                 fi
21558
21559                 if [ $difference -ne $rc ]; then
21560                         error "Ladvise test ${i}, bad lock count, returned " \
21561                               "${rc}, actual ${difference}"
21562                 fi
21563         done
21564
21565         #test 22 returns only success/failure
21566         i=22
21567         lockahead_test -d $DIR/$tdir -t $i -f $tfile
21568         rc=$?
21569         if [ $rc -eq 255 ]; then
21570                 error "Ladvise test${i} failed, ${rc}"
21571         fi
21572 }
21573 run_test 255c "suite of ladvise lockahead tests"
21574
21575 test_256() {
21576         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21577         remote_mds_nodsh && skip "remote MDS with nodsh"
21578         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip "ldiskfs only test"
21579         changelog_users $SINGLEMDS | grep "^cl" &&
21580                 skip "active changelog user"
21581
21582         local cl_user
21583         local cat_sl
21584         local mdt_dev
21585
21586         mdt_dev=$(mdsdevname 1)
21587         echo $mdt_dev
21588
21589         changelog_register || error "changelog_register failed"
21590
21591         rm -rf $DIR/$tdir
21592         mkdir_on_mdt0 $DIR/$tdir
21593
21594         changelog_clear 0 || error "changelog_clear failed"
21595
21596         # change something
21597         touch $DIR/$tdir/{1..10}
21598
21599         # stop the MDT
21600         stop $SINGLEMDS || error "Fail to stop MDT"
21601
21602         # remount the MDT
21603
21604         start $SINGLEMDS $mdt_dev $MDS_MOUNT_OPTS || error "Fail to start MDT"
21605
21606         #after mount new plainllog is used
21607         touch $DIR/$tdir/{11..19}
21608         local tmpfile="$(mktemp --tmpdir -u $tfile.XXXXXX)"
21609         stack_trap "rm -f $tmpfile"
21610         cat_sl=$(do_facet $SINGLEMDS "sync; \
21611                  $DEBUGFS -c -R 'dump changelog_catalog $tmpfile' $mdt_dev; \
21612                  llog_reader $tmpfile | grep -c type=1064553b")
21613         do_facet $SINGLEMDS llog_reader $tmpfile
21614
21615         [ $cat_sl != 2 ] && error "Changelog catalog has $cat_sl != 2 slots"
21616
21617         changelog_clear 0 || error "changelog_clear failed"
21618
21619         cat_sl=$(do_facet $SINGLEMDS "sync; \
21620                  $DEBUGFS -c -R 'dump changelog_catalog $tmpfile' $mdt_dev; \
21621                  llog_reader $tmpfile | grep -c type=1064553b")
21622
21623         if (( cat_sl == 2 )); then
21624                 error "Empty plain llog was not deleted from changelog catalog"
21625         elif (( cat_sl != 1 )); then
21626                 error "Active plain llog shouldn't be deleted from catalog"
21627         fi
21628 }
21629 run_test 256 "Check llog delete for empty and not full state"
21630
21631 test_257() {
21632         remote_mds_nodsh && skip "remote MDS with nodsh"
21633         [[ $MDS1_VERSION -lt $(version_code 2.8.55) ]] &&
21634                 skip "Need MDS version at least 2.8.55"
21635
21636         test_mkdir $DIR/$tdir
21637
21638         setfattr -n trusted.name1 -v value1 $DIR/$tdir ||
21639                 error "setfattr -n trusted.name1=value1 $DIR/$tdir failed"
21640         stat $DIR/$tdir
21641
21642 #define OBD_FAIL_MDS_XATTR_REP                  0x161
21643         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
21644         local facet=mds$((mdtidx + 1))
21645         set_nodes_failloc $(facet_active_host $facet) 0x80000161
21646         getfattr -n trusted.name1 $DIR/$tdir 2> /dev/null
21647
21648         stop $facet || error "stop MDS failed"
21649         start $facet $(mdsdevname $((mdtidx + 1))) $MDS_MOUNT_OPTS ||
21650                 error "start MDS fail"
21651         wait_recovery_complete $facet
21652 }
21653 run_test 257 "xattr locks are not lost"
21654
21655 # Verify we take the i_mutex when security requires it
21656 test_258a() {
21657 #define OBD_FAIL_IMUTEX_SEC 0x141c
21658         $LCTL set_param fail_loc=0x141c
21659         touch $DIR/$tfile
21660         chmod u+s $DIR/$tfile
21661         chmod a+rwx $DIR/$tfile
21662         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 oflag=append
21663         RC=$?
21664         if [ $RC -ne 0 ]; then
21665                 error "error, failed to take i_mutex, rc=$?"
21666         fi
21667         rm -f $DIR/$tfile
21668 }
21669 run_test 258a "verify i_mutex security behavior when suid attributes is set"
21670
21671 # Verify we do NOT take the i_mutex in the normal case
21672 test_258b() {
21673 #define OBD_FAIL_IMUTEX_NOSEC 0x141d
21674         $LCTL set_param fail_loc=0x141d
21675         touch $DIR/$tfile
21676         chmod a+rwx $DIR
21677         chmod a+rw $DIR/$tfile
21678         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 oflag=append
21679         RC=$?
21680         if [ $RC -ne 0 ]; then
21681                 error "error, took i_mutex unnecessarily, rc=$?"
21682         fi
21683         rm -f $DIR/$tfile
21684
21685 }
21686 run_test 258b "verify i_mutex security behavior"
21687
21688 test_259() {
21689         local file=$DIR/$tfile
21690         local before
21691         local after
21692
21693         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip "ldiskfs only test"
21694
21695         stack_trap "rm -f $file" EXIT
21696
21697         wait_delete_completed
21698         before=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
21699         echo "before: $before"
21700
21701         $LFS setstripe -i 0 -c 1 $file
21702         dd if=/dev/zero of=$file bs=1M count=10 || error "couldn't write"
21703         sync_all_data
21704         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
21705         echo "after write: $after"
21706
21707 #define OBD_FAIL_OSD_FAIL_AT_TRUNCATE          0x2301
21708         do_facet ost1 $LCTL set_param fail_loc=0x2301
21709         $TRUNCATE $file 0
21710         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
21711         echo "after truncate: $after"
21712
21713         stop ost1
21714         do_facet ost1 $LCTL set_param fail_loc=0
21715         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
21716         sleep 2
21717         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
21718         echo "after restart: $after"
21719         [ $((after - before)) -ge $(fs_log_size ost1) ] &&
21720                 error "missing truncate?"
21721
21722         return 0
21723 }
21724 run_test 259 "crash at delayed truncate"
21725
21726 test_260() {
21727 #define OBD_FAIL_MDC_CLOSE               0x806
21728         $LCTL set_param fail_loc=0x80000806
21729         touch $DIR/$tfile
21730
21731 }
21732 run_test 260 "Check mdc_close fail"
21733
21734 ### Data-on-MDT sanity tests ###
21735 test_270a() {
21736         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
21737                 skip "Need MDS version at least 2.10.55 for DoM"
21738
21739         # create DoM file
21740         local dom=$DIR/$tdir/dom_file
21741         local tmp=$DIR/$tdir/tmp_file
21742
21743         mkdir_on_mdt0 $DIR/$tdir
21744
21745         # basic checks for DoM component creation
21746         $LFS setstripe -E 1024K -E 2048K -L mdt $dom 2>/dev/null &&
21747                 error "Can set MDT layout to non-first entry"
21748
21749         $LFS setstripe -E 1024K -L mdt -E 2048K -L mdt $dom 2>/dev/null &&
21750                 error "Can define multiple entries as MDT layout"
21751
21752         $LFS setstripe -E 1M -L mdt $dom || error "Can't create DoM layout"
21753
21754         [ $($LFS getstripe -L $dom) == "mdt" ] || error "bad pattern"
21755         [ $($LFS getstripe -c $dom) == 0 ] || error "bad stripe count"
21756         [ $($LFS getstripe -S $dom) == 1048576 ] || error "bad stripe size"
21757
21758         local mdtidx=$($LFS getstripe -m $dom)
21759         local mdtname=MDT$(printf %04x $mdtidx)
21760         local facet=mds$((mdtidx + 1))
21761         local space_check=1
21762
21763         # Skip free space checks with ZFS
21764         [ "$(facet_fstype $facet)" == "zfs" ] && space_check=0
21765
21766         # write
21767         sync
21768         local size_tmp=$((65536 * 3))
21769         local mdtfree1=$(do_facet $facet \
21770                          lctl get_param -n osd*.*$mdtname.kbytesfree)
21771
21772         dd if=/dev/urandom of=$tmp bs=1024 count=$((size_tmp / 1024))
21773         # check also direct IO along write
21774         # IO size must be a multiple of PAGE_SIZE on all platforms (ARM=64KB)
21775         dd if=$tmp of=$dom bs=65536 count=$((size_tmp / 65536)) oflag=direct
21776         sync
21777         cmp $tmp $dom || error "file data is different"
21778         [ $(stat -c%s $dom) == $size_tmp ] ||
21779                 error "bad size after write: $(stat -c%s $dom) != $size_tmp"
21780         if [ $space_check == 1 ]; then
21781                 local mdtfree2=$(do_facet $facet \
21782                                  lctl get_param -n osd*.*$mdtname.kbytesfree)
21783
21784                 # increase in usage from by $size_tmp
21785                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_tmp / 1024)) ] ||
21786                         error "MDT free space wrong after write: " \
21787                               "$mdtfree1 >= $mdtfree2 + $size_tmp/1024"
21788         fi
21789
21790         # truncate
21791         local size_dom=10000
21792
21793         $TRUNCATE $dom $size_dom
21794         [ $(stat -c%s $dom) == $size_dom ] ||
21795                 error "bad size after truncate: $(stat -c%s $dom) != $size_dom"
21796         if [ $space_check == 1 ]; then
21797                 mdtfree1=$(do_facet $facet \
21798                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
21799                 # decrease in usage from $size_tmp to new $size_dom
21800                 [ $(($mdtfree1 - $mdtfree2)) -ge \
21801                   $(((size_tmp - size_dom) / 1024)) ] ||
21802                         error "MDT free space is wrong after truncate: " \
21803                               "$mdtfree1 >= $mdtfree2 + ($size_tmp - $size_dom) / 1024"
21804         fi
21805
21806         # append
21807         cat $tmp >> $dom
21808         sync
21809         size_dom=$((size_dom + size_tmp))
21810         [ $(stat -c%s $dom) == $size_dom ] ||
21811                 error "bad size after append: $(stat -c%s $dom) != $size_dom"
21812         if [ $space_check == 1 ]; then
21813                 mdtfree2=$(do_facet $facet \
21814                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
21815                 # increase in usage by $size_tmp from previous
21816                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_tmp / 1024)) ] ||
21817                         error "MDT free space is wrong after append: " \
21818                               "$mdtfree1 >= $mdtfree2 + $size_tmp/1024"
21819         fi
21820
21821         # delete
21822         rm $dom
21823         if [ $space_check == 1 ]; then
21824                 mdtfree1=$(do_facet $facet \
21825                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
21826                 # decrease in usage by $size_dom from previous
21827                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_dom / 1024)) ] ||
21828                         error "MDT free space is wrong after removal: " \
21829                               "$mdtfree1 >= $mdtfree2 + $size_dom/1024"
21830         fi
21831
21832         # combined striping
21833         $LFS setstripe -E 1024K -L mdt -E EOF $dom ||
21834                 error "Can't create DoM + OST striping"
21835
21836         size_tmp=2031616 # must be a multiple of PAGE_SIZE=65536 on ARM
21837         dd if=/dev/urandom of=$tmp bs=1024 count=$((size_tmp / 1024))
21838         # check also direct IO along write
21839         dd if=$tmp of=$dom bs=65536 count=$((size_tmp / 65536)) oflag=direct
21840         sync
21841         cmp $tmp $dom || error "file data is different"
21842         [ $(stat -c%s $dom) == $size_tmp ] ||
21843                 error "bad size after write: $(stat -c%s $dom) != $size_tmp"
21844         rm $dom $tmp
21845
21846         return 0
21847 }
21848 run_test 270a "DoM: basic functionality tests"
21849
21850 test_270b() {
21851         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
21852                 skip "Need MDS version at least 2.10.55"
21853
21854         local dom=$DIR/$tdir/dom_file
21855         local max_size=1048576
21856
21857         mkdir -p $DIR/$tdir
21858         $LFS setstripe -E $max_size -L mdt $dom
21859
21860         # truncate over the limit
21861         $TRUNCATE $dom $(($max_size + 1)) &&
21862                 error "successful truncate over the maximum size"
21863         # write over the limit
21864         dd if=/dev/zero of=$dom bs=$max_size seek=1 count=1 &&
21865                 error "successful write over the maximum size"
21866         # append over the limit
21867         dd if=/dev/zero of=$dom bs=$(($max_size - 3)) count=1
21868         echo "12345" >> $dom && error "successful append over the maximum size"
21869         rm $dom
21870
21871         return 0
21872 }
21873 run_test 270b "DoM: maximum size overflow checks for DoM-only file"
21874
21875 test_270c() {
21876         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
21877                 skip "Need MDS version at least 2.10.55"
21878
21879         mkdir -p $DIR/$tdir
21880         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
21881
21882         # check files inherit DoM EA
21883         touch $DIR/$tdir/first
21884         [ $($LFS getstripe -L $DIR/$tdir/first) == "mdt" ] ||
21885                 error "bad pattern"
21886         [ $($LFS getstripe -c $DIR/$tdir/first) == 0 ] ||
21887                 error "bad stripe count"
21888         [ $($LFS getstripe -S $DIR/$tdir/first) == 1048576 ] ||
21889                 error "bad stripe size"
21890
21891         # check directory inherits DoM EA and uses it as default
21892         mkdir $DIR/$tdir/subdir
21893         touch $DIR/$tdir/subdir/second
21894         [ $($LFS getstripe -L $DIR/$tdir/subdir/second) == "mdt" ] ||
21895                 error "bad pattern in sub-directory"
21896         [ $($LFS getstripe -c $DIR/$tdir/subdir/second) == 0 ] ||
21897                 error "bad stripe count in sub-directory"
21898         [ $($LFS getstripe -S $DIR/$tdir/subdir/second) == 1048576 ] ||
21899                 error "bad stripe size in sub-directory"
21900         return 0
21901 }
21902 run_test 270c "DoM: DoM EA inheritance tests"
21903
21904 test_270d() {
21905         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
21906                 skip "Need MDS version at least 2.10.55"
21907
21908         mkdir -p $DIR/$tdir
21909         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
21910
21911         # inherit default DoM striping
21912         mkdir $DIR/$tdir/subdir
21913         touch $DIR/$tdir/subdir/f1
21914
21915         # change default directory striping
21916         $LFS setstripe -c 1 $DIR/$tdir/subdir
21917         touch $DIR/$tdir/subdir/f2
21918         [ $($LFS getstripe -c $DIR/$tdir/subdir/f2) == 1 ] ||
21919                 error "wrong default striping in file 2"
21920         [ $($LFS getstripe -L $DIR/$tdir/subdir/f2) == "raid0" ] ||
21921                 error "bad pattern in file 2"
21922         return 0
21923 }
21924 run_test 270d "DoM: change striping from DoM to RAID0"
21925
21926 test_270e() {
21927         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
21928                 skip "Need MDS version at least 2.10.55"
21929
21930         mkdir -p $DIR/$tdir/dom
21931         mkdir -p $DIR/$tdir/norm
21932         DOMFILES=20
21933         NORMFILES=10
21934         $LFS setstripe -E 1M -L mdt $DIR/$tdir/dom
21935         $LFS setstripe -i 0 -S 2M $DIR/$tdir/norm
21936
21937         createmany -o $DIR/$tdir/dom/dom- $DOMFILES
21938         createmany -o $DIR/$tdir/norm/norm- $NORMFILES
21939
21940         # find DoM files by layout
21941         NUM=$($LFS find -L mdt -type f $DIR/$tdir 2>/dev/null | wc -l)
21942         [ $NUM -eq  $DOMFILES ] ||
21943                 error "lfs find -L: found $NUM, expected $DOMFILES"
21944         echo "Test 1: lfs find 20 DOM files by layout: OK"
21945
21946         # there should be 1 dir with default DOM striping
21947         NUM=$($LFS find -L mdt -type d $DIR/$tdir 2>/dev/null | wc -l)
21948         [ $NUM -eq  1 ] ||
21949                 error "lfs find -L: found $NUM, expected 1 dir"
21950         echo "Test 2: lfs find 1 DOM dir by layout: OK"
21951
21952         # find DoM files by stripe size
21953         NUM=$($LFS find -S -1200K -type f $DIR/$tdir 2>/dev/null | wc -l)
21954         [ $NUM -eq  $DOMFILES ] ||
21955                 error "lfs find -S: found $NUM, expected $DOMFILES"
21956         echo "Test 4: lfs find 20 DOM files by stripe size: OK"
21957
21958         # find files by stripe offset except DoM files
21959         NUM=$($LFS find -i 0 -type f $DIR/$tdir 2>/dev/null | wc -l)
21960         [ $NUM -eq  $NORMFILES ] ||
21961                 error "lfs find -i: found $NUM, expected $NORMFILES"
21962         echo "Test 5: lfs find no DOM files by stripe index: OK"
21963         return 0
21964 }
21965 run_test 270e "DoM: lfs find with DoM files test"
21966
21967 test_270f() {
21968         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
21969                 skip "Need MDS version at least 2.10.55"
21970
21971         local mdtname=${FSNAME}-MDT0000-mdtlov
21972         local dom=$DIR/$tdir/dom_file
21973         local dom_limit_saved=$(do_facet mds1 $LCTL get_param -n \
21974                                                 lod.$mdtname.dom_stripesize)
21975         local dom_limit=131072
21976
21977         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=$dom_limit
21978         local dom_current=$(do_facet mds1 $LCTL get_param -n \
21979                                                 lod.$mdtname.dom_stripesize)
21980         [ ${dom_limit} -eq ${dom_current} ] ||
21981                 error "Cannot change per-MDT DoM stripe limit to $dom_limit"
21982
21983         $LFS mkdir -i 0 -c 1 $DIR/$tdir
21984         $LFS setstripe -d $DIR/$tdir
21985         $LFS setstripe -E $dom_limit -L mdt $DIR/$tdir ||
21986                 error "Can't set directory default striping"
21987
21988         # exceed maximum stripe size
21989         $LFS setstripe -E $((dom_limit * 2)) -L mdt $dom ||
21990                 error "Can't create file with $((dom_limit * 2)) DoM stripe"
21991         [ $($LFS getstripe -S $dom) -eq $((dom_limit * 2)) ] &&
21992                 error "Able to create DoM component size more than LOD limit"
21993
21994         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=0
21995         dom_current=$(do_facet mds1 $LCTL get_param -n \
21996                                                 lod.$mdtname.dom_stripesize)
21997         [ 0 -eq ${dom_current} ] ||
21998                 error "Can't set zero DoM stripe limit"
21999         rm $dom
22000
22001         # attempt to create DoM file on server with disabled DoM should
22002         # remove DoM entry from layout and be succeed
22003         $LFS setstripe -E $dom_limit -L mdt -E -1 $dom ||
22004                 error "Can't create DoM file (DoM is disabled)"
22005         [ $($LFS getstripe -L $dom) == "mdt" ] &&
22006                 error "File has DoM component while DoM is disabled"
22007         rm $dom
22008
22009         # attempt to create DoM file with only DoM stripe should return error
22010         $LFS setstripe -E $dom_limit -L mdt $dom &&
22011                 error "Able to create DoM-only file while DoM is disabled"
22012
22013         # too low values to be aligned with smallest stripe size 64K
22014         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=30000
22015         dom_current=$(do_facet mds1 $LCTL get_param -n \
22016                                                 lod.$mdtname.dom_stripesize)
22017         [ 30000 -eq ${dom_current} ] &&
22018                 error "Can set too small DoM stripe limit"
22019
22020         # 64K is a minimal stripe size in Lustre, expect limit of that size
22021         [ 65536 -eq ${dom_current} ] ||
22022                 error "Limit is not set to 64K but ${dom_current}"
22023
22024         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=2147483648
22025         dom_current=$(do_facet mds1 $LCTL get_param -n \
22026                                                 lod.$mdtname.dom_stripesize)
22027         echo $dom_current
22028         [ 2147483648 -eq ${dom_current} ] &&
22029                 error "Can set too large DoM stripe limit"
22030
22031         do_facet mds1 $LCTL set_param -n \
22032                                 lod.$mdtname.dom_stripesize=$((dom_limit * 2))
22033         $LFS setstripe -E $((dom_limit * 2)) -L mdt $dom ||
22034                 error "Can't create DoM component size after limit change"
22035         do_facet mds1 $LCTL set_param -n \
22036                                 lod.$mdtname.dom_stripesize=$((dom_limit / 2))
22037         $LFS setstripe -E $dom_limit -L mdt ${dom}_big ||
22038                 error "Can't create DoM file after limit decrease"
22039         [ $($LFS getstripe -S ${dom}_big) -eq $((dom_limit / 2)) ] ||
22040                 error "Can create big DoM component after limit decrease"
22041         touch ${dom}_def ||
22042                 error "Can't create file with old default layout"
22043
22044         do_facet mds1 $LCTL set_param -n lod.*.dom_stripesize=$dom_limit_saved
22045         return 0
22046 }
22047 run_test 270f "DoM: maximum DoM stripe size checks"
22048
22049 test_270g() {
22050         [ $MDS1_VERSION -ge $(version_code 2.13.52) ] ||
22051                 skip "Need MDS version at least 2.13.52"
22052         local dom=$DIR/$tdir/$tfile
22053
22054         $LFS mkdir -i 0 -c 1 $DIR/$tdir
22055         local lodname=${FSNAME}-MDT0000-mdtlov
22056
22057         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
22058         save_lustre_params mds1 "lod.${lodname}.dom_stripesize_max_kb" > $save
22059         save_lustre_params mds1 "lod.${lodname}.dom_threshold_free_mb" >> $save
22060         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
22061
22062         local dom_limit=1024
22063         local dom_threshold="50%"
22064
22065         $LFS setstripe -d $DIR/$tdir
22066         $LFS setstripe -E ${dom_limit}K -L mdt $DIR/$tdir ||
22067                 error "Can't set directory default striping"
22068
22069         do_facet mds1 $LCTL set_param -n \
22070                                 lod.${lodname}.dom_stripesize_max_kb=$dom_limit
22071         # set 0 threshold and create DOM file to change tunable stripesize
22072         do_facet mds1 $LCTL set_param -n lod.${lodname}.dom_threshold_free_mb=0
22073         $LFS setstripe -E ${dom_limit}K -L mdt -E -1 $dom ||
22074                 error "Failed to create $dom file"
22075         # now tunable dom_cur_stripesize should reach maximum
22076         local dom_current=$(do_facet mds1 $LCTL get_param -n \
22077                                         lod.${lodname}.dom_stripesize_cur_kb)
22078         [[ $dom_current == $dom_limit ]] ||
22079                 error "Current DOM stripesize is not maximum"
22080         rm $dom
22081
22082         # set threshold for further tests
22083         do_facet mds1 $LCTL set_param -n \
22084                         lod.${lodname}.dom_threshold_free_mb=$dom_threshold
22085         echo "DOM threshold is $dom_threshold free space"
22086         local dom_def
22087         local dom_set
22088         # Spoof bfree to exceed threshold
22089         #define OBD_FAIL_MDS_STATFS_SPOOF   0x168
22090         do_facet mds1 $LCTL set_param -n fail_loc=0x0168
22091         for spfree in 40 20 0 15 30 55; do
22092                 do_facet mds1 $LCTL set_param -n fail_val=$spfree
22093                 $LFS setstripe -E ${dom_limit}K -L mdt -E -1 $dom ||
22094                         error "Failed to create $dom file"
22095                 dom_def=$(do_facet mds1 $LCTL get_param -n \
22096                                         lod.${lodname}.dom_stripesize_cur_kb)
22097                 echo "Free space: ${spfree}%, default DOM stripe: ${dom_def}K"
22098                 [[ $dom_def != $dom_current ]] ||
22099                         error "Default stripe size was not changed"
22100                 if [[ $spfree > 0 ]] ; then
22101                         dom_set=$($LFS getstripe -S $dom)
22102                         [[ $dom_set == $((dom_def * 1024)) ]] ||
22103                                 error "DOM component size is still old"
22104                 else
22105                         [[ $($LFS getstripe -L $dom) != "mdt" ]] ||
22106                                 error "DoM component is set with no free space"
22107                 fi
22108                 rm $dom
22109                 dom_current=$dom_def
22110         done
22111 }
22112 run_test 270g "DoM: default DoM stripe size depends on free space"
22113
22114 test_270h() {
22115         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
22116                 skip "Need MDS version at least 2.13.53"
22117
22118         local mdtname=${FSNAME}-MDT0000-mdtlov
22119         local dom=$DIR/$tdir/$tfile
22120         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
22121
22122         save_lustre_params mds1 "lod.*.dom_stripesize" > $save
22123         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
22124
22125         $LFS mkdir -i 0 -c 1 $DIR/$tdir
22126         $LFS setstripe -E 1M -c1  -E -1 -c2 ${dom}_1 ||
22127                 error "can't create OST file"
22128         # mirrored file with DOM entry in the second mirror
22129         $LFS mirror extend -N -E 1M -L mdt -E eof -c2 ${dom}_1 ||
22130                 error "can't create mirror with DoM component"
22131
22132         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=0
22133
22134         # DOM component in the middle and has other enries in the same mirror,
22135         # should succeed but lost DoM component
22136         $LFS setstripe --copy=${dom}_1 $dom ||
22137                 error "Can't create file from OST|DOM mirror layout"
22138         # check new file has no DoM layout after all
22139         [[ $($LFS getstripe -L $dom) != "mdt" ]] ||
22140                 error "File has DoM component while DoM is disabled"
22141 }
22142 run_test 270h "DoM: DoM stripe removal when disabled on server"
22143
22144 test_270i() {
22145         (( $MDS1_VERSION >= $(version_code 2.14.54) )) ||
22146                 skip "Need MDS version at least 2.14.54"
22147
22148         mkdir $DIR/$tdir
22149         $LFS setstripe -L mdt -S 128k -c -1 $DIR/$tdir &&
22150                 error "setstripe should fail" || true
22151 }
22152 run_test 270i "DoM: setting invalid DoM striping should fail"
22153
22154 test_271a() {
22155         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
22156                 skip "Need MDS version at least 2.10.55"
22157
22158         local dom=$DIR/$tdir/dom
22159
22160         mkdir -p $DIR/$tdir
22161
22162         $LFS setstripe -E 1024K -L mdt $dom
22163
22164         lctl set_param -n mdc.*.stats=clear
22165         dd if=/dev/zero of=$dom bs=4096 count=1 || return 1
22166         cat $dom > /dev/null
22167         local reads=$(lctl get_param -n mdc.*.stats | grep -c ost_read)
22168         [ $reads -eq 0 ] || error "Unexpected $reads READ RPCs"
22169         ls $dom
22170         rm -f $dom
22171 }
22172 run_test 271a "DoM: data is cached for read after write"
22173
22174 test_271b() {
22175         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
22176                 skip "Need MDS version at least 2.10.55"
22177
22178         local dom=$DIR/$tdir/dom
22179
22180         mkdir -p $DIR/$tdir
22181
22182         $LFS setstripe -E 1024K -L mdt -E EOF $dom
22183
22184         lctl set_param -n mdc.*.stats=clear
22185         dd if=/dev/zero of=$dom bs=4096 count=1 || return 1
22186         cancel_lru_locks mdc
22187         $CHECKSTAT -t file -s 4096 $dom || error "stat #1 fails"
22188         # second stat to check size is cached on client
22189         $CHECKSTAT -t file -s 4096 $dom || error "stat #2 fails"
22190         local gls=$(lctl get_param -n mdc.*.stats | grep -c ldlm_glimpse)
22191         [ $gls -eq 0 ] || error "Unexpected $gls glimpse RPCs"
22192         rm -f $dom
22193 }
22194 run_test 271b "DoM: no glimpse RPC for stat (DoM only file)"
22195
22196 test_271ba() {
22197         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
22198                 skip "Need MDS version at least 2.10.55"
22199
22200         local dom=$DIR/$tdir/dom
22201
22202         mkdir -p $DIR/$tdir
22203
22204         $LFS setstripe -E 1024K -L mdt -E EOF $dom
22205
22206         lctl set_param -n mdc.*.stats=clear
22207         lctl set_param -n osc.*.stats=clear
22208         dd if=/dev/zero of=$dom bs=2048K count=1 || return 1
22209         cancel_lru_locks mdc
22210         $CHECKSTAT -t file -s 2097152 $dom || error "stat"
22211         # second stat to check size is cached on client
22212         $CHECKSTAT -t file -s 2097152 $dom || error "stat"
22213         local gls=$(lctl get_param -n mdc.*.stats | grep -c ldlm_glimpse)
22214         [ $gls == 0 ] || error "Unexpected $gls glimpse RPCs"
22215         local gls=$(lctl get_param -n osc.*.stats | grep -c ldlm_glimpse)
22216         [ $gls == 0 ] || error "Unexpected $gls OSC glimpse RPCs"
22217         rm -f $dom
22218 }
22219 run_test 271ba "DoM: no glimpse RPC for stat (combined file)"
22220
22221
22222 get_mdc_stats() {
22223         local mdtidx=$1
22224         local param=$2
22225         local mdt=MDT$(printf %04x $mdtidx)
22226
22227         if [ -z $param ]; then
22228                 lctl get_param -n mdc.*$mdt*.stats
22229         else
22230                 lctl get_param -n mdc.*$mdt*.stats | awk "/$param/"'{print $2}'
22231         fi
22232 }
22233
22234 test_271c() {
22235         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
22236                 skip "Need MDS version at least 2.10.55"
22237
22238         local dom=$DIR/$tdir/dom
22239
22240         mkdir -p $DIR/$tdir
22241
22242         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
22243
22244         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
22245         local facet=mds$((mdtidx + 1))
22246
22247         cancel_lru_locks mdc
22248         do_facet $facet lctl set_param -n mdt.*.dom_lock=0
22249         createmany -o $dom 1000
22250         lctl set_param -n mdc.*.stats=clear
22251         smalliomany -w $dom 1000 200
22252         get_mdc_stats $mdtidx
22253         local enq=$(get_mdc_stats $mdtidx ldlm_ibits_enqueue)
22254         # Each file has 1 open, 1 IO enqueues, total 2000
22255         # but now we have also +1 getxattr for security.capability, total 3000
22256         [ $enq -ge 2000 ] || error "Too few enqueues $enq, expected > 2000"
22257         unlinkmany $dom 1000
22258
22259         cancel_lru_locks mdc
22260         do_facet $facet lctl set_param -n mdt.*.dom_lock=1
22261         createmany -o $dom 1000
22262         lctl set_param -n mdc.*.stats=clear
22263         smalliomany -w $dom 1000 200
22264         local enq_2=$(get_mdc_stats $mdtidx ldlm_ibits_enqueue)
22265         # Expect to see reduced amount of RPCs by 1000 due to single enqueue
22266         # for OPEN and IO lock.
22267         [ $((enq - enq_2)) -ge 1000 ] ||
22268                 error "Too many enqueues $enq_2, expected about $((enq - 1000))"
22269         unlinkmany $dom 1000
22270         return 0
22271 }
22272 run_test 271c "DoM: IO lock at open saves enqueue RPCs"
22273
22274 cleanup_271def_tests() {
22275         trap 0
22276         rm -f $1
22277 }
22278
22279 test_271d() {
22280         [ $MDS1_VERSION -lt $(version_code 2.10.57) ] &&
22281                 skip "Need MDS version at least 2.10.57"
22282
22283         local dom=$DIR/$tdir/dom
22284         local tmp=$TMP/$tfile
22285         trap "cleanup_271def_tests $tmp" EXIT
22286
22287         mkdir -p $DIR/$tdir
22288
22289         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
22290
22291         local mdtidx=$($LFS getstripe --mdt-index $DIR/$tdir)
22292
22293         cancel_lru_locks mdc
22294         dd if=/dev/urandom of=$tmp bs=1000 count=1
22295         dd if=$tmp of=$dom bs=1000 count=1
22296         cancel_lru_locks mdc
22297
22298         cat /etc/hosts >> $tmp
22299         lctl set_param -n mdc.*.stats=clear
22300
22301         # append data to the same file it should update local page
22302         echo "Append to the same page"
22303         cat /etc/hosts >> $dom
22304         local num=$(get_mdc_stats $mdtidx ost_read)
22305         local ra=$(get_mdc_stats $mdtidx req_active)
22306         local rw=$(get_mdc_stats $mdtidx req_waittime)
22307
22308         [ -z $num ] || error "$num READ RPC occured"
22309         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
22310         echo "... DONE"
22311
22312         # compare content
22313         cmp $tmp $dom || error "file miscompare"
22314
22315         cancel_lru_locks mdc
22316         lctl set_param -n mdc.*.stats=clear
22317
22318         echo "Open and read file"
22319         cat $dom > /dev/null
22320         local num=$(get_mdc_stats $mdtidx ost_read)
22321         local ra=$(get_mdc_stats $mdtidx req_active)
22322         local rw=$(get_mdc_stats $mdtidx req_waittime)
22323
22324         [ -z $num ] || error "$num READ RPC occured"
22325         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
22326         echo "... DONE"
22327
22328         # compare content
22329         cmp $tmp $dom || error "file miscompare"
22330
22331         return 0
22332 }
22333 run_test 271d "DoM: read on open (1K file in reply buffer)"
22334
22335 test_271f() {
22336         [ $MDS1_VERSION -lt $(version_code 2.10.57) ] &&
22337                 skip "Need MDS version at least 2.10.57"
22338
22339         local dom=$DIR/$tdir/dom
22340         local tmp=$TMP/$tfile
22341         trap "cleanup_271def_tests $tmp" EXIT
22342
22343         mkdir -p $DIR/$tdir
22344
22345         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
22346
22347         local mdtidx=$($LFS getstripe --mdt-index $DIR/$tdir)
22348
22349         cancel_lru_locks mdc
22350         dd if=/dev/urandom of=$tmp bs=265000 count=1
22351         dd if=$tmp of=$dom bs=265000 count=1
22352         cancel_lru_locks mdc
22353         cat /etc/hosts >> $tmp
22354         lctl set_param -n mdc.*.stats=clear
22355
22356         echo "Append to the same page"
22357         cat /etc/hosts >> $dom
22358         local num=$(get_mdc_stats $mdtidx ost_read)
22359         local ra=$(get_mdc_stats $mdtidx req_active)
22360         local rw=$(get_mdc_stats $mdtidx req_waittime)
22361
22362         [ -z $num ] || error "$num READ RPC occured"
22363         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
22364         echo "... DONE"
22365
22366         # compare content
22367         cmp $tmp $dom || error "file miscompare"
22368
22369         cancel_lru_locks mdc
22370         lctl set_param -n mdc.*.stats=clear
22371
22372         echo "Open and read file"
22373         cat $dom > /dev/null
22374         local num=$(get_mdc_stats $mdtidx ost_read)
22375         local ra=$(get_mdc_stats $mdtidx req_active)
22376         local rw=$(get_mdc_stats $mdtidx req_waittime)
22377
22378         [ -z $num ] && num=0
22379         [ $num -eq 1 ] || error "expect 1 READ RPC, $num occured"
22380         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
22381         echo "... DONE"
22382
22383         # compare content
22384         cmp $tmp $dom || error "file miscompare"
22385
22386         return 0
22387 }
22388 run_test 271f "DoM: read on open (200K file and read tail)"
22389
22390 test_271g() {
22391         [[ $($LCTL get_param mdc.*.import) =~ async_discard ]] ||
22392                 skip "Skipping due to old client or server version"
22393
22394         $LFS setstripe -E 1024K -L mdt -E EOF $DIR1/$tfile
22395         # to get layout
22396         $CHECKSTAT -t file $DIR1/$tfile
22397
22398         $MULTIOP $DIR1/$tfile Ow40960_w4096c &
22399         MULTIOP_PID=$!
22400         sleep 1
22401         #define OBD_FAIL_LDLM_CANCEL_BL_CB_RACE
22402         $LCTL set_param fail_loc=0x80000314
22403         rm $DIR1/$tfile || error "Unlink fails"
22404         RC=$?
22405         kill -USR1 $MULTIOP_PID && wait $MULTIOP_PID || error "multiop failure"
22406         [ $RC -eq 0 ] || error "Failed write to stale object"
22407 }
22408 run_test 271g "Discard DoM data vs client flush race"
22409
22410 test_272a() {
22411         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
22412                 skip "Need MDS version at least 2.11.50"
22413
22414         local dom=$DIR/$tdir/dom
22415         mkdir -p $DIR/$tdir
22416
22417         $LFS setstripe -E 256K -L mdt -E -1 -c1 $dom
22418         dd if=/dev/urandom of=$dom bs=512K count=1 ||
22419                 error "failed to write data into $dom"
22420         local old_md5=$(md5sum $dom)
22421
22422         $LFS migrate -E 256K -L mdt -E -1 -c2 $dom ||
22423                 error "failed to migrate to the same DoM component"
22424
22425         local new_md5=$(md5sum $dom)
22426
22427         [ "$old_md5" == "$new_md5" ] ||
22428                 error "md5sum differ: $old_md5, $new_md5"
22429
22430         [ $($LFS getstripe -c $dom) -eq 2 ] ||
22431                 error "bad final stripe count: $($LFS getstripe -c $dom) != 2"
22432 }
22433 run_test 272a "DoM migration: new layout with the same DOM component"
22434
22435 test_272b() {
22436         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
22437                 skip "Need MDS version at least 2.11.50"
22438
22439         local dom=$DIR/$tdir/dom
22440         mkdir -p $DIR/$tdir
22441         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
22442
22443         local mdtidx=$($LFS getstripe -m $dom)
22444         local mdtname=MDT$(printf %04x $mdtidx)
22445         local facet=mds$((mdtidx + 1))
22446
22447         local mdtfree1=$(do_facet $facet \
22448                 lctl get_param -n osd*.*$mdtname.kbytesfree)
22449         dd if=/dev/urandom of=$dom bs=2M count=1 ||
22450                 error "failed to write data into $dom"
22451         local old_md5=$(md5sum $dom)
22452         cancel_lru_locks mdc
22453         local mdtfree1=$(do_facet $facet \
22454                 lctl get_param -n osd*.*$mdtname.kbytesfree)
22455
22456         $LFS migrate -c2 $dom ||
22457                 error "failed to migrate to the new composite layout"
22458         [ $($LFS getstripe -L $dom) != 'mdt' ] ||
22459                 error "MDT stripe was not removed"
22460
22461         cancel_lru_locks mdc
22462         local new_md5=$(md5sum $dom)
22463         [ "$old_md5" == "$new_md5" ] ||
22464                 error "$old_md5 != $new_md5"
22465
22466         # Skip free space checks with ZFS
22467         if [ "$(facet_fstype $facet)" != "zfs" ]; then
22468                 local mdtfree2=$(do_facet $facet \
22469                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
22470                 [ $mdtfree2 -gt $mdtfree1 ] ||
22471                         error "MDT space is not freed after migration"
22472         fi
22473         return 0
22474 }
22475 run_test 272b "DoM migration: DOM file to the OST-striped file (plain)"
22476
22477 test_272c() {
22478         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
22479                 skip "Need MDS version at least 2.11.50"
22480
22481         local dom=$DIR/$tdir/$tfile
22482         mkdir -p $DIR/$tdir
22483         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
22484
22485         local mdtidx=$($LFS getstripe -m $dom)
22486         local mdtname=MDT$(printf %04x $mdtidx)
22487         local facet=mds$((mdtidx + 1))
22488
22489         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
22490                 error "failed to write data into $dom"
22491         local old_md5=$(md5sum $dom)
22492         cancel_lru_locks mdc
22493         local mdtfree1=$(do_facet $facet \
22494                 lctl get_param -n osd*.*$mdtname.kbytesfree)
22495
22496         $LFS migrate -E 2M -c1 -E -1 -c2 $dom ||
22497                 error "failed to migrate to the new composite layout"
22498         [ $($LFS getstripe -L $dom) == 'mdt' ] &&
22499                 error "MDT stripe was not removed"
22500
22501         cancel_lru_locks mdc
22502         local new_md5=$(md5sum $dom)
22503         [ "$old_md5" == "$new_md5" ] ||
22504                 error "$old_md5 != $new_md5"
22505
22506         # Skip free space checks with ZFS
22507         if [ "$(facet_fstype $facet)" != "zfs" ]; then
22508                 local mdtfree2=$(do_facet $facet \
22509                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
22510                 [ $mdtfree2 -gt $mdtfree1 ] ||
22511                         error "MDS space is not freed after migration"
22512         fi
22513         return 0
22514 }
22515 run_test 272c "DoM migration: DOM file to the OST-striped file (composite)"
22516
22517 test_272d() {
22518         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
22519                 skip "Need MDS version at least 2.12.55"
22520
22521         local dom=$DIR/$tdir/$tfile
22522         mkdir -p $DIR/$tdir
22523         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
22524
22525         local mdtidx=$($LFS getstripe -m $dom)
22526         local mdtname=MDT$(printf %04x $mdtidx)
22527         local facet=mds$((mdtidx + 1))
22528
22529         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
22530                 error "failed to write data into $dom"
22531         local old_md5=$(md5sum $dom)
22532         cancel_lru_locks mdc
22533         local mdtfree1=$(do_facet $facet \
22534                 lctl get_param -n osd*.*$mdtname.kbytesfree)
22535
22536         $LFS mirror extend -N -E 2M -c1 -E -1 -c2 $dom ||
22537                 error "failed mirroring to the new composite layout"
22538         $LFS mirror resync $dom ||
22539                 error "failed mirror resync"
22540         $LFS mirror split --mirror-id 1 -d $dom ||
22541                 error "failed mirror split"
22542
22543         [ $($LFS getstripe -L $dom) != 'mdt' ] ||
22544                 error "MDT stripe was not removed"
22545
22546         cancel_lru_locks mdc
22547         local new_md5=$(md5sum $dom)
22548         [ "$old_md5" == "$new_md5" ] ||
22549                 error "$old_md5 != $new_md5"
22550
22551         # Skip free space checks with ZFS
22552         if [ "$(facet_fstype $facet)" != "zfs" ]; then
22553                 local mdtfree2=$(do_facet $facet \
22554                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
22555                 [ $mdtfree2 -gt $mdtfree1 ] ||
22556                         error "MDS space is not freed after DOM mirror deletion"
22557         fi
22558         return 0
22559 }
22560 run_test 272d "DoM mirroring: OST-striped mirror to DOM file"
22561
22562 test_272e() {
22563         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
22564                 skip "Need MDS version at least 2.12.55"
22565
22566         local dom=$DIR/$tdir/$tfile
22567         mkdir -p $DIR/$tdir
22568         $LFS setstripe -c 2 $dom
22569
22570         dd if=/dev/urandom of=$dom bs=512K count=1 oflag=direct ||
22571                 error "failed to write data into $dom"
22572         local old_md5=$(md5sum $dom)
22573         cancel_lru_locks mdc
22574
22575         $LFS mirror extend -N -E 1M -L mdt -E eof -c2 $dom ||
22576                 error "failed mirroring to the DOM layout"
22577         $LFS mirror resync $dom ||
22578                 error "failed mirror resync"
22579         $LFS mirror split --mirror-id 1 -d $dom ||
22580                 error "failed mirror split"
22581
22582         [ $($LFS getstripe -L $dom) != 'mdt' ] ||
22583                 error "MDT stripe was not removed"
22584
22585         cancel_lru_locks mdc
22586         local new_md5=$(md5sum $dom)
22587         [ "$old_md5" == "$new_md5" ] ||
22588                 error "$old_md5 != $new_md5"
22589
22590         return 0
22591 }
22592 run_test 272e "DoM mirroring: DOM mirror to the OST-striped file"
22593
22594 test_272f() {
22595         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
22596                 skip "Need MDS version at least 2.12.55"
22597
22598         local dom=$DIR/$tdir/$tfile
22599         mkdir -p $DIR/$tdir
22600         $LFS setstripe -c 2 $dom
22601
22602         dd if=/dev/urandom of=$dom bs=512K count=1 oflag=direct ||
22603                 error "failed to write data into $dom"
22604         local old_md5=$(md5sum $dom)
22605         cancel_lru_locks mdc
22606
22607         $LFS migrate -E 1M -L mdt -E eof -c2 -v $dom ||
22608                 error "failed migrating to the DOM file"
22609
22610         cancel_lru_locks mdc
22611         local new_md5=$(md5sum $dom)
22612         [ "$old_md5" != "$new_md5" ] &&
22613                 error "$old_md5 != $new_md5"
22614
22615         return 0
22616 }
22617 run_test 272f "DoM migration: OST-striped file to DOM file"
22618
22619 test_273a() {
22620         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
22621                 skip "Need MDS version at least 2.11.50"
22622
22623         # Layout swap cannot be done if either file has DOM component,
22624         # this will never be supported, migration should be used instead
22625
22626         local dom=$DIR/$tdir/$tfile
22627         mkdir -p $DIR/$tdir
22628
22629         $LFS setstripe -c2 ${dom}_plain
22630         $LFS setstripe -E 1M -L mdt -E -1 -c2 ${dom}_dom
22631         $LFS swap_layouts ${dom}_plain ${dom}_dom &&
22632                 error "can swap layout with DoM component"
22633         $LFS swap_layouts ${dom}_dom ${dom}_plain &&
22634                 error "can swap layout with DoM component"
22635
22636         $LFS setstripe -E 1M -c1 -E -1 -c2 ${dom}_comp
22637         $LFS swap_layouts ${dom}_comp ${dom}_dom &&
22638                 error "can swap layout with DoM component"
22639         $LFS swap_layouts ${dom}_dom ${dom}_comp &&
22640                 error "can swap layout with DoM component"
22641         return 0
22642 }
22643 run_test 273a "DoM: layout swapping should fail with DOM"
22644
22645 test_273b() {
22646         mkdir -p $DIR/$tdir
22647         $LFS setstripe -E 1M -L mdt -E -1 -c -1 $DIR/$tdir
22648
22649 #define OBD_FAIL_MDS_COMMITRW_DELAY      0x16b
22650         do_facet mds1 $LCTL set_param fail_loc=0x8000016b fail_val=2
22651
22652         $MULTIOP $DIR/$tdir/$tfile Ouw2097152c
22653 }
22654 run_test 273b "DoM: race writeback and object destroy"
22655
22656 test_275() {
22657         remote_ost_nodsh && skip "remote OST with nodsh"
22658         [ $OST1_VERSION -lt $(version_code 2.10.57) ] &&
22659                 skip "Need OST version >= 2.10.57"
22660
22661         local file=$DIR/$tfile
22662         local oss
22663
22664         oss=$(comma_list $(osts_nodes))
22665
22666         dd if=/dev/urandom of=$file bs=1M count=2 ||
22667                 error "failed to create a file"
22668         cancel_lru_locks osc
22669
22670         #lock 1
22671         dd if=$file of=/dev/null bs=1M count=1 iflag=direct ||
22672                 error "failed to read a file"
22673
22674 #define OBD_FAIL_LDLM_PAUSE_CANCEL2      0x31f
22675         $LCTL set_param fail_loc=0x8000031f
22676
22677         cancel_lru_locks osc &
22678         sleep 1
22679
22680 #define OBD_FAIL_LDLM_PROLONG_PAUSE      0x32b
22681         do_nodes $oss $LCTL set_param fail_loc=0x8000032b
22682         #IO takes another lock, but matches the PENDING one
22683         #and places it to the IO RPC
22684         dd if=$file of=/dev/null bs=1M count=1 iflag=direct ||
22685                 error "failed to read a file with PENDING lock"
22686 }
22687 run_test 275 "Read on a canceled duplicate lock"
22688
22689 test_276() {
22690         remote_ost_nodsh && skip "remote OST with nodsh"
22691         local pid
22692
22693         do_facet ost1 "(while true; do \
22694                 $LCTL get_param obdfilter.*.filesfree > /dev/null 2>&1; \
22695                 done) & pid=\\\$!; echo \\\$pid > $TMP/sanity_276_pid" &
22696         pid=$!
22697
22698         for LOOP in $(seq 20); do
22699                 stop ost1
22700                 start ost1 $(ostdevname 1) $OST_MOUNT_OPTS
22701         done
22702         kill -9 $pid
22703         do_facet ost1 "pid=\\\$(cat $TMP/sanity_276_pid); kill -9 \\\$pid; \
22704                 rm $TMP/sanity_276_pid"
22705 }
22706 run_test 276 "Race between mount and obd_statfs"
22707
22708 test_277() {
22709         $LCTL set_param ldlm.namespaces.*.lru_size=0
22710         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
22711         local cached_mb=$($LCTL get_param llite.*.max_cached_mb |
22712                         grep ^used_mb | awk '{print $2}')
22713         [ $cached_mb -eq 1 ] || error "expected mb 1 got $cached_mb"
22714         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 \
22715                 oflag=direct conv=notrunc
22716         cached_mb=$($LCTL get_param llite.*.max_cached_mb |
22717                         grep ^used_mb | awk '{print $2}')
22718         [ $cached_mb -eq 0 ] || error "expected mb 0 got $cached_mb"
22719 }
22720 run_test 277 "Direct IO shall drop page cache"
22721
22722 test_278() {
22723         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
22724         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
22725         [[ "$(facet_host mds1)" != "$(facet_host mds2)" ]] &&
22726                 skip "needs the same host for mdt1 mdt2" && return
22727
22728         local pid1
22729         local pid2
22730
22731 #define OBD_FAIL_OBD_STOP_MDS_RACE     0x60b
22732         do_facet mds2 $LCTL set_param fail_loc=0x8000060c
22733         stop mds2 &
22734         pid2=$!
22735
22736         stop mds1
22737
22738         echo "Starting MDTs"
22739         start mds1 $(mdsdevname 1) $MDS_MOUNT_OPTS
22740         wait $pid2
22741 #For the error assertion will happen. lu_env_get_key(..., &mdt_thread_key)
22742 #will return NULL
22743         do_facet mds2 $LCTL set_param fail_loc=0
22744
22745         start mds2 $(mdsdevname 2) $MDS_MOUNT_OPTS
22746         wait_recovery_complete mds2
22747 }
22748 run_test 278 "Race starting MDS between MDTs stop/start"
22749
22750 test_280() {
22751         [ $MGS_VERSION -lt $(version_code 2.13.52) ] &&
22752                 skip "Need MGS version at least 2.13.52"
22753         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22754         combined_mgs_mds || skip "needs combined MGS/MDT"
22755
22756         umount_client $MOUNT
22757 #define OBD_FAIL_MDS_LLOG_UMOUNT_RACE   0x15e
22758         do_facet mgs $LCTL set_param fail_loc=0x8000015e fail_val=0
22759
22760         mount_client $MOUNT &
22761         sleep 1
22762         stop mgs || error "stop mgs failed"
22763         #for a race mgs would crash
22764         start mgs $(mgsdevname) $MGS_MOUNT_OPTS || error "start mgs failed"
22765         # make sure we unmount client before remounting
22766         wait
22767         umount_client $MOUNT
22768         mount_client $MOUNT || error "mount client failed"
22769 }
22770 run_test 280 "Race between MGS umount and client llog processing"
22771
22772 cleanup_test_300() {
22773         trap 0
22774         umask $SAVE_UMASK
22775 }
22776 test_striped_dir() {
22777         local mdt_index=$1
22778         local stripe_count
22779         local stripe_index
22780
22781         mkdir -p $DIR/$tdir
22782
22783         SAVE_UMASK=$(umask)
22784         trap cleanup_test_300 RETURN EXIT
22785
22786         $LFS setdirstripe -i $mdt_index -c 2 -H all_char -o 755 \
22787                                                 $DIR/$tdir/striped_dir ||
22788                 error "set striped dir error"
22789
22790         local mode=$(stat -c%a $DIR/$tdir/striped_dir)
22791         [ "$mode" = "755" ] || error "expect 755 got $mode"
22792
22793         $LFS getdirstripe $DIR/$tdir/striped_dir > /dev/null 2>&1 ||
22794                 error "getdirstripe failed"
22795         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir)
22796         if [ "$stripe_count" != "2" ]; then
22797                 error "1:stripe_count is $stripe_count, expect 2"
22798         fi
22799         stripe_count=$($LFS getdirstripe -T $DIR/$tdir/striped_dir)
22800         if [ "$stripe_count" != "2" ]; then
22801                 error "2:stripe_count is $stripe_count, expect 2"
22802         fi
22803
22804         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir)
22805         if [ "$stripe_index" != "$mdt_index" ]; then
22806                 error "stripe_index is $stripe_index, expect $mdt_index"
22807         fi
22808
22809         [ $(stat -c%h $DIR/$tdir/striped_dir) == '2' ] ||
22810                 error "nlink error after create striped dir"
22811
22812         mkdir $DIR/$tdir/striped_dir/a
22813         mkdir $DIR/$tdir/striped_dir/b
22814
22815         stat $DIR/$tdir/striped_dir/a ||
22816                 error "create dir under striped dir failed"
22817         stat $DIR/$tdir/striped_dir/b ||
22818                 error "create dir under striped dir failed"
22819
22820         [ $(stat -c%h $DIR/$tdir/striped_dir) == '4' ] ||
22821                 error "nlink error after mkdir"
22822
22823         rmdir $DIR/$tdir/striped_dir/a
22824         [ $(stat -c%h $DIR/$tdir/striped_dir) == '3' ] ||
22825                 error "nlink error after rmdir"
22826
22827         rmdir $DIR/$tdir/striped_dir/b
22828         [ $(stat -c%h $DIR/$tdir/striped_dir) == '2' ] ||
22829                 error "nlink error after rmdir"
22830
22831         chattr +i $DIR/$tdir/striped_dir
22832         createmany -o $DIR/$tdir/striped_dir/f 10 &&
22833                 error "immutable flags not working under striped dir!"
22834         chattr -i $DIR/$tdir/striped_dir
22835
22836         rmdir $DIR/$tdir/striped_dir ||
22837                 error "rmdir striped dir error"
22838
22839         cleanup_test_300
22840
22841         true
22842 }
22843
22844 test_300a() {
22845         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
22846                 skip "skipped for lustre < 2.7.0"
22847         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22848         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22849
22850         test_striped_dir 0 || error "failed on striped dir on MDT0"
22851         test_striped_dir 1 || error "failed on striped dir on MDT0"
22852 }
22853 run_test 300a "basic striped dir sanity test"
22854
22855 test_300b() {
22856         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
22857                 skip "skipped for lustre < 2.7.0"
22858         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22859         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22860
22861         local i
22862         local mtime1
22863         local mtime2
22864         local mtime3
22865
22866         test_mkdir $DIR/$tdir || error "mkdir fail"
22867         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
22868                 error "set striped dir error"
22869         for i in {0..9}; do
22870                 mtime1=$(stat -c %Y $DIR/$tdir/striped_dir)
22871                 sleep 1
22872                 touch $DIR/$tdir/striped_dir/file_$i || error "touch error $i"
22873                 mtime2=$(stat -c %Y $DIR/$tdir/striped_dir)
22874                 [ $mtime1 -eq $mtime2 ] && error "mtime unchanged after create"
22875                 sleep 1
22876                 rm -f $DIR/$tdir/striped_dir/file_$i || error "unlink error $i"
22877                 mtime3=$(stat -c %Y $DIR/$tdir/striped_dir)
22878                 [ $mtime2 -eq $mtime3 ] && error "mtime unchanged after unlink"
22879         done
22880         true
22881 }
22882 run_test 300b "check ctime/mtime for striped dir"
22883
22884 test_300c() {
22885         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
22886                 skip "skipped for lustre < 2.7.0"
22887         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22888         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22889
22890         local file_count
22891
22892         mkdir_on_mdt0 $DIR/$tdir
22893         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir ||
22894                 error "set striped dir error"
22895
22896         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/striped_dir ||
22897                 error "chown striped dir failed"
22898
22899         $RUNAS createmany -o $DIR/$tdir/striped_dir/f 5000 ||
22900                 error "create 5k files failed"
22901
22902         file_count=$(ls $DIR/$tdir/striped_dir | wc -l)
22903
22904         [ "$file_count" = 5000 ] || error "file count $file_count != 5000"
22905
22906         rm -rf $DIR/$tdir
22907 }
22908 run_test 300c "chown && check ls under striped directory"
22909
22910 test_300d() {
22911         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
22912                 skip "skipped for lustre < 2.7.0"
22913         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22914         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22915
22916         local stripe_count
22917         local file
22918
22919         mkdir -p $DIR/$tdir
22920         $LFS setstripe -c 2 $DIR/$tdir
22921
22922         #local striped directory
22923         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
22924                 error "set striped dir error"
22925         #look at the directories for debug purposes
22926         ls -l $DIR/$tdir
22927         $LFS getdirstripe $DIR/$tdir
22928         ls -l $DIR/$tdir/striped_dir
22929         $LFS getdirstripe $DIR/$tdir/striped_dir
22930         createmany -o $DIR/$tdir/striped_dir/f 10 ||
22931                 error "create 10 files failed"
22932
22933         #remote striped directory
22934         $LFS setdirstripe -i 1 -c 2 $DIR/$tdir/remote_striped_dir ||
22935                 error "set striped dir error"
22936         #look at the directories for debug purposes
22937         ls -l $DIR/$tdir
22938         $LFS getdirstripe $DIR/$tdir
22939         ls -l $DIR/$tdir/remote_striped_dir
22940         $LFS getdirstripe $DIR/$tdir/remote_striped_dir
22941         createmany -o $DIR/$tdir/remote_striped_dir/f 10 ||
22942                 error "create 10 files failed"
22943
22944         for file in $(find $DIR/$tdir); do
22945                 stripe_count=$($LFS getstripe -c $file)
22946                 [ $stripe_count -eq 2 ] ||
22947                         error "wrong stripe $stripe_count for $file"
22948         done
22949
22950         rm -rf $DIR/$tdir
22951 }
22952 run_test 300d "check default stripe under striped directory"
22953
22954 test_300e() {
22955         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
22956                 skip "Need MDS version at least 2.7.55"
22957         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22958         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22959
22960         local stripe_count
22961         local file
22962
22963         mkdir -p $DIR/$tdir
22964
22965         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
22966                 error "set striped dir error"
22967
22968         touch $DIR/$tdir/striped_dir/a
22969         touch $DIR/$tdir/striped_dir/b
22970         touch $DIR/$tdir/striped_dir/c
22971
22972         mkdir $DIR/$tdir/striped_dir/dir_a
22973         mkdir $DIR/$tdir/striped_dir/dir_b
22974         mkdir $DIR/$tdir/striped_dir/dir_c
22975
22976         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_a ||
22977                 error "set striped adir under striped dir error"
22978
22979         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_b ||
22980                 error "set striped bdir under striped dir error"
22981
22982         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_c ||
22983                 error "set striped cdir under striped dir error"
22984
22985         mrename $DIR/$tdir/striped_dir/dir_a $DIR/$tdir/striped_dir/dir_b ||
22986                 error "rename dir under striped dir fails"
22987
22988         mrename $DIR/$tdir/striped_dir/stp_a $DIR/$tdir/striped_dir/stp_b ||
22989                 error "rename dir under different stripes fails"
22990
22991         mrename $DIR/$tdir/striped_dir/a $DIR/$tdir/striped_dir/c ||
22992                 error "rename file under striped dir should succeed"
22993
22994         mrename $DIR/$tdir/striped_dir/dir_b $DIR/$tdir/striped_dir/dir_c ||
22995                 error "rename dir under striped dir should succeed"
22996
22997         rm -rf $DIR/$tdir
22998 }
22999 run_test 300e "check rename under striped directory"
23000
23001 test_300f() {
23002         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23003         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23004         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23005                 skip "Need MDS version at least 2.7.55"
23006
23007         local stripe_count
23008         local file
23009
23010         rm -rf $DIR/$tdir
23011         mkdir -p $DIR/$tdir
23012
23013         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
23014                 error "set striped dir error"
23015
23016         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir1 ||
23017                 error "set striped dir error"
23018
23019         touch $DIR/$tdir/striped_dir/a
23020         mkdir $DIR/$tdir/striped_dir/dir_a
23021         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir/stp_a ||
23022                 error "create striped dir under striped dir fails"
23023
23024         touch $DIR/$tdir/striped_dir1/b
23025         mkdir $DIR/$tdir/striped_dir1/dir_b
23026         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir/stp_b ||
23027                 error "create striped dir under striped dir fails"
23028
23029         mrename $DIR/$tdir/striped_dir/dir_a $DIR/$tdir/striped_dir1/dir_b ||
23030                 error "rename dir under different striped dir should fail"
23031
23032         mrename $DIR/$tdir/striped_dir/stp_a $DIR/$tdir/striped_dir1/stp_b ||
23033                 error "rename striped dir under diff striped dir should fail"
23034
23035         mrename $DIR/$tdir/striped_dir/a $DIR/$tdir/striped_dir1/a ||
23036                 error "rename file under diff striped dirs fails"
23037
23038         rm -rf $DIR/$tdir
23039 }
23040 run_test 300f "check rename cross striped directory"
23041
23042 test_300_check_default_striped_dir()
23043 {
23044         local dirname=$1
23045         local default_count=$2
23046         local default_index=$3
23047         local stripe_count
23048         local stripe_index
23049         local dir_stripe_index
23050         local dir
23051
23052         echo "checking $dirname $default_count $default_index"
23053         $LFS setdirstripe -D -c $default_count -i $default_index \
23054                                 -H all_char $DIR/$tdir/$dirname ||
23055                 error "set default stripe on striped dir error"
23056         stripe_count=$($LFS getdirstripe -D -c $DIR/$tdir/$dirname)
23057         [ $stripe_count -eq $default_count ] ||
23058                 error "expect $default_count get $stripe_count for $dirname"
23059
23060         stripe_index=$($LFS getdirstripe -D -i $DIR/$tdir/$dirname)
23061         [ $stripe_index -eq $default_index ] ||
23062                 error "expect $default_index get $stripe_index for $dirname"
23063
23064         mkdir $DIR/$tdir/$dirname/{test1,test2,test3,test4} ||
23065                                                 error "create dirs failed"
23066
23067         createmany -o $DIR/$tdir/$dirname/f- 10 || error "create files failed"
23068         unlinkmany $DIR/$tdir/$dirname/f- 10    || error "unlink files failed"
23069         for dir in $(find $DIR/$tdir/$dirname/*); do
23070                 stripe_count=$($LFS getdirstripe -c $dir)
23071                 (( $stripe_count == $default_count )) ||
23072                 (( $stripe_count == $MDSCOUNT && $default_count == -1 )) ||
23073                 (( $stripe_count == 0 )) || (( $default_count == 1 )) ||
23074                 error "stripe count $default_count != $stripe_count for $dir"
23075
23076                 stripe_index=$($LFS getdirstripe -i $dir)
23077                 [ $default_index -eq -1 ] ||
23078                         [ $stripe_index -eq $default_index ] ||
23079                         error "$stripe_index != $default_index for $dir"
23080
23081                 #check default stripe
23082                 stripe_count=$($LFS getdirstripe -D -c $dir)
23083                 [ $stripe_count -eq $default_count ] ||
23084                 error "default count $default_count != $stripe_count for $dir"
23085
23086                 stripe_index=$($LFS getdirstripe -D -i $dir)
23087                 [ $stripe_index -eq $default_index ] ||
23088                 error "default index $default_index != $stripe_index for $dir"
23089         done
23090         rmdir $DIR/$tdir/$dirname/* || error "rmdir failed"
23091 }
23092
23093 test_300g() {
23094         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23095         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23096                 skip "Need MDS version at least 2.7.55"
23097
23098         local dir
23099         local stripe_count
23100         local stripe_index
23101
23102         mkdir_on_mdt0 $DIR/$tdir
23103         mkdir $DIR/$tdir/normal_dir
23104
23105         #Checking when client cache stripe index
23106         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
23107         $LFS setdirstripe -D -i1 $DIR/$tdir/striped_dir ||
23108                 error "create striped_dir failed"
23109
23110         $LFS setdirstripe -i0 $DIR/$tdir/striped_dir/dir0 ||
23111                 error "create dir0 fails"
23112         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/dir0)
23113         [ $stripe_index -eq 0 ] ||
23114                 error "dir0 expect index 0 got $stripe_index"
23115
23116         mkdir $DIR/$tdir/striped_dir/dir1 ||
23117                 error "create dir1 fails"
23118         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/dir1)
23119         [ $stripe_index -eq 1 ] ||
23120                 error "dir1 expect index 1 got $stripe_index"
23121
23122         #check default stripe count/stripe index
23123         test_300_check_default_striped_dir normal_dir $MDSCOUNT 1
23124         test_300_check_default_striped_dir normal_dir 1 0
23125         test_300_check_default_striped_dir normal_dir -1 1
23126         test_300_check_default_striped_dir normal_dir 2 -1
23127
23128         #delete default stripe information
23129         echo "delete default stripeEA"
23130         $LFS setdirstripe -d $DIR/$tdir/normal_dir ||
23131                 error "set default stripe on striped dir error"
23132
23133         mkdir -p $DIR/$tdir/normal_dir/{test1,test2,test3,test4}
23134         for dir in $(find $DIR/$tdir/normal_dir/*); do
23135                 stripe_count=$($LFS getdirstripe -c $dir)
23136                 [ $stripe_count -eq 0 ] ||
23137                         error "expect 1 get $stripe_count for $dir"
23138         done
23139 }
23140 run_test 300g "check default striped directory for normal directory"
23141
23142 test_300h() {
23143         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23144         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23145                 skip "Need MDS version at least 2.7.55"
23146
23147         local dir
23148         local stripe_count
23149
23150         mkdir $DIR/$tdir
23151         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
23152                 error "set striped dir error"
23153
23154         test_300_check_default_striped_dir striped_dir $MDSCOUNT 1
23155         test_300_check_default_striped_dir striped_dir 1 0
23156         test_300_check_default_striped_dir striped_dir -1 1
23157         test_300_check_default_striped_dir striped_dir 2 -1
23158
23159         #delete default stripe information
23160         $LFS setdirstripe -d $DIR/$tdir/striped_dir ||
23161                 error "set default stripe on striped dir error"
23162
23163         mkdir -p $DIR/$tdir/striped_dir/{test1,test2,test3,test4}
23164         for dir in $(find $DIR/$tdir/striped_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 300h "check default striped directory for striped directory"
23171
23172 test_300i() {
23173         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23174         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23175         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23176                 skip "Need MDS version at least 2.7.55"
23177
23178         local stripe_count
23179         local file
23180
23181         mkdir $DIR/$tdir
23182
23183         $LFS setdirstripe -i 0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
23184                 error "set striped dir error"
23185
23186         createmany -o $DIR/$tdir/striped_dir/f- 10 ||
23187                 error "create files under striped dir failed"
23188
23189         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/hashdir ||
23190                 error "set striped hashdir error"
23191
23192         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/hashdir/d0 ||
23193                 error "create dir0 under hash dir failed"
23194         $LFS setdirstripe -i0 -c$MDSCOUNT -H fnv_1a_64 $DIR/$tdir/hashdir/d1 ||
23195                 error "create dir1 under hash dir failed"
23196         $LFS setdirstripe -i0 -c$MDSCOUNT -H crush $DIR/$tdir/hashdir/d2 ||
23197                 error "create dir2 under hash dir failed"
23198
23199         # unfortunately, we need to umount to clear dir layout cache for now
23200         # once we fully implement dir layout, we can drop this
23201         umount_client $MOUNT || error "umount failed"
23202         mount_client $MOUNT || error "mount failed"
23203
23204         $LFS find -H fnv_1a_64,crush $DIR/$tdir/hashdir
23205         local dircnt=$($LFS find -H fnv_1a_64,crush $DIR/$tdir/hashdir | wc -l)
23206         [ $dircnt -eq 2 ] || error "lfs find striped dir got:$dircnt,except:1"
23207
23208         #set the stripe to be unknown hash type
23209         #define OBD_FAIL_UNKNOWN_LMV_STRIPE     0x1901
23210         $LCTL set_param fail_loc=0x1901
23211         for ((i = 0; i < 10; i++)); do
23212                 $CHECKSTAT -t file $DIR/$tdir/striped_dir/f-$i ||
23213                         error "stat f-$i failed"
23214                 rm $DIR/$tdir/striped_dir/f-$i || error "unlink f-$i failed"
23215         done
23216
23217         touch $DIR/$tdir/striped_dir/f0 &&
23218                 error "create under striped dir with unknown hash should fail"
23219
23220         $LCTL set_param fail_loc=0
23221
23222         umount_client $MOUNT || error "umount failed"
23223         mount_client $MOUNT || error "mount failed"
23224
23225         return 0
23226 }
23227 run_test 300i "client handle unknown hash type striped directory"
23228
23229 test_300j() {
23230         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23231         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23232         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23233                 skip "Need MDS version at least 2.7.55"
23234
23235         local stripe_count
23236         local file
23237
23238         mkdir $DIR/$tdir
23239
23240         #define OBD_FAIL_SPLIT_UPDATE_REC       0x1702
23241         $LCTL set_param fail_loc=0x1702
23242         $LFS setdirstripe -i 0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
23243                 error "set striped dir error"
23244
23245         createmany -o $DIR/$tdir/striped_dir/f- 10 ||
23246                 error "create files under striped dir failed"
23247
23248         $LCTL set_param fail_loc=0
23249
23250         rm -rf $DIR/$tdir || error "unlink striped dir fails"
23251
23252         return 0
23253 }
23254 run_test 300j "test large update record"
23255
23256 test_300k() {
23257         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23258         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23259         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23260                 skip "Need MDS version at least 2.7.55"
23261
23262         # this test needs a huge transaction
23263         local kb
23264         kb=$(do_facet $SINGLEMDS "$LCTL get_param -n \
23265              osd*.$FSNAME-MDT0000.kbytestotal")
23266         [ $kb -lt $((1024*1024)) ] && skip "MDT0 too small: $kb"
23267
23268         local stripe_count
23269         local file
23270
23271         mkdir $DIR/$tdir
23272
23273         #define OBD_FAIL_LARGE_STRIPE   0x1703
23274         $LCTL set_param fail_loc=0x1703
23275         $LFS setdirstripe -i 0 -c192 $DIR/$tdir/striped_dir ||
23276                 error "set striped dir error"
23277         $LCTL set_param fail_loc=0
23278
23279         $LFS getdirstripe $DIR/$tdir/striped_dir ||
23280                 error "getstripeddir fails"
23281         rm -rf $DIR/$tdir/striped_dir ||
23282                 error "unlink striped dir fails"
23283
23284         return 0
23285 }
23286 run_test 300k "test large striped directory"
23287
23288 test_300l() {
23289         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23290         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23291         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23292                 skip "Need MDS version at least 2.7.55"
23293
23294         local stripe_index
23295
23296         test_mkdir -p $DIR/$tdir/striped_dir
23297         chown $RUNAS_ID $DIR/$tdir/striped_dir ||
23298                         error "chown $RUNAS_ID failed"
23299         $LFS setdirstripe -i 1 -D $DIR/$tdir/striped_dir ||
23300                 error "set default striped dir failed"
23301
23302         #define OBD_FAIL_MDS_STALE_DIR_LAYOUT    0x158
23303         $LCTL set_param fail_loc=0x80000158
23304         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir || error "create dir fails"
23305
23306         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/test_dir)
23307         [ $stripe_index -eq 1 ] ||
23308                 error "expect 1 get $stripe_index for $dir"
23309 }
23310 run_test 300l "non-root user to create dir under striped dir with stale layout"
23311
23312 test_300m() {
23313         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23314         [ $MDSCOUNT -ge 2 ] && skip_env "Only for single MDT"
23315         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23316                 skip "Need MDS version at least 2.7.55"
23317
23318         mkdir -p $DIR/$tdir/striped_dir
23319         $LFS setdirstripe -D -c 1 $DIR/$tdir/striped_dir ||
23320                 error "set default stripes dir error"
23321
23322         mkdir $DIR/$tdir/striped_dir/a || error "mkdir a fails"
23323
23324         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir/a)
23325         [ $stripe_count -eq 0 ] ||
23326                         error "expect 0 get $stripe_count for a"
23327
23328         $LFS setdirstripe -D -c 2 $DIR/$tdir/striped_dir ||
23329                 error "set default stripes dir error"
23330
23331         mkdir $DIR/$tdir/striped_dir/b || error "mkdir b fails"
23332
23333         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir/b)
23334         [ $stripe_count -eq 0 ] ||
23335                         error "expect 0 get $stripe_count for b"
23336
23337         $LFS setdirstripe -D -c1 -i2 $DIR/$tdir/striped_dir ||
23338                 error "set default stripes dir error"
23339
23340         mkdir $DIR/$tdir/striped_dir/c &&
23341                 error "default stripe_index is invalid, mkdir c should fails"
23342
23343         rm -rf $DIR/$tdir || error "rmdir fails"
23344 }
23345 run_test 300m "setstriped directory on single MDT FS"
23346
23347 cleanup_300n() {
23348         local list=$(comma_list $(mdts_nodes))
23349
23350         trap 0
23351         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
23352 }
23353
23354 test_300n() {
23355         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23356         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23357         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23358                 skip "Need MDS version at least 2.7.55"
23359         remote_mds_nodsh && skip "remote MDS with nodsh"
23360
23361         local stripe_index
23362         local list=$(comma_list $(mdts_nodes))
23363
23364         trap cleanup_300n RETURN EXIT
23365         mkdir -p $DIR/$tdir
23366         chmod 777 $DIR/$tdir
23367         $RUNAS $LFS setdirstripe -i0 -c$MDSCOUNT \
23368                                 $DIR/$tdir/striped_dir > /dev/null 2>&1 &&
23369                 error "create striped dir succeeds with gid=0"
23370
23371         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=-1
23372         $RUNAS $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir ||
23373                 error "create striped dir fails with gid=-1"
23374
23375         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
23376         $RUNAS $LFS setdirstripe -i 1 -c$MDSCOUNT -D \
23377                                 $DIR/$tdir/striped_dir > /dev/null 2>&1 &&
23378                 error "set default striped dir succeeds with gid=0"
23379
23380
23381         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=-1
23382         $RUNAS $LFS setdirstripe -i 1 -c$MDSCOUNT -D $DIR/$tdir/striped_dir ||
23383                 error "set default striped dir fails with gid=-1"
23384
23385
23386         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
23387         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir ||
23388                                         error "create test_dir fails"
23389         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir1 ||
23390                                         error "create test_dir1 fails"
23391         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir2 ||
23392                                         error "create test_dir2 fails"
23393         cleanup_300n
23394 }
23395 run_test 300n "non-root user to create dir under striped dir with default EA"
23396
23397 test_300o() {
23398         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23399         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23400         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23401                 skip "Need MDS version at least 2.7.55"
23402
23403         local numfree1
23404         local numfree2
23405
23406         mkdir -p $DIR/$tdir
23407
23408         numfree1=$(lctl get_param -n mdc.*MDT0000*.filesfree)
23409         numfree2=$(lctl get_param -n mdc.*MDT0001*.filesfree)
23410         if [ $numfree1 -lt 66000 ] || [ $numfree2 -lt 66000 ]; then
23411                 skip "not enough free inodes $numfree1 $numfree2"
23412         fi
23413
23414         numfree1=$(lctl get_param -n mdc.*MDT0000-mdc-*.kbytesfree)
23415         numfree2=$(lctl get_param -n mdc.*MDT0001-mdc-*.kbytesfree)
23416         if [ $numfree1 -lt 300000 ] || [ $numfree2 -lt 300000 ]; then
23417                 skip "not enough free space $numfree1 $numfree2"
23418         fi
23419
23420         $LFS setdirstripe -c2 $DIR/$tdir/striped_dir ||
23421                 error "setdirstripe fails"
23422
23423         createmany -d $DIR/$tdir/striped_dir/d 131000 ||
23424                 error "create dirs fails"
23425
23426         $LCTL set_param ldlm.namespaces.*mdc-*.lru_size=0
23427         ls $DIR/$tdir/striped_dir > /dev/null ||
23428                 error "ls striped dir fails"
23429         unlinkmany -d $DIR/$tdir/striped_dir/d 131000 ||
23430                 error "unlink big striped dir fails"
23431 }
23432 run_test 300o "unlink big sub stripe(> 65000 subdirs)"
23433
23434 test_300p() {
23435         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23436         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23437         remote_mds_nodsh && skip "remote MDS with nodsh"
23438
23439         mkdir_on_mdt0 $DIR/$tdir
23440
23441         #define OBD_FAIL_OUT_ENOSPC     0x1704
23442         do_facet mds2 lctl set_param fail_loc=0x80001704
23443         $LFS setdirstripe -i 0 -c2 $DIR/$tdir/bad_striped_dir > /dev/null 2>&1 \
23444                  && error "create striped directory should fail"
23445
23446         [ -e $DIR/$tdir/bad_striped_dir ] && error "striped dir exists"
23447
23448         $LFS setdirstripe -c2 $DIR/$tdir/bad_striped_dir
23449         true
23450 }
23451 run_test 300p "create striped directory without space"
23452
23453 test_300q() {
23454         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23455         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23456
23457         local fd=$(free_fd)
23458         local cmd="exec $fd<$tdir"
23459         cd $DIR
23460         $LFS mkdir -c $MDSCOUNT $tdir || error "create $tdir fails"
23461         eval $cmd
23462         cmd="exec $fd<&-"
23463         trap "eval $cmd" EXIT
23464         cd $tdir || error "cd $tdir fails"
23465         rmdir  ../$tdir || error "rmdir $tdir fails"
23466         mkdir local_dir && error "create dir succeeds"
23467         $LFS setdirstripe -i1 remote_dir && error "create remote dir succeeds"
23468         eval $cmd
23469         return 0
23470 }
23471 run_test 300q "create remote directory under orphan directory"
23472
23473 test_300r() {
23474         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23475                 skip "Need MDS version at least 2.7.55" && return
23476         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
23477
23478         mkdir $DIR/$tdir
23479
23480         $LFS setdirstripe -i 0 -c -1 $DIR/$tdir/striped_dir ||
23481                 error "set striped dir error"
23482
23483         $LFS getdirstripe $DIR/$tdir/striped_dir ||
23484                 error "getstripeddir fails"
23485
23486         local stripe_count
23487         stripe_count=$($LFS getdirstripe $DIR/$tdir/striped_dir |
23488                       awk '/lmv_stripe_count:/ { print $2 }')
23489
23490         [ $MDSCOUNT -ne $stripe_count ] &&
23491                 error "wrong stripe count $stripe_count expected $MDSCOUNT"
23492
23493         rm -rf $DIR/$tdir/striped_dir ||
23494                 error "unlink striped dir fails"
23495 }
23496 run_test 300r "test -1 striped directory"
23497
23498 test_300s_helper() {
23499         local count=$1
23500
23501         local stripe_dir=$DIR/$tdir/striped_dir.$count
23502
23503         $LFS mkdir -c $count $stripe_dir ||
23504                 error "lfs mkdir -c error"
23505
23506         $LFS getdirstripe $stripe_dir ||
23507                 error "lfs getdirstripe fails"
23508
23509         local stripe_count
23510         stripe_count=$($LFS getdirstripe $stripe_dir |
23511                       awk '/lmv_stripe_count:/ { print $2 }')
23512
23513         [ $count -ne $stripe_count ] &&
23514                 error_noexit "bad stripe count $stripe_count expected $count"
23515
23516         local dupe_stripes
23517         dupe_stripes=$($LFS getdirstripe $stripe_dir |
23518                 awk '/0x/ {count[$1] += 1}; END {
23519                         for (idx in count) {
23520                                 if (count[idx]>1) {
23521                                         print "index " idx " count " count[idx]
23522                                 }
23523                         }
23524                 }')
23525
23526         if [[ -n "$dupe_stripes" ]] ; then
23527                 lfs getdirstripe $stripe_dir
23528                 error_noexit "Dupe MDT above: $dupe_stripes "
23529         fi
23530
23531         rm -rf $stripe_dir ||
23532                 error_noexit "unlink $stripe_dir fails"
23533 }
23534
23535 test_300s() {
23536         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
23537                 skip "Need MDS version at least 2.7.55" && return
23538         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
23539
23540         mkdir $DIR/$tdir
23541         for count in $(seq 2 $MDSCOUNT); do
23542                 test_300s_helper $count
23543         done
23544 }
23545 run_test 300s "test lfs mkdir -c without -i"
23546
23547
23548 prepare_remote_file() {
23549         mkdir $DIR/$tdir/src_dir ||
23550                 error "create remote source failed"
23551
23552         cp /etc/hosts $DIR/$tdir/src_dir/a ||
23553                  error "cp to remote source failed"
23554         touch $DIR/$tdir/src_dir/a
23555
23556         $LFS mkdir -i 1 $DIR/$tdir/tgt_dir ||
23557                 error "create remote target dir failed"
23558
23559         touch $DIR/$tdir/tgt_dir/b
23560
23561         mrename $DIR/$tdir/src_dir/a $DIR/$tdir/tgt_dir/b ||
23562                 error "rename dir cross MDT failed!"
23563
23564         $CHECKSTAT -t file $DIR/$tdir/src_dir/a &&
23565                 error "src_child still exists after rename"
23566
23567         $CHECKSTAT -t file $DIR/$tdir/tgt_dir/b ||
23568                 error "missing file(a) after rename"
23569
23570         diff /etc/hosts $DIR/$tdir/tgt_dir/b ||
23571                 error "diff after rename"
23572 }
23573
23574 test_310a() {
23575         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 4 MDTs"
23576         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23577
23578         local remote_file=$DIR/$tdir/tgt_dir/b
23579
23580         mkdir -p $DIR/$tdir
23581
23582         prepare_remote_file || error "prepare remote file failed"
23583
23584         #open-unlink file
23585         $OPENUNLINK $remote_file $remote_file ||
23586                 error "openunlink $remote_file failed"
23587         $CHECKSTAT -a $remote_file || error "$remote_file exists"
23588 }
23589 run_test 310a "open unlink remote file"
23590
23591 test_310b() {
23592         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 4 MDTs"
23593         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23594
23595         local remote_file=$DIR/$tdir/tgt_dir/b
23596
23597         mkdir -p $DIR/$tdir
23598
23599         prepare_remote_file || error "prepare remote file failed"
23600
23601         ln $remote_file $DIR/$tfile || error "link failed for remote file"
23602         $MULTIOP $DIR/$tfile Ouc || error "mulitop failed"
23603         $CHECKSTAT -t file $remote_file || error "check file failed"
23604 }
23605 run_test 310b "unlink remote file with multiple links while open"
23606
23607 test_310c() {
23608         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23609         [[ $MDSCOUNT -lt 4 ]] && skip_env "needs >= 4 MDTs"
23610
23611         local remote_file=$DIR/$tdir/tgt_dir/b
23612
23613         mkdir -p $DIR/$tdir
23614
23615         prepare_remote_file || error "prepare remote file failed"
23616
23617         ln $remote_file $DIR/$tfile || error "link failed for remote file"
23618         multiop_bg_pause $remote_file O_uc ||
23619                         error "mulitop failed for remote file"
23620         MULTIPID=$!
23621         $MULTIOP $DIR/$tfile Ouc
23622         kill -USR1 $MULTIPID
23623         wait $MULTIPID
23624 }
23625 run_test 310c "open-unlink remote file with multiple links"
23626
23627 #LU-4825
23628 test_311() {
23629         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23630         [ $OSTCOUNT -lt 2 ] && skip "needs >= 2 OSTs"
23631         [ $MDS1_VERSION -lt $(version_code 2.8.54) ] &&
23632                 skip "lustre < 2.8.54 does not contain LU-4825 fix"
23633         remote_mds_nodsh && skip "remote MDS with nodsh"
23634
23635         local old_iused=$($LFS df -i | awk '/OST0000/ { print $3; exit; }')
23636         local mdts=$(comma_list $(mdts_nodes))
23637
23638         mkdir -p $DIR/$tdir
23639         $LFS setstripe -i 0 -c 1 $DIR/$tdir
23640         createmany -o $DIR/$tdir/$tfile. 1000
23641
23642         # statfs data is not real time, let's just calculate it
23643         old_iused=$((old_iused + 1000))
23644
23645         local count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
23646                         osp.*OST0000*MDT0000.create_count")
23647         local max_count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
23648                                 osp.*OST0000*MDT0000.max_create_count")
23649         do_nodes $mdts "$LCTL set_param -n osp.*OST0000*.max_create_count=0"
23650
23651         $LFS setstripe -i 0 $DIR/$tdir/$tfile || error "setstripe failed"
23652         local index=$($LFS getstripe -i $DIR/$tdir/$tfile)
23653         [ $index -ne 0 ] || error "$tfile stripe index is 0"
23654
23655         unlinkmany $DIR/$tdir/$tfile. 1000
23656
23657         do_nodes $mdts "$LCTL set_param -n \
23658                         osp.*OST0000*.max_create_count=$max_count"
23659         [ $MDS1_VERSION -lt $(version_code 2.12.51) ] &&
23660                 do_nodes $mdts "$LCTL set_param -n \
23661                                 osp.*OST0000*.create_count=$count"
23662         do_nodes $mdts "$LCTL get_param osp.*OST0000*.create_count" |
23663                         grep "=0" && error "create_count is zero"
23664
23665         local new_iused
23666         for i in $(seq 120); do
23667                 new_iused=$($LFS df -i | awk '/OST0000/ { print $3; exit; }')
23668                 # system may be too busy to destroy all objs in time, use
23669                 # a somewhat small value to not fail autotest
23670                 [ $((old_iused - new_iused)) -gt 400 ] && break
23671                 sleep 1
23672         done
23673
23674         echo "waited $i sec, old Iused $old_iused, new Iused $new_iused"
23675         [ $((old_iused - new_iused)) -gt 400 ] ||
23676                 error "objs not destroyed after unlink"
23677 }
23678 run_test 311 "disable OSP precreate, and unlink should destroy objs"
23679
23680 zfs_oid_to_objid()
23681 {
23682         local ost=$1
23683         local objid=$2
23684
23685         local vdevdir=$(dirname $(facet_vdevice $ost))
23686         local cmd="$ZDB -e -p $vdevdir -ddddd $(facet_device $ost)"
23687         local zfs_zapid=$(do_facet $ost $cmd |
23688                           grep -w "/O/0/d$((objid%32))" -C 5 |
23689                           awk '/Object/{getline; print $1}')
23690         local zfs_objid=$(do_facet $ost $cmd $zfs_zapid |
23691                           awk "/$objid = /"'{printf $3}')
23692
23693         echo $zfs_objid
23694 }
23695
23696 zfs_object_blksz() {
23697         local ost=$1
23698         local objid=$2
23699
23700         local vdevdir=$(dirname $(facet_vdevice $ost))
23701         local cmd="$ZDB -e -p $vdevdir -dddd $(facet_device $ost)"
23702         local blksz=$(do_facet $ost $cmd $objid |
23703                       awk '/dblk/{getline; printf $4}')
23704
23705         case "${blksz: -1}" in
23706                 k|K) blksz=$((${blksz:0:$((${#blksz} - 1))}*1024)) ;;
23707                 m|M) blksz=$((${blksz:0:$((${#blksz} - 1))}*1024*1024)) ;;
23708                 *) ;;
23709         esac
23710
23711         echo $blksz
23712 }
23713
23714 test_312() { # LU-4856
23715         remote_ost_nodsh && skip "remote OST with nodsh"
23716         [ "$ost1_FSTYPE" = "zfs" ] ||
23717                 skip_env "the test only applies to zfs"
23718
23719         local max_blksz=$(do_facet ost1 \
23720                           $ZFS get -p recordsize $(facet_device ost1) |
23721                           awk '!/VALUE/{print $3}')
23722
23723         # to make life a little bit easier
23724         $LFS mkdir -c 1 -i 0 $DIR/$tdir
23725         $LFS setstripe -c 1 -i 0 $DIR/$tdir
23726
23727         local tf=$DIR/$tdir/$tfile
23728         touch $tf
23729         local oid=$($LFS getstripe $tf | awk '/obdidx/{getline; print $2}')
23730
23731         # Get ZFS object id
23732         local zfs_objid=$(zfs_oid_to_objid ost1 $oid)
23733         # block size change by sequential overwrite
23734         local bs
23735
23736         for ((bs=$PAGE_SIZE; bs <= max_blksz; bs *= 4)) ; do
23737                 dd if=/dev/zero of=$tf bs=$bs count=1 oflag=sync conv=notrunc
23738
23739                 local blksz=$(zfs_object_blksz ost1 $zfs_objid)
23740                 [ $blksz -eq $bs ] || error "blksz error: $blksz, expected: $bs"
23741         done
23742         rm -f $tf
23743
23744         # block size change by sequential append write
23745         dd if=/dev/zero of=$tf bs=$PAGE_SIZE count=1 oflag=sync conv=notrunc
23746         oid=$($LFS getstripe $tf | awk '/obdidx/{getline; print $2}')
23747         zfs_objid=$(zfs_oid_to_objid ost1 $oid)
23748         local count
23749
23750         for ((count = 1; count < $((max_blksz / PAGE_SIZE)); count *= 2)); do
23751                 dd if=/dev/zero of=$tf bs=$PAGE_SIZE count=$count seek=$count \
23752                         oflag=sync conv=notrunc
23753
23754                 blksz=$(zfs_object_blksz ost1 $zfs_objid)
23755                 [ $blksz -eq $((2 * count * PAGE_SIZE)) ] ||
23756                         error "blksz error, actual $blksz, " \
23757                                 "expected: 2 * $count * $PAGE_SIZE"
23758         done
23759         rm -f $tf
23760
23761         # random write
23762         touch $tf
23763         oid=$($LFS getstripe $tf | awk '/obdidx/{getline; print $2}')
23764         zfs_objid=$(zfs_oid_to_objid ost1 $oid)
23765
23766         dd if=/dev/zero of=$tf bs=1K count=1 oflag=sync conv=notrunc
23767         blksz=$(zfs_object_blksz ost1 $zfs_objid)
23768         [ $blksz -eq $PAGE_SIZE ] ||
23769                 error "blksz error: $blksz, expected: $PAGE_SIZE"
23770
23771         dd if=/dev/zero of=$tf bs=64K count=1 oflag=sync conv=notrunc seek=128
23772         blksz=$(zfs_object_blksz ost1 $zfs_objid)
23773         [ $blksz -eq 65536 ] || error "blksz error: $blksz, expected: 64k"
23774
23775         dd if=/dev/zero of=$tf bs=1M count=1 oflag=sync conv=notrunc
23776         blksz=$(zfs_object_blksz ost1 $zfs_objid)
23777         [ $blksz -eq 65536 ] || error "rewrite error: $blksz, expected: 64k"
23778 }
23779 run_test 312 "make sure ZFS adjusts its block size by write pattern"
23780
23781 test_313() {
23782         remote_ost_nodsh && skip "remote OST with nodsh"
23783
23784         local file=$DIR/$tfile
23785
23786         rm -f $file
23787         $LFS setstripe -c 1 -i 0 $file || error "setstripe failed"
23788
23789         # define OBD_FAIL_TGT_RCVD_EIO           0x720
23790         do_facet ost1 "$LCTL set_param fail_loc=0x720"
23791         dd if=/dev/zero of=$file bs=$PAGE_SIZE oflag=direct count=1 &&
23792                 error "write should failed"
23793         do_facet ost1 "$LCTL set_param fail_loc=0"
23794         rm -f $file
23795 }
23796 run_test 313 "io should fail after last_rcvd update fail"
23797
23798 test_314() {
23799         [ $OSTCOUNT -lt 2 ] && skip "needs >= 2 OSTs"
23800
23801         $LFS setstripe -c 2 -i 0 $DIR/$tfile || error "setstripe failed"
23802         do_facet ost1 "$LCTL set_param fail_loc=0x720"
23803         rm -f $DIR/$tfile
23804         wait_delete_completed
23805         do_facet ost1 "$LCTL set_param fail_loc=0"
23806 }
23807 run_test 314 "OSP shouldn't fail after last_rcvd update failure"
23808
23809 test_315() { # LU-618
23810         [ -f /proc/$$/io ] || skip_env "no IO accounting in kernel"
23811
23812         local file=$DIR/$tfile
23813         rm -f $file
23814
23815         $MULTIOP $file oO_CREAT:O_DIRECT:O_RDWR:w4063232c ||
23816                 error "multiop file write failed"
23817         $MULTIOP $file oO_RDONLY:r4063232_c &
23818         PID=$!
23819
23820         sleep 2
23821
23822         local rbytes=$(awk '/read_bytes/ { print $2 }' /proc/$PID/io)
23823         kill -USR1 $PID
23824
23825         [ $rbytes -gt 4000000 ] || error "read is not accounted ($rbytes)"
23826         rm -f $file
23827 }
23828 run_test 315 "read should be accounted"
23829
23830 test_316() {
23831         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
23832         large_xattr_enabled || skip_env "ea_inode feature disabled"
23833
23834         rm -rf $DIR/$tdir/d
23835         mkdir -p $DIR/$tdir/d
23836         chown nobody $DIR/$tdir/d
23837         touch $DIR/$tdir/d/file
23838
23839         $LFS mv -m1 $DIR/$tdir/d || error "lfs mv failed"
23840 }
23841 run_test 316 "lfs mv"
23842
23843 test_317() {
23844         [ $MDS1_VERSION -lt $(version_code 2.11.53) ] &&
23845                 skip "Need MDS version at least 2.11.53"
23846         if [ "$ost1_FSTYPE" == "zfs" ]; then
23847                 skip "LU-10370: no implementation for ZFS"
23848         fi
23849
23850         local trunc_sz
23851         local grant_blk_size
23852
23853         grant_blk_size=$($LCTL get_param osc.$FSNAME*.import |
23854                         awk '/grant_block_size:/ { print $2; exit; }')
23855         #
23856         # Create File of size 5M. Truncate it to below size's and verify
23857         # blocks count.
23858         #
23859         dd if=/dev/zero of=$DIR/$tfile bs=5M count=1 conv=fsync ||
23860                 error "Create file $DIR/$tfile failed"
23861         stack_trap "rm -f $DIR/$tfile" EXIT
23862
23863         for trunc_sz in 2097152 4097 4000 509 0; do
23864                 $TRUNCATE $DIR/$tfile $trunc_sz ||
23865                         error "truncate $tfile to $trunc_sz failed"
23866                 local sz=$(stat --format=%s $DIR/$tfile)
23867                 local blk=$(stat --format=%b $DIR/$tfile)
23868                 local trunc_blk=$((((trunc_sz + (grant_blk_size - 1) ) /
23869                                      grant_blk_size) * 8))
23870
23871                 if [[ $blk -ne $trunc_blk ]]; then
23872                         $(which stat) $DIR/$tfile
23873                         error "Expected Block $trunc_blk got $blk for $tfile"
23874                 fi
23875
23876                 $CHECKSTAT -s $trunc_sz $DIR/$tfile ||
23877                         error "Expected Size $trunc_sz got $sz for $tfile"
23878         done
23879
23880         #
23881         # sparse file test
23882         # Create file with a hole and write actual 65536 bytes which aligned
23883         # with 4K and 64K PAGE_SIZE. Block count must be 128.
23884         #
23885         local bs=65536
23886         dd if=/dev/zero of=$DIR/$tfile bs=$bs count=1 seek=5 conv=fsync ||
23887                 error "Create file : $DIR/$tfile"
23888
23889         #
23890         # Truncate to size $trunc_sz bytes. Strip tail blocks and leave only 8
23891         # blocks. The block count must drop to 8.
23892         #
23893         trunc_sz=$(($(stat --format=%s $DIR/$tfile) - \
23894                 ((bs - grant_blk_size) + 1)))
23895         $TRUNCATE $DIR/$tfile $trunc_sz ||
23896                 error "truncate $tfile to $trunc_sz failed"
23897
23898         local trunc_bsz=$((grant_blk_size / $(stat --format=%B $DIR/$tfile)))
23899         sz=$(stat --format=%s $DIR/$tfile)
23900         blk=$(stat --format=%b $DIR/$tfile)
23901
23902         if [[ $blk -ne $trunc_bsz ]]; then
23903                 $(which stat) $DIR/$tfile
23904                 error "Expected Block $trunc_bsz got $blk for $tfile"
23905         fi
23906
23907         $CHECKSTAT -s $trunc_sz $DIR/$tfile ||
23908                 error "Expected Size $trunc_sz got $sz for $tfile"
23909 }
23910 run_test 317 "Verify blocks get correctly update after truncate"
23911
23912 test_318() {
23913         local llite_name="llite.$($LFS getname $MOUNT | awk '{print $1}')"
23914         local old_max_active=$($LCTL get_param -n \
23915                             ${llite_name}.max_read_ahead_async_active \
23916                             2>/dev/null)
23917
23918         $LCTL set_param llite.*.max_read_ahead_async_active=256
23919         local max_active=$($LCTL get_param -n \
23920                            ${llite_name}.max_read_ahead_async_active \
23921                            2>/dev/null)
23922         [ $max_active -ne 256 ] && error "expected 256 but got $max_active"
23923
23924         $LCTL set_param llite.*.max_read_ahead_async_active=0 ||
23925                 error "set max_read_ahead_async_active should succeed"
23926
23927         $LCTL set_param llite.*.max_read_ahead_async_active=512
23928         max_active=$($LCTL get_param -n \
23929                      ${llite_name}.max_read_ahead_async_active 2>/dev/null)
23930         [ $max_active -eq 512 ] || error "expected 512 but got $max_active"
23931
23932         # restore @max_active
23933         [ $old_max_active -ne 0 ] && $LCTL set_param \
23934                 llite.*.max_read_ahead_async_active=$old_max_active
23935
23936         local old_threshold=$($LCTL get_param -n \
23937                 ${llite_name}.read_ahead_async_file_threshold_mb 2>/dev/null)
23938         local max_per_file_mb=$($LCTL get_param -n \
23939                 ${llite_name}.max_read_ahead_per_file_mb 2>/dev/null)
23940
23941         local invalid=$(($max_per_file_mb + 1))
23942         $LCTL set_param \
23943                 llite.*.read_ahead_async_file_threshold_mb=$invalid\
23944                         && error "set $invalid should fail"
23945
23946         local valid=$(($invalid - 1))
23947         $LCTL set_param \
23948                 llite.*.read_ahead_async_file_threshold_mb=$valid ||
23949                         error "set $valid should succeed"
23950         local threshold=$($LCTL get_param -n \
23951                 ${llite_name}.read_ahead_async_file_threshold_mb 2>/dev/null)
23952         [ $threshold -eq $valid ] || error \
23953                 "expect threshold $valid got $threshold"
23954         $LCTL set_param \
23955                 llite.*.read_ahead_async_file_threshold_mb=$old_threshold
23956 }
23957 run_test 318 "Verify async readahead tunables"
23958
23959 test_319() {
23960         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return 0
23961
23962         local before=$(date +%s)
23963         local evict
23964         local mdir=$DIR/$tdir
23965         local file=$mdir/xxx
23966
23967         $LFS mkdir -i0 $mdir || error "mkdir $mdir fails"
23968         touch $file
23969
23970 #define OBD_FAIL_LDLM_LOCAL_CANCEL_PAUSE 0x32c
23971         $LCTL set_param fail_val=5 fail_loc=0x8000032c
23972         $LFS mv -m1 $file &
23973
23974         sleep 1
23975         dd if=$file of=/dev/null
23976         wait
23977         evict=$($LCTL get_param mdc.$FSNAME-MDT*.state |
23978           awk -F"[ [,]" '/EVICTED ]$/ { if (mx<$5) {mx=$5;} } END { print mx }')
23979
23980         [ -z "$evict" ] || [[ $evict -le $before ]] || error "eviction happened"
23981 }
23982 run_test 319 "lost lease lock on migrate error"
23983
23984 test_398a() { # LU-4198
23985         local ost1_imp=$(get_osc_import_name client ost1)
23986         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
23987                          cut -d'.' -f2)
23988
23989         $LFS setstripe -c 1 -i 0 $DIR/$tfile
23990         $LCTL set_param ldlm.namespaces.*.lru_size=clear
23991
23992         # request a new lock on client
23993         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
23994
23995         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=direct conv=notrunc
23996         local lock_count=$($LCTL get_param -n \
23997                            ldlm.namespaces.$imp_name.lru_size)
23998         [[ $lock_count -eq 0 ]] || error "lock should be cancelled by direct IO"
23999
24000         $LCTL set_param ldlm.namespaces.*-OST0000-osc-ffff*.lru_size=clear
24001
24002         # no lock cached, should use lockless IO and not enqueue new lock
24003         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=direct conv=notrunc
24004         lock_count=$($LCTL get_param -n \
24005                      ldlm.namespaces.$imp_name.lru_size)
24006         [[ $lock_count -eq 0 ]] || error "no lock should be held by direct IO"
24007 }
24008 run_test 398a "direct IO should cancel lock otherwise lockless"
24009
24010 test_398b() { # LU-4198
24011         which fio || skip_env "no fio installed"
24012         $LFS setstripe -c -1 $DIR/$tfile
24013
24014         local size=12
24015         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$size
24016
24017         local njobs=4
24018         echo "mix direct rw ${size}M to OST0 by fio with $njobs jobs..."
24019         fio --name=rand-rw --rw=randrw --bs=$PAGE_SIZE --direct=1 \
24020                 --numjobs=$njobs --fallocate=none \
24021                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
24022                 --filename=$DIR/$tfile &
24023         bg_pid=$!
24024
24025         echo "mix buffer rw ${size}M to OST0 by fio with $njobs jobs..."
24026         fio --name=rand-rw --rw=randrw --bs=$PAGE_SIZE \
24027                 --numjobs=$njobs --fallocate=none \
24028                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
24029                 --filename=$DIR/$tfile || true
24030         wait $bg_pid
24031
24032         rm -f $DIR/$tfile
24033 }
24034 run_test 398b "DIO and buffer IO race"
24035
24036 test_398c() { # LU-4198
24037         local ost1_imp=$(get_osc_import_name client ost1)
24038         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
24039                          cut -d'.' -f2)
24040
24041         which fio || skip_env "no fio installed"
24042
24043         saved_debug=$($LCTL get_param -n debug)
24044         $LCTL set_param debug=0
24045
24046         local size=$(lctl get_param -n osc.$FSNAME-OST0000*.kbytesavail | head -1)
24047         ((size /= 1024)) # by megabytes
24048         ((size /= 2)) # write half of the OST at most
24049         [ $size -gt 40 ] && size=40 #reduce test time anyway
24050
24051         $LFS setstripe -c 1 $DIR/$tfile
24052
24053         # it seems like ldiskfs reserves more space than necessary if the
24054         # writing blocks are not mapped, so it extends the file firstly
24055         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$size && sync
24056         cancel_lru_locks osc
24057
24058         # clear and verify rpc_stats later
24059         $LCTL set_param osc.${FSNAME}-OST0000-osc-ffff*.rpc_stats=clear
24060
24061         local njobs=4
24062         echo "writing ${size}M to OST0 by fio with $njobs jobs..."
24063         fio --name=rand-write --rw=randwrite --bs=$PAGE_SIZE --direct=1 \
24064                 --numjobs=$njobs --fallocate=none --ioengine=libaio \
24065                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
24066                 --filename=$DIR/$tfile
24067         [ $? -eq 0 ] || error "fio write error"
24068
24069         [ $($LCTL get_param -n ldlm.namespaces.$imp_name.lock_count) -eq 0 ] ||
24070                 error "Locks were requested while doing AIO"
24071
24072         # get the percentage of 1-page I/O
24073         pct=$($LCTL get_param osc.${imp_name}.rpc_stats |
24074                 grep -A 1 'pages per rpc' | grep -v 'pages per rpc' |
24075                 awk '{print $7}')
24076         [ $pct -le 50 ] || error "$pct% of I/O are 1-page"
24077
24078         echo "mix rw ${size}M to OST0 by fio with $njobs jobs..."
24079         fio --name=rand-rw --rw=randrw --bs=$PAGE_SIZE --direct=1 \
24080                 --numjobs=$njobs --fallocate=none --ioengine=libaio \
24081                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
24082                 --filename=$DIR/$tfile
24083         [ $? -eq 0 ] || error "fio mixed read write error"
24084
24085         echo "AIO with large block size ${size}M"
24086         fio --name=rand-rw --rw=randrw --bs=${size}M --direct=1 \
24087                 --numjobs=1 --fallocate=none --ioengine=libaio \
24088                 --iodepth=16 --allow_file_create=0 --size=${size}M \
24089                 --filename=$DIR/$tfile
24090         [ $? -eq 0 ] || error "fio large block size failed"
24091
24092         rm -f $DIR/$tfile
24093         $LCTL set_param debug="$saved_debug"
24094 }
24095 run_test 398c "run fio to test AIO"
24096
24097 test_398d() { #  LU-13846
24098         which aiocp || skip_env "no aiocp installed"
24099         local aio_file=$DIR/$tfile.aio
24100
24101         $LFS setstripe -c -1 -S 1M $DIR/$tfile $aio_file
24102
24103         dd if=/dev/urandom of=$DIR/$tfile bs=1M count=64
24104         aiocp -a $PAGE_SIZE -b 64M -s 64M -f O_DIRECT $DIR/$tfile $aio_file
24105         stack_trap "rm -f $DIR/$tfile $aio_file"
24106
24107         diff $DIR/$tfile $aio_file || error "file diff after aiocp"
24108
24109         # make sure we don't crash and fail properly
24110         aiocp -a 512 -b 64M -s 64M -f O_DIRECT $DIR/$tfile $aio_file &&
24111                 error "aio not aligned with PAGE SIZE should fail"
24112
24113         rm -f $DIR/$tfile $aio_file
24114 }
24115 run_test 398d "run aiocp to verify block size > stripe size"
24116
24117 test_398e() {
24118         dd if=/dev/zero of=$DIR/$tfile bs=1234 count=1
24119         touch $DIR/$tfile.new
24120         dd if=$DIR/$tfile of=$DIR/$tfile.new bs=1M count=1 oflag=direct
24121 }
24122 run_test 398e "O_Direct open cleared by fcntl doesn't cause hang"
24123
24124 test_398f() { #  LU-14687
24125         which aiocp || skip_env "no aiocp installed"
24126         local aio_file=$DIR/$tfile.aio
24127
24128         $LFS setstripe -c -1 -S 1M $DIR/$tfile $aio_file
24129
24130         dd if=/dev/zero of=$DIR/$tfile bs=1M count=64
24131         stack_trap "rm -f $DIR/$tfile $aio_file"
24132
24133         #define OBD_FAIL_LLITE_PAGE_ALLOC 0x1418
24134         $LCTL set_param fail_loc=0x1418
24135         # make sure we don't crash and fail properly
24136         aiocp -b 64M -s 64M -f O_DIRECT $DIR/$tfile $aio_file &&
24137                 error "aio with page allocation failure succeeded"
24138         $LCTL set_param fail_loc=0
24139         diff $DIR/$tfile $aio_file
24140         [[ $? != 0 ]] || error "no diff after failed aiocp"
24141 }
24142 run_test 398f "verify aio handles ll_direct_rw_pages errors correctly"
24143
24144 # NB: To get the parallel DIO behavior in LU-13798, there must be > 1
24145 # stripe and i/o size must be > stripe size
24146 # Old style synchronous DIO waits after submitting each chunk, resulting in a
24147 # single RPC in flight.  This test shows async DIO submission is working by
24148 # showing multiple RPCs in flight.
24149 test_398g() { #  LU-13798
24150         $LFS setstripe -o 0,0 -S 1M $DIR/$tfile
24151
24152         # We need to do some i/o first to acquire enough grant to put our RPCs
24153         # in flight; otherwise a new connection may not have enough grant
24154         # available
24155         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=1 oflag=direct ||
24156                 error "parallel dio failed"
24157         stack_trap "rm -f $DIR/$tfile"
24158
24159         # Reduce RPC size to 1M to avoid combination in to larger RPCs
24160         local pages_per_rpc=$($LCTL get_param osc.*-OST0000-*.max_pages_per_rpc)
24161         $LCTL set_param osc.*-OST0000-*.max_pages_per_rpc=1M
24162         stack_trap "$LCTL set_param -n $pages_per_rpc"
24163
24164         # Recreate file so it's empty
24165         rm -f $DIR/$tfile
24166         $LFS setstripe -o 0,0 -S 1M $DIR/$tfile
24167         #Pause rpc completion to guarantee we see multiple rpcs in flight
24168         #define OBD_FAIL_OST_BRW_PAUSE_BULK
24169         do_facet ost1 $LCTL set_param fail_loc=0x214 fail_val=2
24170         stack_trap "do_facet ost1 $LCTL set_param fail_loc=0"
24171
24172         # Clear rpc stats
24173         $LCTL set_param osc.*.rpc_stats=c
24174
24175         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=1 oflag=direct ||
24176                 error "parallel dio failed"
24177         stack_trap "rm -f $DIR/$tfile"
24178
24179         $LCTL get_param osc.*-OST0000-*.rpc_stats
24180         pct=$($LCTL get_param osc.*-OST0000-*.rpc_stats |
24181                 grep -A 8 'rpcs in flight' | grep -v 'rpcs in flight' |
24182                 grep "8:" | awk '{print $8}')
24183         # We look at the "8 rpcs in flight" field, and verify A) it is present
24184         # and B) it includes all RPCs.  This proves we had 8 RPCs in flight,
24185         # as expected for an 8M DIO to a file with 1M stripes.
24186         [ $pct -eq 100 ] || error "we should see 8 RPCs in flight"
24187
24188         # Verify turning off parallel dio works as expected
24189         # Clear rpc stats
24190         $LCTL set_param osc.*.rpc_stats=c
24191         $LCTL set_param llite.*.parallel_dio=0
24192         stack_trap '$LCTL set_param llite.*.parallel_dio=1'
24193
24194         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=1 oflag=direct ||
24195                 error "dio with parallel dio disabled failed"
24196
24197         # Ideally, we would see only one RPC in flight here, but there is an
24198         # unavoidable race between i/o completion and RPC in flight counting,
24199         # so while only 1 i/o is in flight at a time, the RPC in flight counter
24200         # will sometimes exceed 1 (3 or 4 is not rare on VM testing).
24201         # So instead we just verify it's always < 8.
24202         $LCTL get_param osc.*-OST0000-*.rpc_stats
24203         ret=$($LCTL get_param osc.*-OST0000-*.rpc_stats |
24204                 grep -A 8 'rpcs in flight' | grep -v 'rpcs in flight' |
24205                 grep '^$' -B1 | grep . | awk '{print $1}')
24206         [ $ret != "8:" ] ||
24207                 error "we should see fewer than 8 RPCs in flight (saw $ret)"
24208 }
24209 run_test 398g "verify parallel dio async RPC submission"
24210
24211 test_398h() { #  LU-13798
24212         local dio_file=$DIR/$tfile.dio
24213
24214         $LFS setstripe -C 2 -S 1M $DIR/$tfile $dio_file
24215
24216         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct
24217         stack_trap "rm -f $DIR/$tfile $dio_file"
24218
24219         dd if=$DIR/$tfile of=$dio_file bs=8M count=8 iflag=direct oflag=direct ||
24220                 error "parallel dio failed"
24221         diff $DIR/$tfile $dio_file
24222         [[ $? == 0 ]] || error "file diff after aiocp"
24223 }
24224 run_test 398h "verify correctness of read & write with i/o size >> stripe size"
24225
24226 test_398i() { #  LU-13798
24227         local dio_file=$DIR/$tfile.dio
24228
24229         $LFS setstripe -C 2 -S 1M $DIR/$tfile $dio_file
24230
24231         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct
24232         stack_trap "rm -f $DIR/$tfile $dio_file"
24233
24234         #define OBD_FAIL_LLITE_PAGE_ALLOC 0x1418
24235         $LCTL set_param fail_loc=0x1418
24236         # make sure we don't crash and fail properly
24237         dd if=$DIR/$tfile of=$dio_file bs=8M count=8 iflag=direct oflag=direct &&
24238                 error "parallel dio page allocation failure succeeded"
24239         diff $DIR/$tfile $dio_file
24240         [[ $? != 0 ]] || error "no diff after failed aiocp"
24241 }
24242 run_test 398i "verify parallel dio handles ll_direct_rw_pages errors correctly"
24243
24244 test_398j() { #  LU-13798
24245         # Stripe size > RPC size but less than i/o size tests split across
24246         # stripes and RPCs for individual i/o op
24247         $LFS setstripe -o 0,0 -S 4M $DIR/$tfile $DIR/$tfile.2
24248
24249         # Reduce RPC size to 1M to guarantee split to multiple RPCs per stripe
24250         local pages_per_rpc=$($LCTL get_param osc.*-OST0000-*.max_pages_per_rpc)
24251         $LCTL set_param osc.*-OST0000-*.max_pages_per_rpc=1M
24252         stack_trap "$LCTL set_param -n $pages_per_rpc"
24253
24254         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct ||
24255                 error "parallel dio write failed"
24256         stack_trap "rm -f $DIR/$tfile $DIR/$tfile.2"
24257
24258         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 iflag=direct ||
24259                 error "parallel dio read failed"
24260         diff $DIR/$tfile $DIR/$tfile.2
24261         [[ $? == 0 ]] || error "file diff after parallel dio read"
24262 }
24263 run_test 398j "test parallel dio where stripe size > rpc_size"
24264
24265 test_398k() { #  LU-13798
24266         wait_delete_completed
24267         wait_mds_ost_sync
24268
24269         # 4 stripe file; we will cause out of space on OST0
24270         $LFS setstripe -o 0,1,0,1 -S 1M $DIR/$tfile
24271
24272         # Fill OST0 (if it's not too large)
24273         ORIGFREE=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
24274                    head -n1)
24275         if [[ $ORIGFREE -gt $MAXFREE ]]; then
24276                 skip "$ORIGFREE > $MAXFREE skipping out-of-space test on OST0"
24277         fi
24278         $LFS setstripe -i 0 -c 1 $DIR/$tfile.1
24279         dd if=/dev/zero of=$DIR/$tfile.1 bs=1024 count=$MAXFREE &&
24280                 error "dd should fill OST0"
24281         stack_trap "rm -f $DIR/$tfile.1"
24282
24283         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct
24284         err=$?
24285
24286         ls -la $DIR/$tfile
24287         $CHECKSTAT -t file -s 0 $DIR/$tfile ||
24288                 error "file is not 0 bytes in size"
24289
24290         # dd above should not succeed, but don't error until here so we can
24291         # get debug info above
24292         [[ $err != 0 ]] ||
24293                 error "parallel dio write with enospc succeeded"
24294         stack_trap "rm -f $DIR/$tfile"
24295 }
24296 run_test 398k "test enospc on first stripe"
24297
24298 test_398l() { #  LU-13798
24299         wait_delete_completed
24300         wait_mds_ost_sync
24301
24302         # 4 stripe file; we will cause out of space on OST0
24303         # Note the 1M stripe size and the > 1M i/o size mean this ENOSPC
24304         # happens on the second i/o chunk we issue
24305         $LFS setstripe -o 1,0,1,0 -S 1M $DIR/$tfile $DIR/$tfile.2
24306
24307         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=2 oflag=direct
24308         stack_trap "rm -f $DIR/$tfile"
24309
24310         # Fill OST0 (if it's not too large)
24311         ORIGFREE=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
24312                    head -n1)
24313         if [[ $ORIGFREE -gt $MAXFREE ]]; then
24314                 skip "$ORIGFREE > $MAXFREE skipping out-of-space test on OST0"
24315         fi
24316         $LFS setstripe -i 0 -c 1 $DIR/$tfile.1
24317         dd if=/dev/zero of=$DIR/$tfile.1 bs=1024 count=$MAXFREE &&
24318                 error "dd should fill OST0"
24319         stack_trap "rm -f $DIR/$tfile.1"
24320
24321         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 oflag=direct
24322         err=$?
24323         stack_trap "rm -f $DIR/$tfile.2"
24324
24325         # Check that short write completed as expected
24326         ls -la $DIR/$tfile.2
24327         $CHECKSTAT -t file -s 1048576 $DIR/$tfile.2 ||
24328                 error "file is not 1M in size"
24329
24330         # dd above should not succeed, but don't error until here so we can
24331         # get debug info above
24332         [[ $err != 0 ]] ||
24333                 error "parallel dio write with enospc succeeded"
24334
24335         # Truncate source file to same length as output file and diff them
24336         $TRUNCATE $DIR/$tfile 1048576
24337         diff $DIR/$tfile $DIR/$tfile.2
24338         [[ $? == 0 ]] || error "data incorrect after short write"
24339 }
24340 run_test 398l "test enospc on intermediate stripe/RPC"
24341
24342 test_398m() { #  LU-13798
24343         $LFS setstripe -o 0,1,0,1 -S 1M $DIR/$tfile
24344
24345         # Set up failure on OST0, the first stripe:
24346         #define OBD_FAIL_OST_BRW_WRITE_BULK     0x20e
24347         #NB: Fail val is ost # + 1, because we cannot use cfs_fail_val = 0
24348         # So this fail_val specifies OST0
24349         do_facet ost1 $LCTL set_param fail_loc=0x20e fail_val=1
24350         stack_trap "do_facet ost1 $LCTL set_param fail_loc=0"
24351
24352         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct &&
24353                 error "parallel dio write with failure on first stripe succeeded"
24354         stack_trap "rm -f $DIR/$tfile"
24355         do_facet ost1 $LCTL set_param fail_loc=0 fail_val=0
24356
24357         # Place data in file for read
24358         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct ||
24359                 error "parallel dio write failed"
24360
24361         # Fail read on OST0, first stripe
24362         #define OBD_FAIL_OST_BRW_READ_BULK       0x20f
24363         do_facet ost1 $LCTL set_param fail_loc=0x20f fail_val=1
24364         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 iflag=direct &&
24365                 error "parallel dio read with error on first stripe succeeded"
24366         rm -f $DIR/$tfile.2
24367         do_facet ost1 $LCTL set_param fail_loc=0 fail_val=0
24368
24369         # Switch to testing on OST1, second stripe
24370         # Clear file contents, maintain striping
24371         echo > $DIR/$tfile
24372         # Set up failure on OST1, second stripe:
24373         do_facet ost1 $LCTL set_param fail_loc=0x20e fail_val=2
24374         stack_trap "do_facet ost1 $LCTL set_param fail_loc=0"
24375
24376         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct &&
24377                 error "parallel dio write with failure on first stripe succeeded"
24378         stack_trap "rm -f $DIR/$tfile"
24379         do_facet ost1 $LCTL set_param fail_loc=0 fail_val=0
24380
24381         # Place data in file for read
24382         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct ||
24383                 error "parallel dio write failed"
24384
24385         # Fail read on OST1, second stripe
24386         #define OBD_FAIL_OST_BRW_READ_BULK       0x20f
24387         do_facet ost2 $LCTL set_param fail_loc=0x20f fail_val=2
24388         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 iflag=direct &&
24389                 error "parallel dio read with error on first stripe succeeded"
24390         rm -f $DIR/$tfile.2
24391         do_facet ost2 $LCTL set_param fail_loc=0 fail_val=0
24392 }
24393 run_test 398m "test RPC failures with parallel dio"
24394
24395 # Parallel submission of DIO should not cause problems for append, but it's
24396 # important to verify.
24397 test_398n() { #  LU-13798
24398         $LFS setstripe -C 2 -S 1M $DIR/$tfile
24399
24400         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 ||
24401                 error "dd to create source file failed"
24402         stack_trap "rm -f $DIR/$tfile"
24403
24404         dd if=$DIR/$tfile of=$DIR/$tfile.1 bs=8M count=8 oflag=direct oflag=append ||
24405                 error "parallel dio write with failure on second stripe succeeded"
24406         stack_trap "rm -f $DIR/$tfile $DIR/$tfile.1"
24407         diff $DIR/$tfile $DIR/$tfile.1
24408         [[ $? == 0 ]] || error "data incorrect after append"
24409
24410 }
24411 run_test 398n "test append with parallel DIO"
24412
24413 test_fake_rw() {
24414         local read_write=$1
24415         if [ "$read_write" = "write" ]; then
24416                 local dd_cmd="dd if=/dev/zero of=$DIR/$tfile"
24417         elif [ "$read_write" = "read" ]; then
24418                 local dd_cmd="dd of=/dev/null if=$DIR/$tfile"
24419         else
24420                 error "argument error"
24421         fi
24422
24423         # turn off debug for performance testing
24424         local saved_debug=$($LCTL get_param -n debug)
24425         $LCTL set_param debug=0
24426
24427         $LFS setstripe -c 1 -i 0 $DIR/$tfile
24428
24429         # get ost1 size - $FSNAME-OST0000
24430         local ost1_avail_size=$($LFS df $DIR | awk /${ost1_svc}/'{ print $4 }')
24431         local blocks=$((ost1_avail_size/2/1024)) # half avail space by megabytes
24432         [ $blocks -gt 1000 ] && blocks=1000 # 1G in maximum
24433
24434         if [ "$read_write" = "read" ]; then
24435                 $TRUNCATE $DIR/$tfile $(expr 1048576 \* $blocks)
24436         fi
24437
24438         local start_time=$(date +%s.%N)
24439         $dd_cmd bs=1M count=$blocks oflag=sync ||
24440                 error "real dd $read_write error"
24441         local duration=$(bc <<< "$(date +%s.%N) - $start_time")
24442
24443         if [ "$read_write" = "write" ]; then
24444                 rm -f $DIR/$tfile
24445         fi
24446
24447         # define OBD_FAIL_OST_FAKE_RW           0x238
24448         do_facet ost1 $LCTL set_param fail_loc=0x238
24449
24450         local start_time=$(date +%s.%N)
24451         $dd_cmd bs=1M count=$blocks oflag=sync ||
24452                 error "fake dd $read_write error"
24453         local duration_fake=$(bc <<< "$(date +%s.%N) - $start_time")
24454
24455         if [ "$read_write" = "write" ]; then
24456                 # verify file size
24457                 cancel_lru_locks osc
24458                 $CHECKSTAT -t file -s $((blocks * 1024 * 1024)) $DIR/$tfile ||
24459                         error "$tfile size not $blocks MB"
24460         fi
24461         do_facet ost1 $LCTL set_param fail_loc=0
24462
24463         echo "fake $read_write $duration_fake vs. normal $read_write" \
24464                 "$duration in seconds"
24465         [ $(bc <<< "$duration_fake < $duration") -eq 1 ] ||
24466                 error_not_in_vm "fake write is slower"
24467
24468         $LCTL set_param -n debug="$saved_debug"
24469         rm -f $DIR/$tfile
24470 }
24471 test_399a() { # LU-7655 for OST fake write
24472         remote_ost_nodsh && skip "remote OST with nodsh"
24473
24474         test_fake_rw write
24475 }
24476 run_test 399a "fake write should not be slower than normal write"
24477
24478 test_399b() { # LU-8726 for OST fake read
24479         remote_ost_nodsh && skip "remote OST with nodsh"
24480         if [ "$ost1_FSTYPE" != "ldiskfs" ]; then
24481                 skip_env "ldiskfs only test"
24482         fi
24483
24484         test_fake_rw read
24485 }
24486 run_test 399b "fake read should not be slower than normal read"
24487
24488 test_400a() { # LU-1606, was conf-sanity test_74
24489         if ! which $CC > /dev/null 2>&1; then
24490                 skip_env "$CC is not installed"
24491         fi
24492
24493         local extra_flags=''
24494         local out=$TMP/$tfile
24495         local prefix=/usr/include/lustre
24496         local prog
24497
24498         # Oleg removes c files in his test rig so test if any c files exist
24499         [ -z "$(ls -A $LUSTRE_TESTS_API_DIR)" ] && \
24500                 skip_env "Needed c test files are missing"
24501
24502         if ! [[ -d $prefix ]]; then
24503                 # Assume we're running in tree and fixup the include path.
24504                 extra_flags+=" -I$LUSTRE/../lnet/include/uapi -I$LUSTRE/include/uapi -I$LUSTRE/include"
24505                 extra_flags+=" -L$LUSTRE/utils/.lib"
24506         fi
24507
24508         for prog in $LUSTRE_TESTS_API_DIR/*.c; do
24509                 $CC -Wall -Werror -std=c99 $extra_flags -o $out $prog -llustreapi ||
24510                         error "client api broken"
24511         done
24512         rm -f $out
24513 }
24514 run_test 400a "Lustre client api program can compile and link"
24515
24516 test_400b() { # LU-1606, LU-5011
24517         local header
24518         local out=$TMP/$tfile
24519         local prefix=/usr/include/linux/lustre
24520
24521         # We use a hard coded prefix so that this test will not fail
24522         # when run in tree. There are headers in lustre/include/lustre/
24523         # that are not packaged (like lustre_idl.h) and have more
24524         # complicated include dependencies (like config.h and lnet/types.h).
24525         # Since this test about correct packaging we just skip them when
24526         # they don't exist (see below) rather than try to fixup cppflags.
24527
24528         if ! which $CC > /dev/null 2>&1; then
24529                 skip_env "$CC is not installed"
24530         fi
24531
24532         for header in $prefix/*.h; do
24533                 if ! [[ -f "$header" ]]; then
24534                         continue
24535                 fi
24536
24537                 if [[ "$(basename $header)" == lustre_ioctl.h ]]; then
24538                         continue # lustre_ioctl.h is internal header
24539                 fi
24540
24541                 $CC -Wall -Werror -std=c99 -include $header -c -x c /dev/null -o $out ||
24542                         error "cannot compile '$header'"
24543         done
24544         rm -f $out
24545 }
24546 run_test 400b "packaged headers can be compiled"
24547
24548 test_401a() { #LU-7437
24549         local printf_arg=$(find -printf 2>&1 | grep "unrecognized:")
24550         [ -n "$printf_arg" ] && skip_env "find does not support -printf"
24551
24552         #count the number of parameters by "list_param -R"
24553         local params=$($LCTL list_param -R '*' 2>/dev/null | wc -l)
24554         #count the number of parameters by listing proc files
24555         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
24556         echo "proc_dirs='$proc_dirs'"
24557         [ -n "$proc_dirs" ] || error "no proc_dirs on $HOSTNAME"
24558         local procs=$(find -L $proc_dirs -mindepth 1 -printf '%P\n' 2>/dev/null|
24559                       sort -u | wc -l)
24560
24561         [ $params -eq $procs ] ||
24562                 error "found $params parameters vs. $procs proc files"
24563
24564         # test the list_param -D option only returns directories
24565         params=$($LCTL list_param -R -D '*' 2>/dev/null | wc -l)
24566         #count the number of parameters by listing proc directories
24567         procs=$(find -L $proc_dirs -mindepth 1 -type d -printf '%P\n' 2>/dev/null |
24568                 sort -u | wc -l)
24569
24570         [ $params -eq $procs ] ||
24571                 error "found $params parameters vs. $procs proc files"
24572 }
24573 run_test 401a "Verify if 'lctl list_param -R' can list parameters recursively"
24574
24575 test_401b() {
24576         # jobid_var may not allow arbitrary values, so use jobid_name
24577         # if available
24578         if $LCTL list_param jobid_name > /dev/null 2>&1; then
24579                 local testname=jobid_name tmp='testing%p'
24580         else
24581                 local testname=jobid_var tmp=testing
24582         fi
24583
24584         local save=$($LCTL get_param -n $testname)
24585
24586         $LCTL set_param foo=bar $testname=$tmp bar=baz &&
24587                 error "no error returned when setting bad parameters"
24588
24589         local jobid_new=$($LCTL get_param -n foe $testname baz)
24590         [[ "$jobid_new" == "$tmp" ]] || error "jobid tmp $jobid_new != $tmp"
24591
24592         $LCTL set_param -n fog=bam $testname=$save bat=fog
24593         local jobid_old=$($LCTL get_param -n foe $testname bag)
24594         [[ "$jobid_old" == "$save" ]] || error "jobid new $jobid_old != $save"
24595 }
24596 run_test 401b "Verify 'lctl {get,set}_param' continue after error"
24597
24598 test_401c() {
24599         # jobid_var may not allow arbitrary values, so use jobid_name
24600         # if available
24601         if $LCTL list_param jobid_name > /dev/null 2>&1; then
24602                 local testname=jobid_name
24603         else
24604                 local testname=jobid_var
24605         fi
24606
24607         local jobid_var_old=$($LCTL get_param -n $testname)
24608         local jobid_var_new
24609
24610         $LCTL set_param $testname= &&
24611                 error "no error returned for 'set_param a='"
24612
24613         jobid_var_new=$($LCTL get_param -n $testname)
24614         [[ "$jobid_var_old" == "$jobid_var_new" ]] ||
24615                 error "$testname was changed by setting without value"
24616
24617         $LCTL set_param $testname &&
24618                 error "no error returned for 'set_param a'"
24619
24620         jobid_var_new=$($LCTL get_param -n $testname)
24621         [[ "$jobid_var_old" == "$jobid_var_new" ]] ||
24622                 error "$testname was changed by setting without value"
24623 }
24624 run_test 401c "Verify 'lctl set_param' without value fails in either format."
24625
24626 test_401d() {
24627         # jobid_var may not allow arbitrary values, so use jobid_name
24628         # if available
24629         if $LCTL list_param jobid_name > /dev/null 2>&1; then
24630                 local testname=jobid_name new_value='foo=bar%p'
24631         else
24632                 local testname=jobid_var new_valuie=foo=bar
24633         fi
24634
24635         local jobid_var_old=$($LCTL get_param -n $testname)
24636         local jobid_var_new
24637
24638         $LCTL set_param $testname=$new_value ||
24639                 error "'set_param a=b' did not accept a value containing '='"
24640
24641         jobid_var_new=$($LCTL get_param -n $testname)
24642         [[ "$jobid_var_new" == "$new_value" ]] ||
24643                 error "'set_param a=b' failed on a value containing '='"
24644
24645         # Reset the $testname to test the other format
24646         $LCTL set_param $testname=$jobid_var_old
24647         jobid_var_new=$($LCTL get_param -n $testname)
24648         [[ "$jobid_var_new" == "$jobid_var_old" ]] ||
24649                 error "failed to reset $testname"
24650
24651         $LCTL set_param $testname $new_value ||
24652                 error "'set_param a b' did not accept a value containing '='"
24653
24654         jobid_var_new=$($LCTL get_param -n $testname)
24655         [[ "$jobid_var_new" == "$new_value" ]] ||
24656                 error "'set_param a b' failed on a value containing '='"
24657
24658         $LCTL set_param $testname $jobid_var_old
24659         jobid_var_new=$($LCTL get_param -n $testname)
24660         [[ "$jobid_var_new" == "$jobid_var_old" ]] ||
24661                 error "failed to reset $testname"
24662 }
24663 run_test 401d "Verify 'lctl set_param' accepts values containing '='"
24664
24665 test_401e() { # LU-14779
24666         $LCTL list_param -R "ldlm.namespaces.MGC*" ||
24667                 error "lctl list_param MGC* failed"
24668         $LCTL get_param "ldlm.namespaces.MGC*" || error "lctl get_param failed"
24669         $LCTL get_param "ldlm.namespaces.MGC*.lru_size" ||
24670                 error "lctl get_param lru_size failed"
24671 }
24672 run_test 401e "verify 'lctl get_param' works with NID in parameter"
24673
24674 test_402() {
24675         [[ $MDS1_VERSION -ge $(version_code 2.7.66) ]] ||
24676         [[ $MDS1_VERSION -ge $(version_code 2.7.18.4) &&
24677                 $MDS1_VERSION -lt $(version_code 2.7.50) ]] ||
24678         [[ $MDS1_VERSION -ge $(version_code 2.7.2) &&
24679                 $MDS1_VERSION -lt $(version_code 2.7.11) ]] ||
24680                 skip "Need MDS version 2.7.2+ or 2.7.18.4+ or 2.7.66+"
24681         remote_mds_nodsh && skip "remote MDS with nodsh"
24682
24683         $LFS setdirstripe -i 0 $DIR/$tdir || error "setdirstripe -i 0 failed"
24684 #define OBD_FAIL_MDS_FLD_LOOKUP 0x15c
24685         do_facet mds1 "lctl set_param fail_loc=0x8000015c"
24686         touch $DIR/$tdir/$tfile && error "touch should fail with ENOENT" ||
24687                 echo "Touch failed - OK"
24688 }
24689 run_test 402 "Return ENOENT to lod_generate_and_set_lovea"
24690
24691 test_403() {
24692         local file1=$DIR/$tfile.1
24693         local file2=$DIR/$tfile.2
24694         local tfile=$TMP/$tfile
24695
24696         rm -f $file1 $file2 $tfile
24697
24698         touch $file1
24699         ln $file1 $file2
24700
24701         # 30 sec OBD_TIMEOUT in ll_getattr()
24702         # right before populating st_nlink
24703         $LCTL set_param fail_loc=0x80001409
24704         stat -c %h $file1 > $tfile &
24705
24706         # create an alias, drop all locks and reclaim the dentry
24707         < $file2
24708         cancel_lru_locks mdc
24709         cancel_lru_locks osc
24710         sysctl -w vm.drop_caches=2
24711
24712         wait
24713
24714         [ $(cat $tfile) -gt 0 ] || error "wrong nlink count: $(cat $tfile)"
24715
24716         rm -f $tfile $file1 $file2
24717 }
24718 run_test 403 "i_nlink should not drop to zero due to aliasing"
24719
24720 test_404() { # LU-6601
24721         [[ $MDS1_VERSION -ge $(version_code 2.8.53) ]] ||
24722                 skip "Need server version newer than 2.8.52"
24723         remote_mds_nodsh && skip "remote MDS with nodsh"
24724
24725         local mosps=$(do_facet $SINGLEMDS $LCTL dl |
24726                 awk '/osp .*-osc-MDT/ { print $4}')
24727
24728         local osp
24729         for osp in $mosps; do
24730                 echo "Deactivate: " $osp
24731                 do_facet $SINGLEMDS $LCTL --device %$osp deactivate
24732                 local stat=$(do_facet $SINGLEMDS $LCTL dl |
24733                         awk -vp=$osp '$4 == p { print $2 }')
24734                 [ $stat = IN ] || {
24735                         do_facet $SINGLEMDS $LCTL dl | grep -w $osp
24736                         error "deactivate error"
24737                 }
24738                 echo "Activate: " $osp
24739                 do_facet $SINGLEMDS $LCTL --device %$osp activate
24740                 local stat=$(do_facet $SINGLEMDS $LCTL dl |
24741                         awk -vp=$osp '$4 == p { print $2 }')
24742                 [ $stat = UP ] || {
24743                         do_facet $SINGLEMDS $LCTL dl | grep -w $osp
24744                         error "activate error"
24745                 }
24746         done
24747 }
24748 run_test 404 "validate manual {de}activated works properly for OSPs"
24749
24750 test_405() {
24751         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
24752         [ $MDS1_VERSION -lt $(version_code 2.6.92) ] ||
24753                 [ $CLIENT_VERSION -lt $(version_code 2.6.99) ] &&
24754                         skip "Layout swap lock is not supported"
24755
24756         check_swap_layouts_support
24757         check_swap_layout_no_dom $DIR
24758
24759         test_mkdir $DIR/$tdir
24760         swap_lock_test -d $DIR/$tdir ||
24761                 error "One layout swap locked test failed"
24762 }
24763 run_test 405 "Various layout swap lock tests"
24764
24765 test_406() {
24766         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
24767         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
24768         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
24769         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24770         [ $MDS1_VERSION -lt $(version_code 2.8.50) ] &&
24771                 skip "Need MDS version at least 2.8.50"
24772
24773         local def_stripe_size=$($LFS getstripe -S $MOUNT)
24774         local test_pool=$TESTNAME
24775
24776         pool_add $test_pool || error "pool_add failed"
24777         pool_add_targets $test_pool 0 $(($OSTCOUNT - 1)) 1 ||
24778                 error "pool_add_targets failed"
24779
24780         save_layout_restore_at_exit $MOUNT
24781
24782         # parent set default stripe count only, child will stripe from both
24783         # parent and fs default
24784         $LFS setstripe -c 1 -i 1 -S $((def_stripe_size * 2)) -p $test_pool $MOUNT ||
24785                 error "setstripe $MOUNT failed"
24786         $LFS mkdir -c $MDSCOUNT $DIR/$tdir || error "mkdir $tdir failed"
24787         $LFS setstripe -c $OSTCOUNT $DIR/$tdir || error "setstripe $tdir failed"
24788         for i in $(seq 10); do
24789                 local f=$DIR/$tdir/$tfile.$i
24790                 touch $f || error "touch failed"
24791                 local count=$($LFS getstripe -c $f)
24792                 [ $count -eq $OSTCOUNT ] ||
24793                         error "$f stripe count $count != $OSTCOUNT"
24794                 local offset=$($LFS getstripe -i $f)
24795                 [ $offset -eq 1 ] || error "$f stripe offset $offset != 1"
24796                 local size=$($LFS getstripe -S $f)
24797                 [ $size -eq $((def_stripe_size * 2)) ] ||
24798                         error "$f stripe size $size != $((def_stripe_size * 2))"
24799                 local pool=$($LFS getstripe -p $f)
24800                 [ $pool == $test_pool ] || error "$f pool $pool != $test_pool"
24801         done
24802
24803         # change fs default striping, delete parent default striping, now child
24804         # will stripe from new fs default striping only
24805         $LFS setstripe -c 1 -S $def_stripe_size -i 0 $MOUNT ||
24806                 error "change $MOUNT default stripe failed"
24807         $LFS setstripe -c 0 $DIR/$tdir ||
24808                 error "delete $tdir default stripe failed"
24809         for i in $(seq 11 20); do
24810                 local f=$DIR/$tdir/$tfile.$i
24811                 touch $f || error "touch $f failed"
24812                 local count=$($LFS getstripe -c $f)
24813                 [ $count -eq 1 ] || error "$f stripe count $count != 1"
24814                 local offset=$($LFS getstripe -i $f)
24815                 [ $offset -eq 0 ] || error "$f stripe offset $offset != 0"
24816                 local size=$($LFS getstripe -S $f)
24817                 [ $size -eq $def_stripe_size ] ||
24818                         error "$f stripe size $size != $def_stripe_size"
24819                 local pool=$($LFS getstripe -p $f)
24820                 [ $pool == $test_pool ] || error "$f pool $pool isn't set"
24821         done
24822
24823         unlinkmany $DIR/$tdir/$tfile. 1 20
24824
24825         local f=$DIR/$tdir/$tfile
24826         pool_remove_all_targets $test_pool $f
24827         pool_remove $test_pool $f
24828 }
24829 run_test 406 "DNE support fs default striping"
24830
24831 test_407() {
24832         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
24833         [[ $MDS1_VERSION -lt $(version_code 2.8.55) ]] &&
24834                 skip "Need MDS version at least 2.8.55"
24835         remote_mds_nodsh && skip "remote MDS with nodsh"
24836
24837         $LFS mkdir -i 0 -c 1 $DIR/$tdir.0 ||
24838                 error "$LFS mkdir -i 0 -c 1 $tdir.0 failed"
24839         $LFS mkdir -i 1 -c 1 $DIR/$tdir.1 ||
24840                 error "$LFS mkdir -i 1 -c 1 $tdir.1 failed"
24841         touch $DIR/$tdir.0/$tfile.0 || error "touch $tdir.0/$tfile.0 failed"
24842
24843         #define OBD_FAIL_DT_TXN_STOP    0x2019
24844         for idx in $(seq $MDSCOUNT); do
24845                 do_facet mds$idx "lctl set_param fail_loc=0x2019"
24846         done
24847         $LFS mkdir -c 2 $DIR/$tdir && error "$LFS mkdir -c 2 $tdir should fail"
24848         mv $DIR/$tdir.0/$tfile.0 $DIR/$tdir.1/$tfile.1 &&
24849                 error "mv $tdir.0/$tfile.0 $tdir.1/$tfile.1 should fail"
24850         true
24851 }
24852 run_test 407 "transaction fail should cause operation fail"
24853
24854 test_408() {
24855         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1 oflag=direct
24856
24857         #define OBD_FAIL_OSC_BRW_PREP_REQ2        0x40a
24858         lctl set_param fail_loc=0x8000040a
24859         # let ll_prepare_partial_page() fail
24860         dd if=/dev/zero of=$DIR/$tfile bs=2048 count=1 conv=notrunc || true
24861
24862         rm -f $DIR/$tfile
24863
24864         # create at least 100 unused inodes so that
24865         # shrink_icache_memory(0) should not return 0
24866         touch $DIR/$tfile-{0..100}
24867         rm -f $DIR/$tfile-{0..100}
24868         sync
24869
24870         echo 2 > /proc/sys/vm/drop_caches
24871 }
24872 run_test 408 "drop_caches should not hang due to page leaks"
24873
24874 test_409()
24875 {
24876         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
24877
24878         mkdir -p $DIR/$tdir || error "(0) Fail to mkdir"
24879         $LFS mkdir -i 1 -c 2 $DIR/$tdir/foo || error "(1) Fail to mkdir"
24880         touch $DIR/$tdir/guard || error "(2) Fail to create"
24881
24882         local PREFIX=$(str_repeat 'A' 128)
24883         echo "Create 1K hard links start at $(date)"
24884         createmany -l $DIR/$tdir/guard $DIR/$tdir/foo/${PREFIX}_ 1000 ||
24885                 error "(3) Fail to hard link"
24886
24887         echo "Links count should be right although linkEA overflow"
24888         stat $DIR/$tdir/guard || error "(4) Fail to stat"
24889         local linkcount=$(stat --format=%h $DIR/$tdir/guard)
24890         [ $linkcount -eq 1001 ] ||
24891                 error "(5) Unexpected hard links count: $linkcount"
24892
24893         echo "List all links start at $(date)"
24894         ls -l $DIR/$tdir/foo > /dev/null ||
24895                 error "(6) Fail to list $DIR/$tdir/foo"
24896
24897         echo "Unlink hard links start at $(date)"
24898         unlinkmany $DIR/$tdir/foo/${PREFIX}_ 1000 ||
24899                 error "(7) Fail to unlink"
24900         echo "Unlink hard links finished at $(date)"
24901 }
24902 run_test 409 "Large amount of cross-MDTs hard links on the same file"
24903
24904 test_410()
24905 {
24906         [[ $CLIENT_VERSION -lt $(version_code 2.9.59) ]] &&
24907                 skip "Need client version at least 2.9.59"
24908         [ -f $LUSTRE/tests/kernel/kinode.ko ] ||
24909                 skip "Need MODULES build"
24910
24911         # Create a file, and stat it from the kernel
24912         local testfile=$DIR/$tfile
24913         touch $testfile
24914
24915         local run_id=$RANDOM
24916         local my_ino=$(stat --format "%i" $testfile)
24917
24918         # Try to insert the module. This will always fail as the
24919         # module is designed to not be inserted.
24920         insmod $LUSTRE/tests/kernel/kinode.ko run_id=$run_id fname=$testfile \
24921             &> /dev/null
24922
24923         # Anything but success is a test failure
24924         dmesg | grep -q \
24925             "lustre_kinode_$run_id: inode numbers are identical: $my_ino" ||
24926             error "no inode match"
24927 }
24928 run_test 410 "Test inode number returned from kernel thread"
24929
24930 cleanup_test411_cgroup() {
24931         trap 0
24932         rmdir "$1"
24933 }
24934
24935 test_411() {
24936         local cg_basedir=/sys/fs/cgroup/memory
24937         # LU-9966
24938         test -f "$cg_basedir/memory.kmem.limit_in_bytes" ||
24939                 skip "no setup for cgroup"
24940
24941         dd if=/dev/zero of=$DIR/$tfile bs=1M count=100 conv=fsync ||
24942                 error "test file creation failed"
24943         cancel_lru_locks osc
24944
24945         # Create a very small memory cgroup to force a slab allocation error
24946         local cgdir=$cg_basedir/osc_slab_alloc
24947         mkdir $cgdir || error "cgroup mkdir '$cgdir' failed"
24948         trap "cleanup_test411_cgroup $cgdir" EXIT
24949         echo 2M > $cgdir/memory.kmem.limit_in_bytes
24950         echo 1M > $cgdir/memory.limit_in_bytes
24951
24952         # Should not LBUG, just be killed by oom-killer
24953         # dd will return 0 even allocation failure in some environment.
24954         # So don't check return value
24955         sh -c "echo \$$ > $cgdir/tasks && dd if=$DIR/$tfile of=/dev/null"
24956         cleanup_test411_cgroup $cgdir
24957
24958         return 0
24959 }
24960 run_test 411 "Slab allocation error with cgroup does not LBUG"
24961
24962 test_412() {
24963         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
24964         if [ $MDS1_VERSION -lt $(version_code 2.10.55) ]; then
24965                 skip "Need server version at least 2.10.55"
24966         fi
24967
24968         $LFS mkdir -i $((MDSCOUNT - 1)),$((MDSCOUNT - 2)) $DIR/$tdir ||
24969                 error "mkdir failed"
24970         $LFS getdirstripe $DIR/$tdir
24971         local stripe_index=$($LFS getdirstripe -i $DIR/$tdir)
24972         [ $stripe_index -eq $((MDSCOUNT - 1)) ] ||
24973                 error "expect $((MDSCOUT - 1)) get $stripe_index"
24974         local stripe_count=$($LFS getdirstripe -T $DIR/$tdir)
24975         [ $stripe_count -eq 2 ] ||
24976                 error "expect 2 get $stripe_count"
24977 }
24978 run_test 412 "mkdir on specific MDTs"
24979
24980 generate_uneven_mdts() {
24981         local threshold=$1
24982         local lmv_qos_maxage
24983         local lod_qos_maxage
24984         local ffree
24985         local bavail
24986         local max
24987         local min
24988         local max_index
24989         local min_index
24990         local tmp
24991         local i
24992
24993         lmv_qos_maxage=$($LCTL get_param -n lmv.*.qos_maxage)
24994         $LCTL set_param lmv.*.qos_maxage=1
24995         stack_trap "$LCTL set_param \
24996                 lmv.*.qos_maxage=$lmv_qos_maxage > /dev/null" RETURN
24997         lod_qos_maxage=$(do_facet mds1 $LCTL get_param -n \
24998                 lod.$FSNAME-MDT0000-mdtlov.qos_maxage | awk '{ print $1 }')
24999         do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param \
25000                 lod.*.mdt_qos_maxage=1
25001         stack_trap "do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param \
25002                 lod.*.mdt_qos_maxage=$lod_qos_maxage > /dev/null" RETURN
25003
25004         echo
25005         echo "Check for uneven MDTs: "
25006
25007         ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.filesfree))
25008         bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.kbytesavail))
25009         bsize=$(lctl get_param -n mdc.*MDT0000*.blocksize)
25010
25011         max=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
25012         min=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
25013         max_index=0
25014         min_index=0
25015         for ((i = 1; i < ${#ffree[@]}; i++)); do
25016                 tmp=$(((${ffree[i]} >> 8) * (${bavail[i]} * bsize >> 16)))
25017                 if [ $tmp -gt $max ]; then
25018                         max=$tmp
25019                         max_index=$i
25020                 fi
25021                 if [ $tmp -lt $min ]; then
25022                         min=$tmp
25023                         min_index=$i
25024                 fi
25025         done
25026
25027         (( ${ffree[min_index]} > 0 )) ||
25028                 skip "no free files in MDT$min_index"
25029         (( ${ffree[min_index]} < 10000000 )) ||
25030                 skip "too many free files in MDT$min_index"
25031
25032         # Check if we need to generate uneven MDTs
25033         local diff=$(((max - min) * 100 / min))
25034         local testdir=$DIR/$tdir-fillmdt
25035         local start
25036
25037         mkdir -p $testdir
25038
25039         i=0
25040         while (( diff < threshold )); do
25041                 # generate uneven MDTs, create till $threshold% diff
25042                 echo -n "weight diff=$diff% must be > $threshold% ..."
25043                 echo "Fill MDT$min_index with 1000 files: loop $i"
25044                 testdir=$DIR/$tdir-fillmdt/$i
25045                 [ -d $testdir ] || $LFS mkdir -i $min_index $testdir ||
25046                         error "mkdir $testdir failed"
25047                 $LFS setstripe -E 1M -L mdt $testdir ||
25048                         error "setstripe $testdir failed"
25049                 start=$SECONDS
25050                 for F in f.{0..999}; do
25051                         dd if=/dev/zero of=$testdir/$F bs=64K count=1 > \
25052                                 /dev/null 2>&1 || error "dd $F failed"
25053                 done
25054
25055                 # wait for QOS to update
25056                 (( SECONDS < start + 1 )) && sleep $((start + 1 - SECONDS))
25057
25058                 ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-*.filesfree))
25059                 bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-*.kbytesavail))
25060                 max=$(((${ffree[max_index]} >> 8) * \
25061                         (${bavail[max_index]} * bsize >> 16)))
25062                 min=$(((${ffree[min_index]} >> 8) * \
25063                         (${bavail[min_index]} * bsize >> 16)))
25064                 diff=$(((max - min) * 100 / min))
25065                 i=$((i + 1))
25066         done
25067
25068         echo "MDT filesfree available: ${ffree[@]}"
25069         echo "MDT blocks available: ${bavail[@]}"
25070         echo "weight diff=$diff%"
25071 }
25072
25073 test_qos_mkdir() {
25074         local mkdir_cmd=$1
25075         local stripe_count=$2
25076         local mdts=$(comma_list $(mdts_nodes))
25077
25078         local testdir
25079         local lmv_qos_prio_free
25080         local lmv_qos_threshold_rr
25081         local lmv_qos_maxage
25082         local lod_qos_prio_free
25083         local lod_qos_threshold_rr
25084         local lod_qos_maxage
25085         local count
25086         local i
25087
25088         lmv_qos_prio_free=$($LCTL get_param -n lmv.*.qos_prio_free | head -n1)
25089         lmv_qos_prio_free=${lmv_qos_prio_free%%%}
25090         lmv_qos_threshold_rr=$($LCTL get_param -n lmv.*.qos_threshold_rr |
25091                 head -n1)
25092         lmv_qos_threshold_rr=${lmv_qos_threshold_rr%%%}
25093         lmv_qos_maxage=$($LCTL get_param -n lmv.*.qos_maxage)
25094         stack_trap "$LCTL set_param \
25095                 lmv.*.qos_prio_free=$lmv_qos_prio_free > /dev/null"
25096         stack_trap "$LCTL set_param \
25097                 lmv.*.qos_threshold_rr=$lmv_qos_threshold_rr > /dev/null"
25098         stack_trap "$LCTL set_param \
25099                 lmv.*.qos_maxage=$lmv_qos_maxage > /dev/null"
25100
25101         lod_qos_prio_free=$(do_facet mds1 $LCTL get_param -n \
25102                 lod.$FSNAME-MDT0000-mdtlov.mdt_qos_prio_free | head -n1)
25103         lod_qos_prio_free=${lod_qos_prio_free%%%}
25104         lod_qos_threshold_rr=$(do_facet mds1 $LCTL get_param -n \
25105                 lod.$FSNAME-MDT0000-mdtlov.mdt_qos_threshold_rr | head -n1)
25106         lod_qos_threshold_rr=${lod_qos_threshold_rr%%%}
25107         lod_qos_maxage=$(do_facet mds1 $LCTL get_param -n \
25108                 lod.$FSNAME-MDT0000-mdtlov.qos_maxage | awk '{ print $1 }')
25109         stack_trap "do_nodes $mdts $LCTL set_param \
25110                 lod.*.mdt_qos_prio_free=$lod_qos_prio_free > /dev/null"
25111         stack_trap "do_nodes $mdts $LCTL set_param \
25112                 lod.*.mdt_qos_threshold_rr=$lod_qos_threshold_rr > /dev/null"
25113         stack_trap "do_nodes $mdts $LCTL set_param \
25114                 lod.*.mdt_qos_maxage=$lod_qos_maxage > /dev/null"
25115
25116         $LCTL set_param lmv.*.qos_threshold_rr=100 > /dev/null
25117         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_threshold_rr=100 > /dev/null
25118
25119         testdir=$DIR/$tdir-s$stripe_count/rr
25120
25121         local stripe_index=$($LFS getstripe -m $testdir)
25122         local test_mkdir_rr=true
25123
25124         getfattr -d -m dmv -e hex $testdir | grep dmv
25125         if (( $? == 0 && $MDS1_VERSION >= $(version_code 2.14.51) )); then
25126                 echo "defstripe: '$($LFS getdirstripe -D $testdir)'"
25127                 (( $($LFS getdirstripe -D --max-inherit-rr $testdir) == 0 )) &&
25128                         test_mkdir_rr=false
25129         fi
25130
25131         echo
25132         $test_mkdir_rr &&
25133                 echo "Mkdir (stripe_count $stripe_count) roundrobin:" ||
25134                 echo "Mkdir (stripe_count $stripe_count) on stripe $stripe_index"
25135
25136         stack_trap "unlinkmany -d $testdir/subdir $((100 * MDSCOUNT))"
25137         for (( i = 0; i < 100 * MDSCOUNT; i++ )); do
25138                 eval $mkdir_cmd $testdir/subdir$i ||
25139                         error "$mkdir_cmd subdir$i failed"
25140         done
25141
25142         for (( i = 0; i < $MDSCOUNT; i++ )); do
25143                 count=$($LFS getdirstripe -i $testdir/* | grep -c "^$i$")
25144                 echo "$count directories created on MDT$i"
25145                 if $test_mkdir_rr; then
25146                         (( $count == 100 )) ||
25147                                 error "subdirs are not evenly distributed"
25148                 elif (( $i == $stripe_index )); then
25149                         (( $count == 100 * MDSCOUNT )) ||
25150                                 error "$count subdirs created on MDT$i"
25151                 else
25152                         (( $count == 0 )) ||
25153                                 error "$count subdirs created on MDT$i"
25154                 fi
25155
25156                 if $test_mkdir_rr && [ $stripe_count -gt 1 ]; then
25157                         count=$($LFS getdirstripe $testdir/* |
25158                                 grep -c -P "^\s+$i\t")
25159                         echo "$count stripes created on MDT$i"
25160                         # deviation should < 5% of average
25161                         (( $count >= 95 * stripe_count &&
25162                            $count <= 105 * stripe_count)) ||
25163                                 error "stripes are not evenly distributed"
25164                 fi
25165         done
25166
25167         echo
25168         echo "Check for uneven MDTs: "
25169
25170         local ffree
25171         local bavail
25172         local max
25173         local min
25174         local max_index
25175         local min_index
25176         local tmp
25177
25178         ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.filesfree))
25179         bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.kbytesavail))
25180         bsize=$(lctl get_param -n mdc.*MDT0000*.blocksize)
25181
25182         max=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
25183         min=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
25184         max_index=0
25185         min_index=0
25186         for ((i = 1; i < ${#ffree[@]}; i++)); do
25187                 tmp=$(((${ffree[i]} >> 8) * (${bavail[i]} * bsize >> 16)))
25188                 if [ $tmp -gt $max ]; then
25189                         max=$tmp
25190                         max_index=$i
25191                 fi
25192                 if [ $tmp -lt $min ]; then
25193                         min=$tmp
25194                         min_index=$i
25195                 fi
25196         done
25197
25198         (( ${ffree[min_index]} > 0 )) ||
25199                 skip "no free files in MDT$min_index"
25200         (( ${ffree[min_index]} < 10000000 )) ||
25201                 skip "too many free files in MDT$min_index"
25202
25203         echo "MDT filesfree available: ${ffree[@]}"
25204         echo "MDT blocks available: ${bavail[@]}"
25205         echo "weight diff=$(((max - min) * 100 / min))%"
25206         echo
25207         echo "Mkdir (stripe_count $stripe_count) with balanced space usage:"
25208
25209         $LCTL set_param lmv.*.qos_threshold_rr=0 > /dev/null
25210         $LCTL set_param lmv.*.qos_prio_free=100 > /dev/null
25211         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_threshold_rr=0 > /dev/null
25212         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_prio_free=100 > /dev/null
25213         # decrease statfs age, so that it can be updated in time
25214         $LCTL set_param lmv.*.qos_maxage=1 > /dev/null
25215         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_maxage=1 > /dev/null
25216
25217         sleep 1
25218
25219         testdir=$DIR/$tdir-s$stripe_count/qos
25220         local num=200
25221
25222         stack_trap "unlinkmany -d $testdir/subdir $((num * MDSCOUNT))"
25223         for (( i = 0; i < num * MDSCOUNT; i++ )); do
25224                 eval $mkdir_cmd $testdir/subdir$i ||
25225                         error "$mkdir_cmd subdir$i failed"
25226         done
25227
25228         max=0
25229         for (( i = 0; i < $MDSCOUNT; i++ )); do
25230                 count=$($LFS getdirstripe -i $testdir/* | grep -c "^$i$")
25231                 (( count > max )) && max=$count
25232                 echo "$count directories created on MDT$i"
25233         done
25234
25235         min=$($LFS getdirstripe -i $testdir/* | grep -c "^$min_index$")
25236
25237         # D-value should > 10% of averge
25238         (( max - min > num / 10 )) ||
25239                 error "subdirs shouldn't be evenly distributed: $max - $min < $((num / 10))"
25240
25241         # ditto for stripes
25242         if (( stripe_count > 1 )); then
25243                 max=0
25244                 for (( i = 0; i < $MDSCOUNT; i++ )); do
25245                         count=$($LFS getdirstripe $testdir/* |
25246                                 grep -c -P "^\s+$i\t")
25247                         (( count > max )) && max=$count
25248                         echo "$count stripes created on MDT$i"
25249                 done
25250
25251                 min=$($LFS getdirstripe $testdir/* |
25252                         grep -c -P "^\s+$min_index\t")
25253                 (( max - min > num * stripe_count / 10 )) ||
25254                         error "stripes shouldn't be evenly distributed: $max - $min < $((num / 10)) * $stripe_count"
25255         fi
25256 }
25257
25258 most_full_mdt() {
25259         local ffree
25260         local bavail
25261         local bsize
25262         local min
25263         local min_index
25264         local tmp
25265
25266         ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.filesfree))
25267         bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.kbytesavail))
25268         bsize=$(lctl get_param -n mdc.*MDT0000*.blocksize)
25269
25270         min=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
25271         min_index=0
25272         for ((i = 1; i < ${#ffree[@]}; i++)); do
25273                 tmp=$(((${ffree[i]} >> 8) * (${bavail[i]} * bsize >> 16)))
25274                 (( tmp < min )) && min=$tmp && min_index=$i
25275         done
25276
25277         echo -n $min_index
25278 }
25279
25280 test_413a() {
25281         [ $MDSCOUNT -lt 2 ] &&
25282                 skip "We need at least 2 MDTs for this test"
25283
25284         [ $MDS1_VERSION -lt $(version_code 2.12.52) ] &&
25285                 skip "Need server version at least 2.12.52"
25286
25287         local stripe_count
25288
25289         generate_uneven_mdts 100
25290         for stripe_count in $(seq 1 $((MDSCOUNT - 1))); do
25291                 mkdir $DIR/$tdir-s$stripe_count || error "mkdir failed"
25292                 mkdir $DIR/$tdir-s$stripe_count/rr || error "mkdir failed"
25293                 $LFS mkdir -i $(most_full_mdt) $DIR/$tdir-s$stripe_count/qos ||
25294                         error "mkdir failed"
25295                 test_qos_mkdir "$LFS mkdir -i -1 -c $stripe_count" $stripe_count
25296         done
25297 }
25298 run_test 413a "QoS mkdir with 'lfs mkdir -i -1'"
25299
25300 test_413b() {
25301         [ $MDSCOUNT -lt 2 ] &&
25302                 skip "We need at least 2 MDTs for this test"
25303
25304         [ $MDS1_VERSION -lt $(version_code 2.12.52) ] &&
25305                 skip "Need server version at least 2.12.52"
25306
25307         local testdir
25308         local stripe_count
25309
25310         generate_uneven_mdts 100
25311         for stripe_count in $(seq 1 $((MDSCOUNT - 1))); do
25312                 testdir=$DIR/$tdir-s$stripe_count
25313                 mkdir $testdir || error "mkdir $testdir failed"
25314                 mkdir $testdir/rr || error "mkdir rr failed"
25315                 $LFS mkdir -i $(most_full_mdt) $testdir/qos ||
25316                         error "mkdir qos failed"
25317                 $LFS setdirstripe -D -c $stripe_count --max-inherit-rr 2 \
25318                         $testdir/rr || error "setdirstripe rr failed"
25319                 $LFS setdirstripe -D -c $stripe_count $testdir/qos ||
25320                         error "setdirstripe failed"
25321                 test_qos_mkdir "mkdir" $stripe_count
25322         done
25323 }
25324 run_test 413b "QoS mkdir under dir whose default LMV starting MDT offset is -1"
25325
25326 test_413c() {
25327         (( $MDSCOUNT >= 2 )) ||
25328                 skip "We need at least 2 MDTs for this test"
25329
25330         (( $MDS1_VERSION >= $(version_code 2.14.51) )) ||
25331                 skip "Need server version at least 2.14.51"
25332
25333         local testdir
25334         local inherit
25335         local inherit_rr
25336
25337         testdir=$DIR/${tdir}-s1
25338         mkdir $testdir || error "mkdir $testdir failed"
25339         mkdir $testdir/rr || error "mkdir rr failed"
25340         $LFS mkdir -i $(most_full_mdt) $testdir/qos || error "mkdir qos failed"
25341         # default max_inherit is -1, default max_inherit_rr is 0
25342         $LFS setdirstripe -D -c 1 $testdir/rr ||
25343                 error "setdirstripe rr failed"
25344         $LFS setdirstripe -D -c 1 -i -1 -X 2 --max-inherit-rr 1 $testdir/qos ||
25345                 error "setdirstripe qos failed"
25346         test_qos_mkdir "mkdir" 1
25347
25348         mkdir $testdir/rr/level1 || error "mkdir rr/level1 failed"
25349         inherit=$($LFS getdirstripe -D -X $testdir/rr/level1)
25350         (( $inherit == -1 )) || error "rr/level1 inherit $inherit != -1"
25351         inherit_rr=$($LFS getdirstripe -D --max-inherit-rr $testdir/rr/level1)
25352         (( $inherit_rr == 0 )) || error "rr/level1 inherit-rr $inherit_rr != 0"
25353
25354         mkdir $testdir/qos/level1 || error "mkdir qos/level1 failed"
25355         inherit=$($LFS getdirstripe -D -X $testdir/qos/level1)
25356         (( $inherit == 1 )) || error "qos/level1 inherit $inherit != 1"
25357         inherit_rr=$($LFS getdirstripe -D --max-inherit-rr $testdir/qos/level1)
25358         (( $inherit_rr == 0 )) || error "qos/level1 inherit-rr $inherit_rr != 0"
25359         mkdir $testdir/qos/level1/level2 || error "mkdir level2 failed"
25360         getfattr -d -m dmv -e hex $testdir/qos/level1/level2 | grep dmv &&
25361                 error "level2 shouldn't have default LMV" || true
25362 }
25363 run_test 413c "mkdir with default LMV max inherit rr"
25364
25365 test_413d() {
25366         (( MDSCOUNT >= 2 )) ||
25367                 skip "We need at least 2 MDTs for this test"
25368
25369         (( MDS1_VERSION >= $(version_code 2.14.51) )) ||
25370                 skip "Need server version at least 2.14.51"
25371
25372         local lmv_qos_threshold_rr
25373
25374         lmv_qos_threshold_rr=$($LCTL get_param -n lmv.*.qos_threshold_rr |
25375                 head -n1)
25376         stack_trap "$LCTL set_param \
25377                 lmv.*.qos_threshold_rr=$lmv_qos_threshold_rr > /dev/null" EXIT
25378
25379         $LCTL set_param lmv.*.qos_threshold_rr=100 > /dev/null
25380         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
25381         getfattr -d -m dmv -e hex $DIR/$tdir | grep dmv &&
25382                 error "$tdir shouldn't have default LMV"
25383         createmany -d $DIR/$tdir/sub $((100 * MDSCOUNT)) ||
25384                 error "mkdir sub failed"
25385
25386         local count=$($LFS getstripe -m $DIR/$tdir/* | grep -c ^0)
25387
25388         (( count == 100 )) || error "$count subdirs on MDT0"
25389 }
25390 run_test 413d "inherit ROOT default LMV"
25391
25392 test_413z() {
25393         local pids=""
25394         local subdir
25395         local pid
25396
25397         for subdir in $(\ls -1 -d $DIR/d413*-fillmdt/*); do
25398                 unlinkmany $subdir/f. 1000 &
25399                 pids="$pids $!"
25400         done
25401
25402         for pid in $pids; do
25403                 wait $pid
25404         done
25405 }
25406 run_test 413z "413 test cleanup"
25407
25408 test_414() {
25409 #define OBD_FAIL_PTLRPC_BULK_ATTACH      0x521
25410         $LCTL set_param fail_loc=0x80000521
25411         dd if=/dev/zero of=$DIR/$tfile bs=2M count=1 oflag=sync
25412         rm -f $DIR/$tfile
25413 }
25414 run_test 414 "simulate ENOMEM in ptlrpc_register_bulk()"
25415
25416 test_415() {
25417         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25418         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
25419                 skip "Need server version at least 2.11.52"
25420
25421         # LU-11102
25422         local total
25423         local setattr_pid
25424         local start_time
25425         local end_time
25426         local duration
25427
25428         total=500
25429         # this test may be slow on ZFS
25430         [ "$mds1_FSTYPE" == "zfs" ] && total=100
25431
25432         # though this test is designed for striped directory, let's test normal
25433         # directory too since lock is always saved as CoS lock.
25434         test_mkdir $DIR/$tdir || error "mkdir $tdir"
25435         createmany -o $DIR/$tdir/$tfile. $total || error "createmany"
25436
25437         (
25438                 while true; do
25439                         touch $DIR/$tdir
25440                 done
25441         ) &
25442         setattr_pid=$!
25443
25444         start_time=$(date +%s)
25445         for i in $(seq $total); do
25446                 mrename $DIR/$tdir/$tfile.$i $DIR/$tdir/$tfile-new.$i \
25447                         > /dev/null
25448         done
25449         end_time=$(date +%s)
25450         duration=$((end_time - start_time))
25451
25452         kill -9 $setattr_pid
25453
25454         echo "rename $total files took $duration sec"
25455         [ $duration -lt 100 ] || error "rename took $duration sec"
25456 }
25457 run_test 415 "lock revoke is not missing"
25458
25459 test_416() {
25460         [ $MDS1_VERSION -lt $(version_code 2.11.55) ] &&
25461                 skip "Need server version at least 2.11.55"
25462
25463         # define OBD_FAIL_OSD_TXN_START    0x19a
25464         do_facet mds1 lctl set_param fail_loc=0x19a
25465
25466         lfs mkdir -c $MDSCOUNT $DIR/$tdir
25467
25468         true
25469 }
25470 run_test 416 "transaction start failure won't cause system hung"
25471
25472 cleanup_417() {
25473         trap 0
25474         do_nodes $(comma_list $(mdts_nodes)) \
25475                 "$LCTL set_param -n mdt.*MDT*.enable_dir_migration=1"
25476         do_nodes $(comma_list $(mdts_nodes)) \
25477                 "$LCTL set_param -n mdt.*MDT*.enable_remote_dir=1"
25478         do_nodes $(comma_list $(mdts_nodes)) \
25479                 "$LCTL set_param -n mdt.*MDT*.enable_striped_dir=1"
25480 }
25481
25482 test_417() {
25483         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
25484         [[ $MDS1_VERSION -lt $(version_code 2.11.56) ]] &&
25485                 skip "Need MDS version at least 2.11.56"
25486
25487         trap cleanup_417 RETURN EXIT
25488
25489         $LFS mkdir -i 1 $DIR/$tdir.1 || error "create remote dir $tdir.1 failed"
25490         do_nodes $(comma_list $(mdts_nodes)) \
25491                 "$LCTL set_param -n mdt.*MDT*.enable_dir_migration=0"
25492         $LFS migrate -m 0 $DIR/$tdir.1 &&
25493                 error "migrate dir $tdir.1 should fail"
25494
25495         do_nodes $(comma_list $(mdts_nodes)) \
25496                 "$LCTL set_param -n mdt.*MDT*.enable_remote_dir=0"
25497         $LFS mkdir -i 1 $DIR/$tdir.2 &&
25498                 error "create remote dir $tdir.2 should fail"
25499
25500         do_nodes $(comma_list $(mdts_nodes)) \
25501                 "$LCTL set_param -n mdt.*MDT*.enable_striped_dir=0"
25502         $LFS mkdir -c 2 $DIR/$tdir.3 &&
25503                 error "create striped dir $tdir.3 should fail"
25504         true
25505 }
25506 run_test 417 "disable remote dir, striped dir and dir migration"
25507
25508 # Checks that the outputs of df [-i] and lfs df [-i] match
25509 #
25510 # usage: check_lfs_df <blocks | inodes> <mountpoint>
25511 check_lfs_df() {
25512         local dir=$2
25513         local inodes
25514         local df_out
25515         local lfs_df_out
25516         local count
25517         local passed=false
25518
25519         # blocks or inodes
25520         [ "$1" == "blocks" ] && inodes= || inodes="-i"
25521
25522         for count in {1..100}; do
25523                 do_nodes "$CLIENTS" \
25524                         $LCTL set_param ldlm.namespaces.*.lru_size=clear
25525                 sync; sleep 0.2
25526
25527                 # read the lines of interest
25528                 df_out=($(df -P $inodes $dir | tail -n +2)) ||
25529                         error "df $inodes $dir | tail -n +2 failed"
25530                 lfs_df_out=($($LFS df $inodes $dir | grep summary:)) ||
25531                         error "lfs df $inodes $dir | grep summary: failed"
25532
25533                 # skip first substrings of each output as they are different
25534                 # "<NID>:/<fsname>" for df, "filesystem_summary:" for lfs df
25535                 # compare the two outputs
25536                 passed=true
25537                 #  skip "available" on MDT until LU-13997 is fixed.
25538                 #for i in {1..5}; do
25539                 for i in 1 2 4 5; do
25540                         [ "${df_out[i]}" != "${lfs_df_out[i]}" ] && passed=false
25541                 done
25542                 $passed && break
25543         done
25544
25545         if ! $passed; then
25546                 df -P $inodes $dir
25547                 echo
25548                 lfs df $inodes $dir
25549                 error "df and lfs df $1 output mismatch: "      \
25550                       "df ${inodes}: ${df_out[*]}, "            \
25551                       "lfs df ${inodes}: ${lfs_df_out[*]}"
25552         fi
25553 }
25554
25555 test_418() {
25556         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25557
25558         local dir=$DIR/$tdir
25559         local numfiles=$((RANDOM % 4096 + 2))
25560         local numblocks=$((RANDOM % 256 + 1))
25561
25562         wait_delete_completed
25563         test_mkdir $dir
25564
25565         # check block output
25566         check_lfs_df blocks $dir
25567         # check inode output
25568         check_lfs_df inodes $dir
25569
25570         # create a single file and retest
25571         echo "Creating a single file and testing"
25572         createmany -o $dir/$tfile- 1 &>/dev/null ||
25573                 error "creating 1 file in $dir failed"
25574         check_lfs_df blocks $dir
25575         check_lfs_df inodes $dir
25576
25577         # create a random number of files
25578         echo "Creating $((numfiles - 1)) files and testing"
25579         createmany -o $dir/$tfile- 1 $((numfiles - 1)) &>/dev/null ||
25580                 error "creating $((numfiles - 1)) files in $dir failed"
25581
25582         # write a random number of blocks to the first test file
25583         echo "Writing $numblocks 4K blocks and testing"
25584         dd if=/dev/urandom of=$dir/${tfile}-0 bs=4K conv=fsync \
25585                 count=$numblocks &>/dev/null ||
25586                 error "dd to $dir/${tfile}-0 failed"
25587
25588         # retest
25589         check_lfs_df blocks $dir
25590         check_lfs_df inodes $dir
25591
25592         unlinkmany $dir/$tfile- $numfiles &>/dev/null ||
25593                 error "unlinking $numfiles files in $dir failed"
25594 }
25595 run_test 418 "df and lfs df outputs match"
25596
25597 test_419()
25598 {
25599         local dir=$DIR/$tdir
25600
25601         mkdir -p $dir
25602         touch $dir/file
25603
25604         cancel_lru_locks mdc
25605
25606         #OBD_FAIL_LLITE_OPEN_BY_NAME    0x1410
25607         $LCTL set_param fail_loc=0x1410
25608         cat $dir/file
25609         $LCTL set_param fail_loc=0
25610         rm -rf $dir
25611 }
25612 run_test 419 "Verify open file by name doesn't crash kernel"
25613
25614 test_420()
25615 {
25616         [[ $MDS1_VERSION -ge $(version_code 2.12.53) ]] ||
25617                 skip "Need MDS version at least 2.12.53"
25618
25619         local SAVE_UMASK=$(umask)
25620         local dir=$DIR/$tdir
25621         local uname=$(getent passwd $RUNAS_ID | cut -d: -f1)
25622
25623         mkdir -p $dir
25624         umask 0000
25625         mkdir -m03777 $dir/testdir
25626         ls -dn $dir/testdir
25627         # Need to remove trailing '.' when SELinux is enabled
25628         local dirperms=$(ls -dn $dir/testdir |
25629                          awk '{ sub(/\.$/, "", $1); print $1}')
25630         [ $dirperms == "drwxrwsrwt" ] ||
25631                 error "incorrect perms on $dir/testdir"
25632
25633         su - $uname -c "PATH=$LUSTRE/tests:\$PATH; \
25634                 openfile -f O_RDONLY:O_CREAT -m 02755 $dir/testdir/testfile"
25635         ls -n $dir/testdir/testfile
25636         local fileperms=$(ls -n $dir/testdir/testfile |
25637                           awk '{ sub(/\.$/, "", $1); print $1}')
25638         [ $fileperms == "-rwxr-xr-x" ] ||
25639                 error "incorrect perms on $dir/testdir/testfile"
25640
25641         umask $SAVE_UMASK
25642 }
25643 run_test 420 "clear SGID bit on non-directories for non-members"
25644
25645 test_421a() {
25646         local cnt
25647         local fid1
25648         local fid2
25649
25650         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
25651                 skip "Need MDS version at least 2.12.54"
25652
25653         test_mkdir $DIR/$tdir
25654         createmany -o $DIR/$tdir/f 3
25655         cnt=$(ls -1 $DIR/$tdir | wc -l)
25656         [ $cnt != 3 ] && error "unexpected #files: $cnt"
25657
25658         fid1=$(lfs path2fid $DIR/$tdir/f1)
25659         fid2=$(lfs path2fid $DIR/$tdir/f2)
25660         $LFS rmfid $DIR $fid1 $fid2 || error "rmfid failed"
25661
25662         stat $DIR/$tdir/f1 && error "f1 still visible on the client"
25663         stat $DIR/$tdir/f2 && error "f2 still visible on the client"
25664
25665         cnt=$(ls -1 $DIR/$tdir | wc -l)
25666         [ $cnt == 1 ] || error "unexpected #files after: $cnt"
25667
25668         rm -f $DIR/$tdir/f3 || error "can't remove f3"
25669         createmany -o $DIR/$tdir/f 3
25670         cnt=$(ls -1 $DIR/$tdir | wc -l)
25671         [ $cnt != 3 ] && error "unexpected #files: $cnt"
25672
25673         fid1=$(lfs path2fid $DIR/$tdir/f1)
25674         fid2=$(lfs path2fid $DIR/$tdir/f2)
25675         echo "remove using fsname $FSNAME"
25676         $LFS rmfid $FSNAME $fid1 $fid2 || error "rmfid with fsname failed"
25677
25678         cnt=$(ls -1 $DIR/$tdir | wc -l)
25679         [ $cnt == 1 ] || error "unexpected #files after: $cnt"
25680 }
25681 run_test 421a "simple rm by fid"
25682
25683 test_421b() {
25684         local cnt
25685         local FID1
25686         local FID2
25687
25688         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
25689                 skip "Need MDS version at least 2.12.54"
25690
25691         test_mkdir $DIR/$tdir
25692         createmany -o $DIR/$tdir/f 3
25693         multiop_bg_pause $DIR/$tdir/f1 o_c || error "multiop failed to start"
25694         MULTIPID=$!
25695
25696         FID1=$(lfs path2fid $DIR/$tdir/f1)
25697         FID2=$(lfs path2fid $DIR/$tdir/f2)
25698         $LFS rmfid $DIR $FID1 $FID2 && error "rmfid didn't fail"
25699
25700         kill -USR1 $MULTIPID
25701         wait
25702
25703         cnt=$(ls $DIR/$tdir | wc -l)
25704         [ $cnt == 2 ] || error "unexpected #files after: $cnt"
25705 }
25706 run_test 421b "rm by fid on open file"
25707
25708 test_421c() {
25709         local cnt
25710         local FIDS
25711
25712         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
25713                 skip "Need MDS version at least 2.12.54"
25714
25715         test_mkdir $DIR/$tdir
25716         createmany -o $DIR/$tdir/f 3
25717         touch $DIR/$tdir/$tfile
25718         createmany -l$DIR/$tdir/$tfile $DIR/$tdir/h 180
25719         cnt=$(ls -1 $DIR/$tdir | wc -l)
25720         [ $cnt != 184 ] && error "unexpected #files: $cnt"
25721
25722         FID1=$(lfs path2fid $DIR/$tdir/$tfile)
25723         $LFS rmfid $DIR $FID1 || error "rmfid failed"
25724
25725         cnt=$(ls $DIR/$tdir | wc -l)
25726         [ $cnt == 3 ] || error "unexpected #files after: $cnt"
25727 }
25728 run_test 421c "rm by fid against hardlinked files"
25729
25730 test_421d() {
25731         local cnt
25732         local FIDS
25733
25734         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
25735                 skip "Need MDS version at least 2.12.54"
25736
25737         test_mkdir $DIR/$tdir
25738         createmany -o $DIR/$tdir/f 4097
25739         cnt=$(ls -1 $DIR/$tdir | wc -l)
25740         [ $cnt != 4097 ] && error "unexpected #files: $cnt"
25741
25742         FIDS=$(lfs path2fid $DIR/$tdir/f* | sed "s/[/][^:]*://g")
25743         $LFS rmfid $DIR $FIDS || error "rmfid failed"
25744
25745         cnt=$(ls $DIR/$tdir | wc -l)
25746         rm -rf $DIR/$tdir
25747         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
25748 }
25749 run_test 421d "rmfid en masse"
25750
25751 test_421e() {
25752         local cnt
25753         local FID
25754
25755         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
25756         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
25757                 skip "Need MDS version at least 2.12.54"
25758
25759         mkdir -p $DIR/$tdir
25760         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
25761         createmany -o $DIR/$tdir/striped_dir/f 512
25762         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
25763         [ $cnt != 512 ] && error "unexpected #files: $cnt"
25764
25765         FIDS=$(lfs path2fid $DIR/$tdir/striped_dir/f* |
25766                 sed "s/[/][^:]*://g")
25767         $LFS rmfid $DIR $FIDS || error "rmfid failed"
25768
25769         cnt=$(ls $DIR/$tdir/striped_dir | wc -l)
25770         rm -rf $DIR/$tdir
25771         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
25772 }
25773 run_test 421e "rmfid in DNE"
25774
25775 test_421f() {
25776         local cnt
25777         local FID
25778
25779         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
25780                 skip "Need MDS version at least 2.12.54"
25781
25782         test_mkdir $DIR/$tdir
25783         touch $DIR/$tdir/f
25784         cnt=$(ls -1 $DIR/$tdir | wc -l)
25785         [ $cnt != 1 ] && error "unexpected #files: $cnt"
25786
25787         FID=$(lfs path2fid $DIR/$tdir/f)
25788         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail (1)"
25789         # rmfid should fail
25790         cnt=$(ls -1 $DIR/$tdir | wc -l)
25791         [ $cnt != 1 ] && error "unexpected #files after (2): $cnt"
25792
25793         chmod a+rw $DIR/$tdir
25794         ls -la $DIR/$tdir
25795         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail (2)"
25796         # rmfid should fail
25797         cnt=$(ls -1 $DIR/$tdir | wc -l)
25798         [ $cnt != 1 ] && error "unexpected #files after (3): $cnt"
25799
25800         rm -f $DIR/$tdir/f
25801         $RUNAS touch $DIR/$tdir/f
25802         FID=$(lfs path2fid $DIR/$tdir/f)
25803         echo "rmfid as root"
25804         $LFS rmfid $DIR $FID || error "rmfid as root failed"
25805         cnt=$(ls -1 $DIR/$tdir | wc -l)
25806         [ $cnt == 0 ] || error "unexpected #files after (4): $cnt"
25807
25808         rm -f $DIR/$tdir/f
25809         $RUNAS touch $DIR/$tdir/f
25810         cnt=$(ls -1 $DIR/$tdir | wc -l)
25811         [ $cnt != 1 ] && error "unexpected #files (4): $cnt"
25812         FID=$(lfs path2fid $DIR/$tdir/f)
25813         # rmfid w/o user_fid2path mount option should fail
25814         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail(3)"
25815         cnt=$(ls -1 $DIR/$tdir | wc -l)
25816         [ $cnt == 1 ] || error "unexpected #files after (5): $cnt"
25817
25818         tmpdir=$(mktemp -d /tmp/lustre-XXXXXX)
25819         stack_trap "rmdir $tmpdir"
25820         mount_client $tmpdir "$MOUNT_OPTS,user_fid2path" ||
25821                 error "failed to mount client'"
25822         stack_trap "umount_client $tmpdir"
25823
25824         $RUNAS $LFS rmfid $tmpdir $FID || error "rmfid failed"
25825         # rmfid should succeed
25826         cnt=$(ls -1 $tmpdir/$tdir | wc -l)
25827         [ $cnt == 0 ] || error "unexpected #files after (6): $cnt"
25828
25829         # rmfid shouldn't allow to remove files due to dir's permission
25830         chmod a+rwx $tmpdir/$tdir
25831         touch $tmpdir/$tdir/f
25832         ls -la $tmpdir/$tdir
25833         FID=$(lfs path2fid $tmpdir/$tdir/f)
25834         $RUNAS $LFS rmfid $tmpdir $FID && error "rmfid didn't fail"
25835         return 0
25836 }
25837 run_test 421f "rmfid checks permissions"
25838
25839 test_421g() {
25840         local cnt
25841         local FIDS
25842
25843         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
25844         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
25845                 skip "Need MDS version at least 2.12.54"
25846
25847         mkdir -p $DIR/$tdir
25848         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
25849         createmany -o $DIR/$tdir/striped_dir/f 512
25850         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
25851         [ $cnt != 512 ] && error "unexpected #files: $cnt"
25852
25853         FIDS=$(lfs path2fid $DIR/$tdir/striped_dir/f* |
25854                 sed "s/[/][^:]*://g")
25855
25856         rm -f $DIR/$tdir/striped_dir/f1*
25857         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
25858         removed=$((512 - cnt))
25859
25860         # few files have been just removed, so we expect
25861         # rmfid to fail on their fids
25862         errors=$($LFS rmfid $DIR $FIDS 2>&1 | wc -l)
25863         [ $removed != $errors ] && error "$errors != $removed"
25864
25865         cnt=$(ls $DIR/$tdir/striped_dir | wc -l)
25866         rm -rf $DIR/$tdir
25867         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
25868 }
25869 run_test 421g "rmfid to return errors properly"
25870
25871 test_422() {
25872         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d1
25873         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d2
25874         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d3
25875         dd if=/dev/zero of=$DIR/$tdir/d1/file1 bs=1k count=1
25876         dd if=/dev/zero of=$DIR/$tdir/d2/file1 bs=1k count=1
25877
25878         local amc=$(at_max_get client)
25879         local amo=$(at_max_get mds1)
25880         local timeout=`lctl get_param -n timeout`
25881
25882         at_max_set 0 client
25883         at_max_set 0 mds1
25884
25885 #define OBD_FAIL_PTLRPC_PAUSE_REQ        0x50a
25886         do_facet mds1 $LCTL set_param fail_loc=0x8000050a \
25887                         fail_val=$(((2*timeout + 10)*1000))
25888         touch $DIR/$tdir/d3/file &
25889         sleep 2
25890 #define OBD_FAIL_TGT_REPLY_DATA_RACE     0x722
25891         do_facet mds1 $LCTL set_param fail_loc=0x80000722 \
25892                         fail_val=$((2*timeout + 5))
25893         mv $DIR/$tdir/d1/file1 $DIR/$tdir/d1/file2 &
25894         local pid=$!
25895         sleep 1
25896         kill -9 $pid
25897         sleep $((2 * timeout))
25898         echo kill $pid
25899         kill -9 $pid
25900         lctl mark touch
25901         touch $DIR/$tdir/d2/file3
25902         touch $DIR/$tdir/d2/file4
25903         touch $DIR/$tdir/d2/file5
25904
25905         wait
25906         at_max_set $amc client
25907         at_max_set $amo mds1
25908
25909         # LU-12838 - verify the ptlrpc thread watchdog is not always throttled
25910         do_facet mds1 "dmesg | grep 'Dumping the stack trace for debugging'" ||
25911                 error "Watchdog is always throttled"
25912 }
25913 run_test 422 "kill a process with RPC in progress"
25914
25915 stat_test() {
25916     df -h $MOUNT &
25917     df -h $MOUNT &
25918     df -h $MOUNT &
25919     df -h $MOUNT &
25920     df -h $MOUNT &
25921     df -h $MOUNT &
25922 }
25923
25924 test_423() {
25925     local _stats
25926     # ensure statfs cache is expired
25927     sleep 2;
25928
25929     _stats=$(stat_test | grep $MOUNT | sort -u | wc -l)
25930     [[ ${_stats} -ne 1 ]] && error "statfs wrong"
25931
25932     return 0
25933 }
25934 run_test 423 "statfs should return a right data"
25935
25936 test_424() {
25937 #define OBD_FAIL_PTLRPC_BULK_REPLY_ATTACH      0x522 | OBD_FAIL_ONCE
25938         $LCTL set_param fail_loc=0x80000522
25939         dd if=/dev/zero of=$DIR/$tfile bs=2M count=1 oflag=sync
25940         rm -f $DIR/$tfile
25941 }
25942 run_test 424 "simulate ENOMEM in ptl_send_rpc bulk reply ME attach"
25943
25944 test_425() {
25945         test_mkdir -c -1 $DIR/$tdir
25946         $LFS setstripe -c -1 $DIR/$tdir
25947
25948         lru_resize_disable "" 100
25949         stack_trap "lru_resize_enable" EXIT
25950
25951         sleep 5
25952
25953         for i in $(seq $((MDSCOUNT * 125))); do
25954                 local t=$DIR/$tdir/$tfile_$i
25955
25956                 dd if=/dev/zero of=$t bs=4K count=1 > /dev/null 2>&1 ||
25957                         error_noexit "Create file $t"
25958         done
25959         stack_trap "rm -rf $DIR/$tdir" EXIT
25960
25961         for oscparam in $($LCTL list_param ldlm.namespaces.*osc-[-0-9a-f]*); do
25962                 local lru_size=$($LCTL get_param -n $oscparam.lru_size)
25963                 local lock_count=$($LCTL get_param -n $oscparam.lock_count)
25964
25965                 [ $lock_count -le $lru_size ] ||
25966                         error "osc lock count $lock_count > lru size $lru_size"
25967         done
25968
25969         for mdcparam in $($LCTL list_param ldlm.namespaces.*mdc-*); do
25970                 local lru_size=$($LCTL get_param -n $mdcparam.lru_size)
25971                 local lock_count=$($LCTL get_param -n $mdcparam.lock_count)
25972
25973                 [ $lock_count -le $lru_size ] ||
25974                         error "mdc lock count $lock_count > lru size $lru_size"
25975         done
25976 }
25977 run_test 425 "lock count should not exceed lru size"
25978
25979 test_426() {
25980         splice-test -r $DIR/$tfile
25981         splice-test -rd $DIR/$tfile
25982         splice-test $DIR/$tfile
25983         splice-test -d $DIR/$tfile
25984 }
25985 run_test 426 "splice test on Lustre"
25986
25987 test_427() {
25988         [ $MDSCOUNT -ge 2 ] || skip "needs >= 2 MDTs"
25989         (( $MDS1_VERSION >= $(version_code 2.12.4) )) ||
25990                 skip "Need MDS version at least 2.12.4"
25991         local log
25992
25993         mkdir $DIR/$tdir
25994         mkdir $DIR/$tdir/1
25995         mkdir $DIR/$tdir/2
25996         test_mkdir -c $MDSCOUNT -i 1 $DIR/$tdir/1/dir
25997         test_mkdir -c $MDSCOUNT -i 1 $DIR/$tdir/2/dir2
25998
25999         $LFS getdirstripe $DIR/$tdir/1/dir
26000
26001         #first setfattr for creating updatelog
26002         setfattr -n user.attr0 -v "some text" $DIR/$tdir/1/dir
26003
26004 #define OBD_FAIL_OUT_OBJECT_MISS        0x1708
26005         do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param fail_loc=0x80001708
26006         setfattr -n user.attr1 -v "some text" $DIR/$tdir/1/dir &
26007         setfattr -n user.attr2 -v "another attr"  $DIR/$tdir/2/dir2 &
26008
26009         sleep 2
26010         fail mds2
26011         wait_recovery_complete mds2 $((2*TIMEOUT))
26012
26013         log=$(do_facet mds1 dmesg | tac | sed "/${TESTNAME//_/ }/,$ d")
26014         echo $log | grep "get update log failed" &&
26015                 error "update log corruption is detected" || true
26016 }
26017 run_test 427 "Failed DNE2 update request shouldn't corrupt updatelog"
26018
26019 test_428() {
26020         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26021         local cache_limit=$CACHE_MAX
26022
26023         stack_trap "$LCTL set_param -n llite.*.max_cached_mb=$cache_limit"
26024         $LCTL set_param -n llite.*.max_cached_mb=64
26025
26026         mkdir $DIR/$tdir
26027         $LFS setstripe -c 1 $DIR/$tdir
26028         eval touch $DIR/$tdir/$tfile.{1..$OSTCOUNT}
26029         stack_trap "rm -f $DIR/$tdir/$tfile.*"
26030         #test write
26031         for f in $(seq 4); do
26032                 dd if=/dev/zero of=$DIR/$tdir/$tfile.$f bs=128M count=1 &
26033         done
26034         wait
26035
26036         cancel_lru_locks osc
26037         # Test read
26038         for f in $(seq 4); do
26039                 dd if=$DIR/$tdir/$tfile.$f of=/dev/null bs=128M count=1 &
26040         done
26041         wait
26042 }
26043 run_test 428 "large block size IO should not hang"
26044
26045 test_429() { # LU-7915 / LU-10948
26046         local ll_opencache_threshold_count="llite.*.opencache_threshold_count"
26047         local testfile=$DIR/$tfile
26048         local mdc_rpcstats="mdc.$FSNAME-MDT0000-*.stats"
26049         local new_flag=1
26050         local first_rpc
26051         local second_rpc
26052         local third_rpc
26053
26054         $LCTL get_param $ll_opencache_threshold_count ||
26055                 skip "client does not have opencache parameter"
26056
26057         set_opencache $new_flag
26058         stack_trap "restore_opencache"
26059         [ $($LCTL get_param -n $ll_opencache_threshold_count) == $new_flag ] ||
26060                 error "enable opencache failed"
26061         touch $testfile
26062         # drop MDC DLM locks
26063         cancel_lru_locks mdc
26064         # clear MDC RPC stats counters
26065         $LCTL set_param $mdc_rpcstats=clear
26066
26067         # According to the current implementation, we need to run 3 times
26068         # open & close file to verify if opencache is enabled correctly.
26069         # 1st, RPCs are sent for lookup/open and open handle is released on
26070         #      close finally.
26071         # 2nd, RPC is sent for open, MDS_OPEN_LOCK is fetched automatically,
26072         #      so open handle won't be released thereafter.
26073         # 3rd, No RPC is sent out.
26074         $MULTIOP $testfile oc || error "multiop failed"
26075         first_rpc=$(calc_stats $mdc_rpcstats ldlm_ibits_enqueue)
26076         echo "1st: $first_rpc RPCs in flight"
26077
26078         $MULTIOP $testfile oc || error "multiop failed"
26079         second_rpc=$(calc_stats $mdc_rpcstats ldlm_ibits_enqueue)
26080         echo "2nd: $second_rpc RPCs in flight"
26081
26082         $MULTIOP $testfile oc || error "multiop failed"
26083         third_rpc=$(calc_stats $mdc_rpcstats ldlm_ibits_enqueue)
26084         echo "3rd: $third_rpc RPCs in flight"
26085
26086         #verify no MDC RPC is sent
26087         [[ $second_rpc == $third_rpc ]] || error "MDC RPC is still sent"
26088 }
26089 run_test 429 "verify if opencache flag on client side does work"
26090
26091 lseek_test_430() {
26092         local offset
26093         local file=$1
26094
26095         # data at [200K, 400K)
26096         dd if=/dev/urandom of=$file bs=256K count=1 seek=1 ||
26097                 error "256K->512K dd fails"
26098         # data at [2M, 3M)
26099         dd if=/dev/urandom of=$file bs=1M count=1 seek=2 ||
26100                 error "2M->3M dd fails"
26101         # data at [4M, 5M)
26102         dd if=/dev/urandom of=$file bs=1M count=1 seek=4 ||
26103                 error "4M->5M dd fails"
26104         echo "Data at 256K...512K, 2M...3M and 4M...5M"
26105         # start at first component hole #1
26106         printf "Seeking hole from 1000 ... "
26107         offset=$(lseek_test -l 1000 $file)
26108         echo $offset
26109         [[ $offset == 1000 ]] || error "offset $offset != 1000"
26110         printf "Seeking data from 1000 ... "
26111         offset=$(lseek_test -d 1000 $file)
26112         echo $offset
26113         [[ $offset == 262144 ]] || error "offset $offset != 262144"
26114
26115         # start at first component data block
26116         printf "Seeking hole from 300000 ... "
26117         offset=$(lseek_test -l 300000 $file)
26118         echo $offset
26119         [[ $offset == 524288 ]] || error "offset $offset != 524288"
26120         printf "Seeking data from 300000 ... "
26121         offset=$(lseek_test -d 300000 $file)
26122         echo $offset
26123         [[ $offset == 300000 ]] || error "offset $offset != 300000"
26124
26125         # start at the first component but beyond end of object size
26126         printf "Seeking hole from 1000000 ... "
26127         offset=$(lseek_test -l 1000000 $file)
26128         echo $offset
26129         [[ $offset == 1000000 ]] || error "offset $offset != 1000000"
26130         printf "Seeking data from 1000000 ... "
26131         offset=$(lseek_test -d 1000000 $file)
26132         echo $offset
26133         [[ $offset == 2097152 ]] || error "offset $offset != 2097152"
26134
26135         # start at second component stripe 2 (empty file)
26136         printf "Seeking hole from 1500000 ... "
26137         offset=$(lseek_test -l 1500000 $file)
26138         echo $offset
26139         [[ $offset == 1500000 ]] || error "offset $offset != 1500000"
26140         printf "Seeking data from 1500000 ... "
26141         offset=$(lseek_test -d 1500000 $file)
26142         echo $offset
26143         [[ $offset == 2097152 ]] || error "offset $offset != 2097152"
26144
26145         # start at second component stripe 1 (all data)
26146         printf "Seeking hole from 3000000 ... "
26147         offset=$(lseek_test -l 3000000 $file)
26148         echo $offset
26149         [[ $offset == 3145728 ]] || error "offset $offset != 3145728"
26150         printf "Seeking data from 3000000 ... "
26151         offset=$(lseek_test -d 3000000 $file)
26152         echo $offset
26153         [[ $offset == 3000000 ]] || error "offset $offset != 3000000"
26154
26155         dd if=/dev/urandom of=$file bs=640K count=1 seek=1 ||
26156                 error "2nd dd fails"
26157         echo "Add data block at 640K...1280K"
26158
26159         # start at before new data block, in hole
26160         printf "Seeking hole from 600000 ... "
26161         offset=$(lseek_test -l 600000 $file)
26162         echo $offset
26163         [[ $offset == 600000 ]] || error "offset $offset != 600000"
26164         printf "Seeking data from 600000 ... "
26165         offset=$(lseek_test -d 600000 $file)
26166         echo $offset
26167         [[ $offset == 655360 ]] || error "offset $offset != 655360"
26168
26169         # start at the first component new data block
26170         printf "Seeking hole from 1000000 ... "
26171         offset=$(lseek_test -l 1000000 $file)
26172         echo $offset
26173         [[ $offset == 1310720 ]] || error "offset $offset != 1310720"
26174         printf "Seeking data from 1000000 ... "
26175         offset=$(lseek_test -d 1000000 $file)
26176         echo $offset
26177         [[ $offset == 1000000 ]] || error "offset $offset != 1000000"
26178
26179         # start at second component stripe 2, new data
26180         printf "Seeking hole from 1200000 ... "
26181         offset=$(lseek_test -l 1200000 $file)
26182         echo $offset
26183         [[ $offset == 1310720 ]] || error "offset $offset != 1310720"
26184         printf "Seeking data from 1200000 ... "
26185         offset=$(lseek_test -d 1200000 $file)
26186         echo $offset
26187         [[ $offset == 1200000 ]] || error "offset $offset != 1200000"
26188
26189         # start beyond file end
26190         printf "Using offset > filesize ... "
26191         lseek_test -l 4000000 $file && error "lseek should fail"
26192         printf "Using offset > filesize ... "
26193         lseek_test -d 4000000 $file && error "lseek should fail"
26194
26195         printf "Done\n\n"
26196 }
26197
26198 test_430a() {
26199         $LCTL get_param mdc.*.import | grep -q 'connect_flags:.*seek' ||
26200                 skip "MDT does not support SEEK_HOLE"
26201
26202         $LCTL get_param osc.*.import | grep -q 'connect_flags:.*seek' ||
26203                 skip "OST does not support SEEK_HOLE"
26204
26205         local file=$DIR/$tdir/$tfile
26206
26207         mkdir -p $DIR/$tdir
26208
26209         $LFS setstripe -E 1M -L mdt -E eof -c2 $file
26210         # OST stripe #1 will have continuous data at [1M, 3M)
26211         # OST stripe #2 is empty
26212         echo "Component #1: 1M DoM, component #2: EOF, 2 stripes 1M"
26213         lseek_test_430 $file
26214         rm $file
26215         $LFS setstripe -E 1M -c2 -S 64K -E 10M -c2 -S 1M $file
26216         echo "Component #1: 1M, 2 stripes 64K, component #2: EOF, 2 stripes 1M"
26217         lseek_test_430 $file
26218         rm $file
26219         $LFS setstripe -c2 -S 512K $file
26220         echo "Two stripes, stripe size 512K"
26221         lseek_test_430 $file
26222         rm $file
26223         # FLR with stale mirror
26224         $LFS setstripe -N -E 512K -c1 -S 64K -E eof -c2 -S 512K \
26225                        -N -c2 -S 1M $file
26226         echo "Mirrored file:"
26227         echo "Component #1: 512K, stripe 64K, component #2: EOF, 2 stripes 512K"
26228         echo "Plain 2 stripes 1M"
26229         lseek_test_430 $file
26230         rm $file
26231 }
26232 run_test 430a "lseek: SEEK_DATA/SEEK_HOLE basic functionality"
26233
26234 test_430b() {
26235         $LCTL get_param osc.*.import | grep -q 'connect_flags:.*seek' ||
26236                 skip "OST does not support SEEK_HOLE"
26237
26238         local offset
26239         local file=$DIR/$tdir/$tfile
26240
26241         mkdir -p $DIR/$tdir
26242         # Empty layout lseek should fail
26243         $MCREATE $file
26244         # seek from 0
26245         printf "Seeking hole from 0 ... "
26246         lseek_test -l 0 $file && error "lseek should fail"
26247         printf "Seeking data from 0 ... "
26248         lseek_test -d 0 $file && error "lseek should fail"
26249         rm $file
26250
26251         # 1M-hole file
26252         $LFS setstripe -E 1M -c2 -E eof $file
26253         $TRUNCATE $file 1048576
26254         printf "Seeking hole from 1000000 ... "
26255         offset=$(lseek_test -l 1000000 $file)
26256         echo $offset
26257         [[ $offset == 1000000 ]] || error "offset $offset != 1000000"
26258         printf "Seeking data from 1000000 ... "
26259         lseek_test -d 1000000 $file && error "lseek should fail"
26260         rm $file
26261
26262         # full component followed by non-inited one
26263         $LFS setstripe -E 1M -c2 -E eof $file
26264         dd if=/dev/urandom of=$file bs=1M count=1
26265         printf "Seeking hole from 1000000 ... "
26266         offset=$(lseek_test -l 1000000 $file)
26267         echo $offset
26268         [[ $offset == 1048576 ]] || error "offset $offset != 1048576"
26269         printf "Seeking hole from 1048576 ... "
26270         lseek_test -l 1048576 $file && error "lseek should fail"
26271         # init second component and truncate back
26272         echo "123" >> $file
26273         $TRUNCATE $file 1048576
26274         printf "Seeking hole from 1000000 ... "
26275         offset=$(lseek_test -l 1000000 $file)
26276         echo $offset
26277         [[ $offset == 1048576 ]] || error "offset $offset != 1048576"
26278         printf "Seeking hole from 1048576 ... "
26279         lseek_test -l 1048576 $file && error "lseek should fail"
26280         # boundary checks for big values
26281         dd if=/dev/urandom of=$file.10g bs=1 count=1 seek=10G
26282         offset=$(lseek_test -d 0 $file.10g)
26283         [[ $offset == 10737418240 ]] || error "offset $offset != 10737418240"
26284         dd if=/dev/urandom of=$file.100g bs=1 count=1 seek=100G
26285         offset=$(lseek_test -d 0 $file.100g)
26286         [[ $offset == 107374182400 ]] || error "offset $offset != 107374182400"
26287         return 0
26288 }
26289 run_test 430b "lseek: SEEK_DATA/SEEK_HOLE special cases"
26290
26291 test_430c() {
26292         $LCTL get_param osc.*.import | grep -q 'connect_flags:.*seek' ||
26293                 skip "OST does not support SEEK_HOLE"
26294
26295         local file=$DIR/$tdir/$tfile
26296         local start
26297
26298         mkdir -p $DIR/$tdir
26299         dd if=/dev/urandom of=$file bs=1k count=1 seek=5M
26300
26301         # cp version 8.33+ prefers lseek over fiemap
26302         if [[ $(cp --version | head -n1 | sed "s/[^0-9]//g") -ge 833 ]]; then
26303                 start=$SECONDS
26304                 time cp $file /dev/null
26305                 (( SECONDS - start < 5 )) ||
26306                         error "cp: too long runtime $((SECONDS - start))"
26307
26308         fi
26309         # tar version 1.29+ supports SEEK_HOLE/DATA
26310         if [[ $(tar --version | head -n1 | sed "s/[^0-9]//g") -ge 129 ]]; then
26311                 start=$SECONDS
26312                 time tar cS $file - | cat > /dev/null
26313                 (( SECONDS - start < 5 )) ||
26314                         error "tar: too long runtime $((SECONDS - start))"
26315         fi
26316 }
26317 run_test 430c "lseek: external tools check"
26318
26319 test_431() { # LU-14187
26320         local file=$DIR/$tdir/$tfile
26321
26322         mkdir -p $DIR/$tdir
26323         $LFS setstripe -c 1 -i 0 $file || error "lfs setstripe failed"
26324         dd if=/dev/urandom of=$file bs=4k count=1
26325         dd if=/dev/urandom of=$file bs=4k count=1 seek=10 conv=notrunc
26326         dd if=/dev/urandom of=$file bs=4k count=1 seek=12 conv=notrunc
26327         #define OBD_FAIL_OST_RESTART_IO 0x251
26328         do_facet ost1 "$LCTL set_param fail_loc=0x251"
26329         $LFS setstripe -c 1 -i 0 $file.0 || error "lfs setstripe failed"
26330         cp $file $file.0
26331         cancel_lru_locks
26332         sync_all_data
26333         echo 3 > /proc/sys/vm/drop_caches
26334         diff  $file $file.0 || error "data diff"
26335 }
26336 run_test 431 "Restart transaction for IO"
26337
26338 cleanup_test_432() {
26339         do_facet mgs $LCTL nodemap_activate 0
26340         wait_nm_sync active
26341 }
26342
26343 test_432() {
26344         local tmpdir=$TMP/dir432
26345
26346         (( $MDS1_VERSION >= $(version_code 2.14.52) )) ||
26347                 skip "Need MDS version at least 2.14.52"
26348
26349         stack_trap cleanup_test_432 EXIT
26350         mkdir $DIR/$tdir
26351         mkdir $tmpdir
26352
26353         do_facet mgs $LCTL nodemap_activate 1
26354         wait_nm_sync active
26355         do_facet mgs $LCTL nodemap_modify --name default \
26356                 --property admin --value 1
26357         do_facet mgs $LCTL nodemap_modify --name default \
26358                 --property trusted --value 1
26359         cancel_lru_locks mdc
26360         wait_nm_sync default admin_nodemap
26361         wait_nm_sync default trusted_nodemap
26362
26363         if [ $(mv $tmpdir $DIR/$tdir/ 2>&1 |
26364                grep -ci "Operation not permitted") -ne 0 ]; then
26365                 error "mv $tmpdir $DIR/$tdir/ hits 'Operation not permitted'"
26366         fi
26367 }
26368 run_test 432 "mv dir from outside Lustre"
26369
26370 prep_801() {
26371         [[ $MDS1_VERSION -lt $(version_code 2.9.55) ]] ||
26372         [[ $OST1_VERSION -lt $(version_code 2.9.55) ]] &&
26373                 skip "Need server version at least 2.9.55"
26374
26375         start_full_debug_logging
26376 }
26377
26378 post_801() {
26379         stop_full_debug_logging
26380 }
26381
26382 barrier_stat() {
26383         if [ $MGS_VERSION -le $(version_code 2.10.0) ]; then
26384                 local st=$(do_facet mgs $LCTL barrier_stat $FSNAME |
26385                            awk '/The barrier for/ { print $7 }')
26386                 echo $st
26387         else
26388                 local st=$(do_facet mgs $LCTL barrier_stat -s $FSNAME)
26389                 echo \'$st\'
26390         fi
26391 }
26392
26393 barrier_expired() {
26394         local expired
26395
26396         if [ $MGS_VERSION -le $(version_code 2.10.0) ]; then
26397                 expired=$(do_facet mgs $LCTL barrier_stat $FSNAME |
26398                           awk '/will be expired/ { print $7 }')
26399         else
26400                 expired=$(do_facet mgs $LCTL barrier_stat -t $FSNAME)
26401         fi
26402
26403         echo $expired
26404 }
26405
26406 test_801a() {
26407         prep_801
26408
26409         echo "Start barrier_freeze at: $(date)"
26410         #define OBD_FAIL_BARRIER_DELAY          0x2202
26411         do_facet mgs $LCTL set_param fail_val=5 fail_loc=0x2202
26412         # Do not reduce barrier time - See LU-11873
26413         do_facet mgs $LCTL barrier_freeze $FSNAME 20 &
26414
26415         sleep 2
26416         local b_status=$(barrier_stat)
26417         echo "Got barrier status at: $(date)"
26418         [ "$b_status" = "'freezing_p1'" ] ||
26419                 error "(1) unexpected barrier status $b_status"
26420
26421         do_facet mgs $LCTL set_param fail_val=0 fail_loc=0
26422         wait
26423         b_status=$(barrier_stat)
26424         [ "$b_status" = "'frozen'" ] ||
26425                 error "(2) unexpected barrier status $b_status"
26426
26427         local expired=$(barrier_expired)
26428         echo "sleep $((expired + 3)) seconds, then the barrier will be expired"
26429         sleep $((expired + 3))
26430
26431         b_status=$(barrier_stat)
26432         [ "$b_status" = "'expired'" ] ||
26433                 error "(3) unexpected barrier status $b_status"
26434
26435         # Do not reduce barrier time - See LU-11873
26436         do_facet mgs $LCTL barrier_freeze $FSNAME 20 ||
26437                 error "(4) fail to freeze barrier"
26438
26439         b_status=$(barrier_stat)
26440         [ "$b_status" = "'frozen'" ] ||
26441                 error "(5) unexpected barrier status $b_status"
26442
26443         echo "Start barrier_thaw at: $(date)"
26444         #define OBD_FAIL_BARRIER_DELAY          0x2202
26445         do_facet mgs $LCTL set_param fail_val=5 fail_loc=0x2202
26446         do_facet mgs $LCTL barrier_thaw $FSNAME &
26447
26448         sleep 2
26449         b_status=$(barrier_stat)
26450         echo "Got barrier status at: $(date)"
26451         [ "$b_status" = "'thawing'" ] ||
26452                 error "(6) unexpected barrier status $b_status"
26453
26454         do_facet mgs $LCTL set_param fail_val=0 fail_loc=0
26455         wait
26456         b_status=$(barrier_stat)
26457         [ "$b_status" = "'thawed'" ] ||
26458                 error "(7) unexpected barrier status $b_status"
26459
26460         #define OBD_FAIL_BARRIER_FAILURE        0x2203
26461         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2203
26462         do_facet mgs $LCTL barrier_freeze $FSNAME
26463
26464         b_status=$(barrier_stat)
26465         [ "$b_status" = "'failed'" ] ||
26466                 error "(8) unexpected barrier status $b_status"
26467
26468         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
26469         do_facet mgs $LCTL barrier_thaw $FSNAME
26470
26471         post_801
26472 }
26473 run_test 801a "write barrier user interfaces and stat machine"
26474
26475 test_801b() {
26476         prep_801
26477
26478         mkdir $DIR/$tdir || error "(1) fail to mkdir"
26479         createmany -d $DIR/$tdir/d 6 || "(2) fail to mkdir"
26480         touch $DIR/$tdir/d2/f10 || error "(3) fail to touch"
26481         touch $DIR/$tdir/d3/f11 || error "(4) fail to touch"
26482         touch $DIR/$tdir/d4/f12 || error "(5) fail to touch"
26483
26484         cancel_lru_locks mdc
26485
26486         # 180 seconds should be long enough
26487         do_facet mgs $LCTL barrier_freeze $FSNAME 180
26488
26489         local b_status=$(barrier_stat)
26490         [ "$b_status" = "'frozen'" ] ||
26491                 error "(6) unexpected barrier status $b_status"
26492
26493         mkdir $DIR/$tdir/d0/d10 &
26494         mkdir_pid=$!
26495
26496         touch $DIR/$tdir/d1/f13 &
26497         touch_pid=$!
26498
26499         ln $DIR/$tdir/d2/f10 $DIR/$tdir/d2/f14 &
26500         ln_pid=$!
26501
26502         mv $DIR/$tdir/d3/f11 $DIR/$tdir/d3/f15 &
26503         mv_pid=$!
26504
26505         rm -f $DIR/$tdir/d4/f12 &
26506         rm_pid=$!
26507
26508         stat $DIR/$tdir/d5 || error "(7) stat should succeed"
26509
26510         # To guarantee taht the 'stat' is not blocked
26511         b_status=$(barrier_stat)
26512         [ "$b_status" = "'frozen'" ] ||
26513                 error "(8) unexpected barrier status $b_status"
26514
26515         # let above commands to run at background
26516         sleep 5
26517
26518         ps -p $mkdir_pid || error "(9) mkdir should be blocked"
26519         ps -p $touch_pid || error "(10) touch should be blocked"
26520         ps -p $ln_pid || error "(11) link should be blocked"
26521         ps -p $mv_pid || error "(12) rename should be blocked"
26522         ps -p $rm_pid || error "(13) unlink should be blocked"
26523
26524         b_status=$(barrier_stat)
26525         [ "$b_status" = "'frozen'" ] ||
26526                 error "(14) unexpected barrier status $b_status"
26527
26528         do_facet mgs $LCTL barrier_thaw $FSNAME
26529         b_status=$(barrier_stat)
26530         [ "$b_status" = "'thawed'" ] ||
26531                 error "(15) unexpected barrier status $b_status"
26532
26533         wait $mkdir_pid || error "(16) mkdir should succeed"
26534         wait $touch_pid || error "(17) touch should succeed"
26535         wait $ln_pid || error "(18) link should succeed"
26536         wait $mv_pid || error "(19) rename should succeed"
26537         wait $rm_pid || error "(20) unlink should succeed"
26538
26539         post_801
26540 }
26541 run_test 801b "modification will be blocked by write barrier"
26542
26543 test_801c() {
26544         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
26545
26546         prep_801
26547
26548         stop mds2 || error "(1) Fail to stop mds2"
26549
26550         do_facet mgs $LCTL barrier_freeze $FSNAME 30
26551
26552         local b_status=$(barrier_stat)
26553         [ "$b_status" = "'expired'" ] || [ "$b_status" = "'failed'" ] || {
26554                 do_facet mgs $LCTL barrier_thaw $FSNAME
26555                 error "(2) unexpected barrier status $b_status"
26556         }
26557
26558         do_facet mgs $LCTL barrier_rescan $FSNAME ||
26559                 error "(3) Fail to rescan barrier bitmap"
26560
26561         # Do not reduce barrier time - See LU-11873
26562         do_facet mgs $LCTL barrier_freeze $FSNAME 20
26563
26564         b_status=$(barrier_stat)
26565         [ "$b_status" = "'frozen'" ] ||
26566                 error "(4) unexpected barrier status $b_status"
26567
26568         do_facet mgs $LCTL barrier_thaw $FSNAME
26569         b_status=$(barrier_stat)
26570         [ "$b_status" = "'thawed'" ] ||
26571                 error "(5) unexpected barrier status $b_status"
26572
26573         local devname=$(mdsdevname 2)
26574
26575         start mds2 $devname $MDS_MOUNT_OPTS || error "(6) Fail to start mds2"
26576
26577         do_facet mgs $LCTL barrier_rescan $FSNAME ||
26578                 error "(7) Fail to rescan barrier bitmap"
26579
26580         post_801
26581 }
26582 run_test 801c "rescan barrier bitmap"
26583
26584 saved_MGS_MOUNT_OPTS=$MGS_MOUNT_OPTS
26585 saved_MDS_MOUNT_OPTS=$MDS_MOUNT_OPTS
26586 saved_OST_MOUNT_OPTS=$OST_MOUNT_OPTS
26587 saved_MOUNT_OPTS=$MOUNT_OPTS
26588
26589 cleanup_802a() {
26590         trap 0
26591
26592         stopall
26593         MGS_MOUNT_OPTS=$saved_MGS_MOUNT_OPTS
26594         MDS_MOUNT_OPTS=$saved_MDS_MOUNT_OPTS
26595         OST_MOUNT_OPTS=$saved_OST_MOUNT_OPTS
26596         MOUNT_OPTS=$saved_MOUNT_OPTS
26597         setupall
26598 }
26599
26600 test_802a() {
26601         [[ $mds1_FSTYPE = zfs ]] || skip "ZFS specific test"
26602         [[ $MDS1_VERSION -lt $(version_code 2.9.55) ]] ||
26603         [[ $OST1_VERSION -lt $(version_code 2.9.55) ]] &&
26604                 skip "Need server version at least 2.9.55"
26605
26606         [[ $ENABLE_QUOTA ]] && skip "Quota enabled for read-only test"
26607
26608         mkdir $DIR/$tdir || error "(1) fail to mkdir"
26609
26610         cp $LUSTRE/tests/test-framework.sh $DIR/$tdir/ ||
26611                 error "(2) Fail to copy"
26612
26613         trap cleanup_802a EXIT
26614
26615         # sync by force before remount as readonly
26616         sync; sync_all_data; sleep 3; sync_all_data
26617
26618         stopall
26619
26620         MGS_MOUNT_OPTS=$(csa_add "$MGS_MOUNT_OPTS" -o rdonly_dev)
26621         MDS_MOUNT_OPTS=$(csa_add "$MDS_MOUNT_OPTS" -o rdonly_dev)
26622         OST_MOUNT_OPTS=$(csa_add "$OST_MOUNT_OPTS" -o rdonly_dev)
26623
26624         echo "Mount the server as read only"
26625         setupall server_only || error "(3) Fail to start servers"
26626
26627         echo "Mount client without ro should fail"
26628         mount_client $MOUNT &&
26629                 error "(4) Mount client without 'ro' should fail"
26630
26631         echo "Mount client with ro should succeed"
26632         MOUNT_OPTS=$(csa_add "$MOUNT_OPTS" -o ro)
26633         mount_client $MOUNT ||
26634                 error "(5) Mount client with 'ro' should succeed"
26635
26636         echo "Modify should be refused"
26637         touch $DIR/$tdir/guard && error "(6) Touch should fail under ro mode"
26638
26639         echo "Read should be allowed"
26640         diff $LUSTRE/tests/test-framework.sh $DIR/$tdir/test-framework.sh ||
26641                 error "(7) Read should succeed under ro mode"
26642
26643         cleanup_802a
26644 }
26645 run_test 802a "simulate readonly device"
26646
26647 test_802b() {
26648         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26649         remote_mds_nodsh && skip "remote MDS with nodsh"
26650
26651         do_facet $SINGLEMDS $LCTL get_param mdt.*.readonly ||
26652                 skip "readonly option not available"
26653
26654         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "(1) fail to mkdir"
26655
26656         cp $LUSTRE/tests/test-framework.sh $DIR/$tdir/ ||
26657                 error "(2) Fail to copy"
26658
26659         # write back all cached data before setting MDT to readonly
26660         cancel_lru_locks
26661         sync_all_data
26662
26663         do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=1
26664         stack_trap "do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=0" EXIT
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         # disable readonly
26674         do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=0
26675 }
26676 run_test 802b "be able to set MDTs to readonly"
26677
26678 test_803a() {
26679         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
26680         [ $MDS1_VERSION -lt $(version_code 2.10.54) ] &&
26681                 skip "MDS needs to be newer than 2.10.54"
26682
26683         mkdir_on_mdt0 $DIR/$tdir
26684         # Create some objects on all MDTs to trigger related logs objects
26685         for idx in $(seq $MDSCOUNT); do
26686                 $LFS mkdir -c $MDSCOUNT -i $((idx % $MDSCOUNT)) \
26687                         $DIR/$tdir/dir${idx} ||
26688                         error "Fail to create $DIR/$tdir/dir${idx}"
26689         done
26690
26691         sync; sleep 3
26692         wait_delete_completed # ensure old test cleanups are finished
26693         echo "before create:"
26694         $LFS df -i $MOUNT
26695         local before_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
26696
26697         for i in {1..10}; do
26698                 $LFS mkdir -c 1 -i 1 $DIR/$tdir/foo$i ||
26699                         error "Fail to create $DIR/$tdir/foo$i"
26700         done
26701
26702         sync; sleep 3
26703         echo "after create:"
26704         $LFS df -i $MOUNT
26705         local after_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
26706
26707         # allow for an llog to be cleaned up during the test
26708         [ $after_used -ge $((before_used + 10 - 1)) ] ||
26709                 error "before ($before_used) + 10 > after ($after_used)"
26710
26711         for i in {1..10}; do
26712                 rm -rf $DIR/$tdir/foo$i ||
26713                         error "Fail to remove $DIR/$tdir/foo$i"
26714         done
26715
26716         sleep 3 # avoid MDT return cached statfs
26717         wait_delete_completed
26718         echo "after unlink:"
26719         $LFS df -i $MOUNT
26720         after_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
26721
26722         # allow for an llog to be created during the test
26723         [ $after_used -le $((before_used + 1)) ] ||
26724                 error "after ($after_used) > before ($before_used) + 1"
26725 }
26726 run_test 803a "verify agent object for remote object"
26727
26728 test_803b() {
26729         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
26730         [ $MDS1_VERSION -lt $(version_code 2.13.56) ] &&
26731                 skip "MDS needs to be newer than 2.13.56"
26732         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26733
26734         for i in $(seq 0 $((MDSCOUNT - 1))); do
26735                 $LFS mkdir -i $i $DIR/$tdir.$i || error "mkdir $tdir.$i"
26736         done
26737
26738         local before=0
26739         local after=0
26740
26741         local tmp
26742
26743         stat $DIR/$tdir.* >/dev/null || error "stat $tdir.*"
26744         for i in $(seq 0 $((MDSCOUNT - 1))); do
26745                 tmp=$(do_facet mds$i $LCTL get_param mdt.*-MDT000$i.md_stats |
26746                         awk '/getattr/ { print $2 }')
26747                 before=$((before + tmp))
26748         done
26749         stat $DIR/$tdir.* >/dev/null || error "stat $tdir.*"
26750         for i in $(seq 0 $((MDSCOUNT - 1))); do
26751                 tmp=$(do_facet mds$i $LCTL get_param mdt.*-MDT000$i.md_stats |
26752                         awk '/getattr/ { print $2 }')
26753                 after=$((after + tmp))
26754         done
26755
26756         [ $before -eq $after ] || error "getattr count $before != $after"
26757 }
26758 run_test 803b "remote object can getattr from cache"
26759
26760 test_804() {
26761         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
26762         [ $MDS1_VERSION -lt $(version_code 2.10.54) ] &&
26763                 skip "MDS needs to be newer than 2.10.54"
26764         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
26765
26766         mkdir -p $DIR/$tdir
26767         $LFS mkdir -c 1 -i 1 $DIR/$tdir/dir0 ||
26768                 error "Fail to create $DIR/$tdir/dir0"
26769
26770         local fid=$($LFS path2fid $DIR/$tdir/dir0)
26771         local dev=$(mdsdevname 2)
26772
26773         do_facet mds2 "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
26774                 grep ${fid} || error "NOT found agent entry for dir0"
26775
26776         $LFS mkdir -c $MDSCOUNT -i 0 $DIR/$tdir/dir1 ||
26777                 error "Fail to create $DIR/$tdir/dir1"
26778
26779         touch $DIR/$tdir/dir1/foo0 ||
26780                 error "Fail to create $DIR/$tdir/dir1/foo0"
26781         fid=$($LFS path2fid $DIR/$tdir/dir1/foo0)
26782         local rc=0
26783
26784         for idx in $(seq $MDSCOUNT); do
26785                 dev=$(mdsdevname $idx)
26786                 do_facet mds${idx} \
26787                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
26788                         grep ${fid} && rc=$idx
26789         done
26790
26791         mv $DIR/$tdir/dir1/foo0 $DIR/$tdir/dir1/foo1 ||
26792                 error "Fail to rename foo0 to foo1"
26793         if [ $rc -eq 0 ]; then
26794                 for idx in $(seq $MDSCOUNT); do
26795                         dev=$(mdsdevname $idx)
26796                         do_facet mds${idx} \
26797                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
26798                         grep ${fid} && rc=$idx
26799                 done
26800         fi
26801
26802         mv $DIR/$tdir/dir1/foo1 $DIR/$tdir/dir1/foo2 ||
26803                 error "Fail to rename foo1 to foo2"
26804         if [ $rc -eq 0 ]; then
26805                 for idx in $(seq $MDSCOUNT); do
26806                         dev=$(mdsdevname $idx)
26807                         do_facet mds${idx} \
26808                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
26809                         grep ${fid} && rc=$idx
26810                 done
26811         fi
26812
26813         [ $rc -ne 0 ] || error "NOT found agent entry for foo"
26814
26815         ln $DIR/$tdir/dir1/foo2 $DIR/$tdir/dir0/guard ||
26816                 error "Fail to link to $DIR/$tdir/dir1/foo2"
26817         mv $DIR/$tdir/dir1/foo2 $DIR/$tdir/dir1/foo0 ||
26818                 error "Fail to rename foo2 to foo0"
26819         unlink $DIR/$tdir/dir1/foo0 ||
26820                 error "Fail to unlink $DIR/$tdir/dir1/foo0"
26821         rm -rf $DIR/$tdir/dir0 ||
26822                 error "Fail to rm $DIR/$tdir/dir0"
26823
26824         for idx in $(seq $MDSCOUNT); do
26825                 dev=$(mdsdevname $idx)
26826                 rc=0
26827
26828                 stop mds${idx}
26829                 run_e2fsck $(facet_active_host mds$idx) $dev -n ||
26830                         rc=$?
26831                 start mds${idx} $dev $MDS_MOUNT_OPTS ||
26832                         error "mount mds$idx failed"
26833                 df $MOUNT > /dev/null 2>&1
26834
26835                 # e2fsck should not return error
26836                 [ $rc -eq 0 ] ||
26837                         error "e2fsck detected error on MDT${idx}: rc=$rc"
26838         done
26839 }
26840 run_test 804 "verify agent entry for remote entry"
26841
26842 cleanup_805() {
26843         do_facet $SINGLEMDS zfs set quota=$old $fsset
26844         unlinkmany $DIR/$tdir/f- 1000000
26845         trap 0
26846 }
26847
26848 test_805() {
26849         local zfs_version=$(do_facet mds1 cat /sys/module/zfs/version)
26850         [ "$mds1_FSTYPE" != "zfs" ] && skip "ZFS specific test"
26851         [ $(version_code $zfs_version) -lt $(version_code 0.7.2) ] &&
26852                 skip "netfree not implemented before 0.7"
26853         [[ $MDS1_VERSION -ge $(version_code 2.10.57) ]] ||
26854                 skip "Need MDS version at least 2.10.57"
26855
26856         local fsset
26857         local freekb
26858         local usedkb
26859         local old
26860         local quota
26861         local pref="osd-zfs.$FSNAME-MDT0000."
26862
26863         # limit available space on MDS dataset to meet nospace issue
26864         # quickly. then ZFS 0.7.2 can use reserved space if asked
26865         # properly (using netfree flag in osd_declare_destroy()
26866         fsset=$(do_facet $SINGLEMDS lctl get_param -n $pref.mntdev)
26867         old=$(do_facet $SINGLEMDS zfs get -H quota $fsset | \
26868                 gawk '{print $3}')
26869         freekb=$(do_facet $SINGLEMDS lctl get_param -n $pref.kbytesfree)
26870         usedkb=$(do_facet $SINGLEMDS lctl get_param -n $pref.kbytestotal)
26871         let "usedkb=usedkb-freekb"
26872         let "freekb=freekb/2"
26873         if let "freekb > 5000"; then
26874                 let "freekb=5000"
26875         fi
26876         do_facet $SINGLEMDS zfs set quota=$(((usedkb+freekb)*1024)) $fsset
26877         trap cleanup_805 EXIT
26878         mkdir_on_mdt0 $DIR/$tdir
26879         $LFS setstripe -E 1M -c2 -E 4M -c2 -E -1 -c2 $DIR/$tdir ||
26880                 error "Can't set PFL layout"
26881         createmany -m $DIR/$tdir/f- 1000000 && error "ENOSPC wasn't met"
26882         rm -rf $DIR/$tdir || error "not able to remove"
26883         do_facet $SINGLEMDS zfs set quota=$old $fsset
26884         trap 0
26885 }
26886 run_test 805 "ZFS can remove from full fs"
26887
26888 # Size-on-MDS test
26889 check_lsom_data()
26890 {
26891         local file=$1
26892         local expect=$(stat -c %s $file)
26893
26894         check_lsom_size $1 $expect
26895
26896         local blocks=$($LFS getsom -b $file)
26897         expect=$(stat -c %b $file)
26898         [[ $blocks == $expect ]] ||
26899                 error "$file expected blocks: $expect, got: $blocks"
26900 }
26901
26902 check_lsom_size()
26903 {
26904         local size
26905         local expect=$2
26906
26907         cancel_lru_locks mdc
26908
26909         size=$($LFS getsom -s $1)
26910         [[ $size == $expect ]] ||
26911                 error "$file expected size: $expect, got: $size"
26912 }
26913
26914 test_806() {
26915         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
26916                 skip "Need MDS version at least 2.11.52"
26917
26918         local bs=1048576
26919
26920         touch $DIR/$tfile || error "touch $tfile failed"
26921
26922         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
26923         save_lustre_params client "llite.*.xattr_cache" > $save
26924         lctl set_param llite.*.xattr_cache=0
26925         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
26926
26927         # single-threaded write
26928         echo "Test SOM for single-threaded write"
26929         dd if=/dev/zero of=$DIR/$tfile bs=$bs count=1 ||
26930                 error "write $tfile failed"
26931         check_lsom_size $DIR/$tfile $bs
26932
26933         local num=32
26934         local size=$(($num * $bs))
26935         local offset=0
26936         local i
26937
26938         echo "Test SOM for single client multi-threaded($num) write"
26939         $TRUNCATE $DIR/$tfile 0
26940         for ((i = 0; i < $num; i++)); do
26941                 $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
26942                 local pids[$i]=$!
26943                 offset=$((offset + $bs))
26944         done
26945         for (( i=0; i < $num; i++ )); do
26946                 wait ${pids[$i]}
26947         done
26948         check_lsom_size $DIR/$tfile $size
26949
26950         $TRUNCATE $DIR/$tfile 0
26951         for ((i = 0; i < $num; i++)); do
26952                 offset=$((offset - $bs))
26953                 $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
26954                 local pids[$i]=$!
26955         done
26956         for (( i=0; i < $num; i++ )); do
26957                 wait ${pids[$i]}
26958         done
26959         check_lsom_size $DIR/$tfile $size
26960
26961         # multi-client writes
26962         num=$(get_node_count ${CLIENTS//,/ })
26963         size=$(($num * $bs))
26964         offset=0
26965         i=0
26966
26967         echo "Test SOM for multi-client ($num) writes"
26968         $TRUNCATE $DIR/$tfile 0
26969         for client in ${CLIENTS//,/ }; do
26970                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
26971                 local pids[$i]=$!
26972                 i=$((i + 1))
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 $offset
26979
26980         i=0
26981         $TRUNCATE $DIR/$tfile 0
26982         for client in ${CLIENTS//,/ }; do
26983                 offset=$((offset - $bs))
26984                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
26985                 local pids[$i]=$!
26986                 i=$((i + 1))
26987         done
26988         for (( i=0; i < $num; i++ )); do
26989                 wait ${pids[$i]}
26990         done
26991         check_lsom_size $DIR/$tfile $size
26992
26993         # verify truncate
26994         echo "Test SOM for truncate"
26995         $TRUNCATE $DIR/$tfile 1048576
26996         check_lsom_size $DIR/$tfile 1048576
26997         $TRUNCATE $DIR/$tfile 1234
26998         check_lsom_size $DIR/$tfile 1234
26999
27000         # verify SOM blocks count
27001         echo "Verify SOM block count"
27002         $TRUNCATE $DIR/$tfile 0
27003         $MULTIOP $DIR/$tfile oO_TRUNC:O_RDWR:w1048576YSc ||
27004                 error "failed to write file $tfile"
27005         check_lsom_data $DIR/$tfile
27006 }
27007 run_test 806 "Verify Lazy Size on MDS"
27008
27009 test_807() {
27010         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
27011         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
27012                 skip "Need MDS version at least 2.11.52"
27013
27014         # Registration step
27015         changelog_register || error "changelog_register failed"
27016         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
27017         changelog_users $SINGLEMDS | grep -q $cl_user ||
27018                 error "User $cl_user not found in changelog_users"
27019
27020         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
27021         save_lustre_params client "llite.*.xattr_cache" > $save
27022         lctl set_param llite.*.xattr_cache=0
27023         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
27024
27025         rm -rf $DIR/$tdir || error "rm $tdir failed"
27026         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
27027         touch $DIR/$tdir/trunc || error "touch $tdir/trunc failed"
27028         $TRUNCATE $DIR/$tdir/trunc 1024 || error "truncate $tdir/trunc failed"
27029         $TRUNCATE $DIR/$tdir/trunc 1048576 ||
27030                 error "truncate $tdir/trunc failed"
27031
27032         local bs=1048576
27033         dd if=/dev/zero of=$DIR/$tdir/single_dd bs=$bs count=1 conv=fsync ||
27034                 error "write $tfile failed"
27035
27036         # multi-client wirtes
27037         local num=$(get_node_count ${CLIENTS//,/ })
27038         local offset=0
27039         local i=0
27040
27041         echo "Test SOM for multi-client ($num) writes"
27042         touch $DIR/$tfile || error "touch $tfile failed"
27043         $TRUNCATE $DIR/$tfile 0
27044         for client in ${CLIENTS//,/ }; do
27045                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
27046                 local pids[$i]=$!
27047                 i=$((i + 1))
27048                 offset=$((offset + $bs))
27049         done
27050         for (( i=0; i < $num; i++ )); do
27051                 wait ${pids[$i]}
27052         done
27053
27054         do_rpc_nodes "$CLIENTS" cancel_lru_locks osc
27055         do_nodes "$CLIENTS" "sync ; sleep 5 ; sync"
27056         $LSOM_SYNC -u $cl_user -m $FSNAME-MDT0000 $MOUNT
27057         check_lsom_data $DIR/$tdir/trunc
27058         check_lsom_data $DIR/$tdir/single_dd
27059         check_lsom_data $DIR/$tfile
27060
27061         rm -rf $DIR/$tdir
27062         # Deregistration step
27063         changelog_deregister || error "changelog_deregister failed"
27064 }
27065 run_test 807 "verify LSOM syncing tool"
27066
27067 check_som_nologged()
27068 {
27069         local lines=$($LFS changelog $FSNAME-MDT0000 |
27070                 grep 'x=trusted.som' | wc -l)
27071         [ $lines -ne 0 ] && error "trusted.som xattr is logged in Changelogs"
27072 }
27073
27074 test_808() {
27075         [ $MDS1_VERSION -lt $(version_code 2.11.55) ] &&
27076                 skip "Need MDS version at least 2.11.55"
27077
27078         # Registration step
27079         changelog_register || error "changelog_register failed"
27080
27081         touch $DIR/$tfile || error "touch $tfile failed"
27082         check_som_nologged
27083
27084         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=1 ||
27085                 error "write $tfile failed"
27086         check_som_nologged
27087
27088         $TRUNCATE $DIR/$tfile 1234
27089         check_som_nologged
27090
27091         $TRUNCATE $DIR/$tfile 1048576
27092         check_som_nologged
27093
27094         # Deregistration step
27095         changelog_deregister || error "changelog_deregister failed"
27096 }
27097 run_test 808 "Check trusted.som xattr not logged in Changelogs"
27098
27099 check_som_nodata()
27100 {
27101         $LFS getsom $1
27102         [[ $? -eq 61 ]] || error "DoM-only file $1 has SOM xattr"
27103 }
27104
27105 test_809() {
27106         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
27107                 skip "Need MDS version at least 2.11.56"
27108
27109         $LFS setstripe -E 1M -L mdt $DIR/$tfile ||
27110                 error "failed to create DoM-only file $DIR/$tfile"
27111         touch $DIR/$tfile || error "touch $tfile failed"
27112         check_som_nodata $DIR/$tfile
27113
27114         dd if=/dev/zero of=$DIR/$tfile bs=2048 count=1 ||
27115                 error "write $tfile failed"
27116         check_som_nodata $DIR/$tfile
27117
27118         $TRUNCATE $DIR/$tfile 1234
27119         check_som_nodata $DIR/$tfile
27120
27121         $TRUNCATE $DIR/$tfile 4097
27122         check_som_nodata $DIR/$file
27123 }
27124 run_test 809 "Verify no SOM xattr store for DoM-only files"
27125
27126 test_810() {
27127         [ $PARALLEL == "yes" ] && skip "skip parallel run"
27128         $GSS && skip_env "could not run with gss"
27129         [[ $OST1_VERSION -gt $(version_code 2.12.58) ]] ||
27130                 skip "OST < 2.12.58 doesn't align checksum"
27131
27132         set_checksums 1
27133         stack_trap "set_checksums $ORIG_CSUM" EXIT
27134         stack_trap "set_checksum_type $ORIG_CSUM_TYPE" EXIT
27135
27136         local csum
27137         local before
27138         local after
27139         for csum in $CKSUM_TYPES; do
27140                 #define OBD_FAIL_OSC_NO_GRANT   0x411
27141                 $LCTL set_param osc.*.checksum_type=$csum fail_loc=0x411
27142                 for i in "10240 0" "10000 0" "4000 1" "500 1"; do
27143                         eval set -- $i
27144                         dd if=/dev/urandom of=$DIR/$tfile bs=$1 count=2 seek=$2
27145                         before=$(md5sum $DIR/$tfile)
27146                         $LCTL set_param ldlm.namespaces.*osc*.lru_size=clear
27147                         after=$(md5sum $DIR/$tfile)
27148                         [ "$before" == "$after" ] ||
27149                                 error "$csum: $before != $after bs=$1 seek=$2"
27150                 done
27151         done
27152 }
27153 run_test 810 "partial page writes on ZFS (LU-11663)"
27154
27155 test_812a() {
27156         [ $OST1_VERSION -lt $(version_code 2.12.51) ] &&
27157                 skip "OST < 2.12.51 doesn't support this fail_loc"
27158
27159         $LFS setstripe -c 1 -i 0 $DIR/$tfile
27160         # ensure ost1 is connected
27161         stat $DIR/$tfile >/dev/null || error "can't stat"
27162         wait_osc_import_state client ost1 FULL
27163         # no locks, no reqs to let the connection idle
27164         cancel_lru_locks osc
27165
27166         # delay OST_DISCONNECT on OST1 to put OSC into intermediate state
27167 #define OBD_FAIL_OST_DISCONNECT_DELAY    0x245
27168         do_facet ost1 "$LCTL set_param fail_loc=0x245 fail_val=8"
27169         wait_osc_import_state client ost1 CONNECTING
27170         do_facet ost1 "$LCTL set_param fail_loc=0 fail_val=0"
27171
27172         stat $DIR/$tfile >/dev/null || error "can't stat file"
27173 }
27174 run_test 812a "do not drop reqs generated when imp is going to idle (LU-11951)"
27175
27176 test_812b() { # LU-12378
27177         [ $OST1_VERSION -lt $(version_code 2.12.51) ] &&
27178                 skip "OST < 2.12.51 doesn't support this fail_loc"
27179
27180         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "setstripe failed"
27181         # ensure ost1 is connected
27182         stat $DIR/$tfile >/dev/null || error "can't stat"
27183         wait_osc_import_state client ost1 FULL
27184         # no locks, no reqs to let the connection idle
27185         cancel_lru_locks osc
27186
27187         # delay OST_DISCONNECT on OST1 to put OSC into intermediate state
27188 #define OBD_FAIL_OST_DISCONNECT_DELAY    0x245
27189         do_facet ost1 "$LCTL set_param fail_loc=0x245 fail_val=8"
27190         wait_osc_import_state client ost1 CONNECTING
27191         do_facet ost1 "$LCTL set_param fail_loc=0 fail_val=0"
27192
27193         $LFS quota -u 0 $DIR/ || error "lfs quota should succeed"
27194         wait_osc_import_state client ost1 IDLE
27195 }
27196 run_test 812b "do not drop no resend request for idle connect"
27197
27198 test_812c() {
27199         local old
27200
27201         old=$($LCTL get_param -n osc.*.idle_timeout | head -n 1)
27202
27203         $LFS setstripe -c 1 -o 0 $DIR/$tfile
27204         $LFS getstripe $DIR/$tfile
27205         $LCTL set_param osc.*.idle_timeout=10
27206         stack_trap "$LCTL set_param osc.*.idle_timeout=$old" EXIT
27207         # ensure ost1 is connected
27208         stat $DIR/$tfile >/dev/null || error "can't stat"
27209         wait_osc_import_state client ost1 FULL
27210         # no locks, no reqs to let the connection idle
27211         cancel_lru_locks osc
27212
27213 #define OBD_FAIL_PTLRPC_IDLE_RACE        0x533
27214         $LCTL set_param fail_loc=0x80000533
27215         sleep 15
27216         dd if=/dev/zero of=$DIR/$tfile count=1 conv=sync || error "dd failed"
27217 }
27218 run_test 812c "idle import vs lock enqueue race"
27219
27220 test_813() {
27221         local file_heat_sav=$($LCTL get_param -n llite.*.file_heat 2>/dev/null)
27222         [ -z "$file_heat_sav" ] && skip "no file heat support"
27223
27224         local readsample
27225         local writesample
27226         local readbyte
27227         local writebyte
27228         local readsample1
27229         local writesample1
27230         local readbyte1
27231         local writebyte1
27232
27233         local period_second=$($LCTL get_param -n llite.*.heat_period_second)
27234         local decay_pct=$($LCTL get_param -n llite.*.heat_decay_percentage)
27235
27236         $LCTL set_param -n llite.*.file_heat=1
27237         echo "Turn on file heat"
27238         echo "Period second: $period_second, Decay percentage: $decay_pct"
27239
27240         echo "QQQQ" > $DIR/$tfile
27241         echo "QQQQ" > $DIR/$tfile
27242         echo "QQQQ" > $DIR/$tfile
27243         cat $DIR/$tfile > /dev/null
27244         cat $DIR/$tfile > /dev/null
27245         cat $DIR/$tfile > /dev/null
27246         cat $DIR/$tfile > /dev/null
27247
27248         local out=$($LFS heat_get $DIR/$tfile)
27249
27250         $LFS heat_get $DIR/$tfile
27251         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
27252         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
27253         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
27254         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
27255
27256         [ $readsample -le 4 ] || error "read sample ($readsample) is wrong"
27257         [ $writesample -le 3 ] || error "write sample ($writesample) is wrong"
27258         [ $readbyte -le 20 ] || error "read bytes ($readbyte) is wrong"
27259         [ $writebyte -le 15 ] || error "write bytes ($writebyte) is wrong"
27260
27261         sleep $((period_second + 3))
27262         echo "Sleep $((period_second + 3)) seconds..."
27263         # The recursion formula to calculate the heat of the file f is as
27264         # follow:
27265         # Hi+1(f) = (1-P)*Hi(f)+ P*Ci
27266         # Where Hi is the heat value in the period between time points i*I and
27267         # (i+1)*I; Ci is the access count in the period; the symbol P refers
27268         # to the weight of Ci.
27269         out=$($LFS heat_get $DIR/$tfile)
27270         $LFS heat_get $DIR/$tfile
27271         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
27272         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
27273         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
27274         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
27275
27276         [ $(bc <<< "$readsample <= 4 * $decay_pct / 100") -eq 1 ] ||
27277                 error "read sample ($readsample) is wrong"
27278         [ $(bc <<< "$writesample <= 3 * $decay_pct / 100") -eq 1 ] ||
27279                 error "write sample ($writesample) is wrong"
27280         [ $(bc <<< "$readbyte <= 20 * $decay_pct / 100") -eq 1 ] ||
27281                 error "read bytes ($readbyte) is wrong"
27282         [ $(bc <<< "$writebyte <= 15 * $decay_pct / 100") -eq 1 ] ||
27283                 error "write bytes ($writebyte) is wrong"
27284
27285         echo "QQQQ" > $DIR/$tfile
27286         echo "QQQQ" > $DIR/$tfile
27287         echo "QQQQ" > $DIR/$tfile
27288         cat $DIR/$tfile > /dev/null
27289         cat $DIR/$tfile > /dev/null
27290         cat $DIR/$tfile > /dev/null
27291         cat $DIR/$tfile > /dev/null
27292
27293         sleep $((period_second + 3))
27294         echo "Sleep $((period_second + 3)) seconds..."
27295
27296         out=$($LFS heat_get $DIR/$tfile)
27297         $LFS heat_get $DIR/$tfile
27298         readsample1=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
27299         writesample1=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
27300         readbyte1=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
27301         writebyte1=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
27302
27303         [ $(bc <<< "$readsample1 <= ($readsample * (100 - $decay_pct) + \
27304                 4 * $decay_pct) / 100") -eq 1 ] ||
27305                 error "read sample ($readsample1) is wrong"
27306         [ $(bc <<< "$writesample1 <= ($writesample * (100 - $decay_pct) + \
27307                 3 * $decay_pct) / 100") -eq 1 ] ||
27308                 error "write sample ($writesample1) is wrong"
27309         [ $(bc <<< "$readbyte1 <= ($readbyte * (100 - $decay_pct) + \
27310                 20 * $decay_pct) / 100") -eq 1 ] ||
27311                 error "read bytes ($readbyte1) is wrong"
27312         [ $(bc <<< "$writebyte1 <= ($writebyte * (100 - $decay_pct) + \
27313                 15 * $decay_pct) / 100") -eq 1 ] ||
27314                 error "write bytes ($writebyte1) is wrong"
27315
27316         echo "Turn off file heat for the file $DIR/$tfile"
27317         $LFS heat_set -o $DIR/$tfile
27318
27319         echo "QQQQ" > $DIR/$tfile
27320         echo "QQQQ" > $DIR/$tfile
27321         echo "QQQQ" > $DIR/$tfile
27322         cat $DIR/$tfile > /dev/null
27323         cat $DIR/$tfile > /dev/null
27324         cat $DIR/$tfile > /dev/null
27325         cat $DIR/$tfile > /dev/null
27326
27327         out=$($LFS heat_get $DIR/$tfile)
27328         $LFS heat_get $DIR/$tfile
27329         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
27330         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
27331         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
27332         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
27333
27334         [ $readsample -eq 0 ] || error "read sample ($readsample) is wrong"
27335         [ $writesample -eq 0 ] || error "write sample ($writesample) is wrong"
27336         [ $readbyte -eq 0 ] || error "read bytes ($readbyte) is wrong"
27337         [ $writebyte -eq 0 ] || error "write bytes ($writebyte) is wrong"
27338
27339         echo "Trun on file heat for the file $DIR/$tfile"
27340         $LFS heat_set -O $DIR/$tfile
27341
27342         echo "QQQQ" > $DIR/$tfile
27343         echo "QQQQ" > $DIR/$tfile
27344         echo "QQQQ" > $DIR/$tfile
27345         cat $DIR/$tfile > /dev/null
27346         cat $DIR/$tfile > /dev/null
27347         cat $DIR/$tfile > /dev/null
27348         cat $DIR/$tfile > /dev/null
27349
27350         out=$($LFS heat_get $DIR/$tfile)
27351         $LFS heat_get $DIR/$tfile
27352         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
27353         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
27354         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
27355         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
27356
27357         [ $readsample -gt 0 ] || error "read sample ($readsample) is wrong"
27358         [ $writesample -gt 0 ] || error "write sample ($writesample) is wrong"
27359         [ $readbyte -gt 0 ] || error "read bytes ($readbyte) is wrong"
27360         [ $writebyte -gt 0 ] || error "write bytes ($writebyte) is wrong"
27361
27362         $LFS heat_set -c $DIR/$tfile
27363         $LCTL set_param -n llite.*.file_heat=0
27364         echo "Turn off file heat support for the Lustre filesystem"
27365
27366         echo "QQQQ" > $DIR/$tfile
27367         echo "QQQQ" > $DIR/$tfile
27368         echo "QQQQ" > $DIR/$tfile
27369         cat $DIR/$tfile > /dev/null
27370         cat $DIR/$tfile > /dev/null
27371         cat $DIR/$tfile > /dev/null
27372         cat $DIR/$tfile > /dev/null
27373
27374         out=$($LFS heat_get $DIR/$tfile)
27375         $LFS heat_get $DIR/$tfile
27376         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
27377         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
27378         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
27379         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
27380
27381         [ $readsample -eq 0 ] || error "read sample ($readsample) is wrong"
27382         [ $writesample -eq 0 ] || error "write sample ($writesample) is wrong"
27383         [ $readbyte -eq 0 ] || error "read bytes ($readbyte) is wrong"
27384         [ $writebyte -eq 0 ] || error "write bytes ($writebyte) is wrong"
27385
27386         $LCTL set_param -n llite.*.file_heat=$file_heat_sav
27387         rm -f $DIR/$tfile
27388 }
27389 run_test 813 "File heat verfication"
27390
27391 test_814()
27392 {
27393         dd of=$DIR/$tfile seek=128 bs=1k < /dev/null
27394         echo -n y >> $DIR/$tfile
27395         cp --sparse=always $DIR/$tfile $DIR/${tfile}.cp || error "copy failed"
27396         diff $DIR/$tfile $DIR/${tfile}.cp || error "files should be same"
27397 }
27398 run_test 814 "sparse cp works as expected (LU-12361)"
27399
27400 test_815()
27401 {
27402         writeme -b 100 $DIR/$tfile || error "write 100 bytes failed"
27403         writeme -b 0 $DIR/$tfile || error "write 0 byte failed"
27404 }
27405 run_test 815 "zero byte tiny write doesn't hang (LU-12382)"
27406
27407 test_816() {
27408         local ost1_imp=$(get_osc_import_name client ost1)
27409         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
27410                          cut -d'.' -f2)
27411
27412         $LFS setstripe -c 1 -i 0 $DIR/$tfile
27413         # ensure ost1 is connected
27414
27415         stat $DIR/$tfile >/dev/null || error "can't stat"
27416         wait_osc_import_state client ost1 FULL
27417         # no locks, no reqs to let the connection idle
27418         cancel_lru_locks osc
27419         lru_resize_disable osc
27420         local before
27421         local now
27422         before=$($LCTL get_param -n \
27423                  ldlm.namespaces.$imp_name.lru_size)
27424
27425         wait_osc_import_state client ost1 IDLE
27426         dd if=/dev/null of=$DIR/$tfile bs=1k count=1 conv=sync
27427         now=$($LCTL get_param -n \
27428               ldlm.namespaces.$imp_name.lru_size)
27429         [ $before == $now ] || error "lru_size changed $before != $now"
27430 }
27431 run_test 816 "do not reset lru_resize on idle reconnect"
27432
27433 cleanup_817() {
27434         umount $tmpdir
27435         exportfs -u localhost:$DIR/nfsexp
27436         rm -rf $DIR/nfsexp
27437 }
27438
27439 test_817() {
27440         systemctl restart nfs-server.service || skip "failed to restart nfsd"
27441
27442         mkdir -p $DIR/nfsexp
27443         exportfs -orw,no_root_squash localhost:$DIR/nfsexp ||
27444                 error "failed to export nfs"
27445
27446         tmpdir=$(mktemp -d /tmp/nfs-XXXXXX)
27447         stack_trap cleanup_817 EXIT
27448
27449         mount -t nfs -orw localhost:$DIR/nfsexp $tmpdir ||
27450                 error "failed to mount nfs to $tmpdir"
27451
27452         cp /bin/true $tmpdir
27453         $DIR/nfsexp/true || error "failed to execute 'true' command"
27454 }
27455 run_test 817 "nfsd won't cache write lock for exec file"
27456
27457 test_818() {
27458         mkdir $DIR/$tdir
27459         $LFS setstripe -c1 -i0 $DIR/$tfile
27460         $LFS setstripe -c1 -i1 $DIR/$tfile
27461         stop $SINGLEMDS
27462         #define OBD_FAIL_OSP_CANT_PROCESS_LLOG          0x2105
27463         do_facet $SINGLEMDS lctl set_param fail_loc=0x80002105
27464         start $SINGLEMDS $(mdsdevname ${SINGLEMDS//mds/}) $MDS_MOUNT_OPTS ||
27465                 error "start $SINGLEMDS failed"
27466         rm -rf $DIR/$tdir
27467 }
27468 run_test 818 "unlink with failed llog"
27469
27470 test_819a() {
27471         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
27472         cancel_lru_locks osc
27473         #define OBD_FAIL_OST_2BIG_NIOBUF                0x248
27474         do_facet $SINGLEMDS lctl set_param fail_loc=0x80000248
27475         dd if=$DIR/$tfile of=/dev/null bs=1M count=1
27476         rm -f $TDIR/$tfile
27477 }
27478 run_test 819a "too big niobuf in read"
27479
27480 test_819b() {
27481         #define OBD_FAIL_OST_2BIG_NIOBUF                0x248
27482         do_facet $SINGLEMDS lctl set_param fail_loc=0x80000248
27483         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
27484         cancel_lru_locks osc
27485         sleep 1
27486         rm -f $TDIR/$tfile
27487 }
27488 run_test 819b "too big niobuf in write"
27489
27490
27491 function test_820_start_ost() {
27492         sleep 5
27493
27494         for num in $(seq $OSTCOUNT); do
27495                 start ost$num $(ostdevname $num) $OST_MOUNT_OPTS
27496         done
27497 }
27498
27499 test_820() {
27500         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
27501
27502         mkdir $DIR/$tdir
27503         umount_client $MOUNT || error "umount failed"
27504         for num in $(seq $OSTCOUNT); do
27505                 stop ost$num
27506         done
27507
27508         # mount client with no active OSTs
27509         # so that the client can't initialize max LOV EA size
27510         # from OSC notifications
27511         mount_client $MOUNT || error "mount failed"
27512         # delay OST starting to keep this 0 max EA size for a while
27513         test_820_start_ost &
27514
27515         # create a directory on MDS2
27516         test_mkdir -i 1 -c1 $DIR/$tdir/mds2 ||
27517                 error "Failed to create directory"
27518         # open intent should update default EA size
27519         # see mdc_update_max_ea_from_body()
27520         # notice this is the very first RPC to MDS2
27521         out=$(cp /etc/services $DIR/$tdir/mds2 2>&1)
27522         ret=$?
27523         echo $out
27524         # With SSK, this situation can lead to -EPERM being returned.
27525         # In that case, simply retry.
27526         if [ $ret -ne 0 ] && $SHARED_KEY; then
27527                 if echo "$out" | grep -q "not permitted"; then
27528                         cp /etc/services $DIR/$tdir/mds2
27529                         ret=$?
27530                 fi
27531         fi
27532         [ $ret -eq 0 ] || error "Failed to copy files to mds$n"
27533 }
27534 run_test 820 "update max EA from open intent"
27535
27536 test_822() {
27537         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
27538
27539         save_lustre_params mds1 \
27540                 "osp.$FSNAME-OST*-osc-MDT0000.max_create_count" > $p
27541         do_facet $SINGLEMDS "$LCTL set_param -n \
27542                         osp.$FSNAME-OST*MDT0000.max_create_count=0"
27543         do_facet $SINGLEMDS "$LCTL set_param -n \
27544                         osp.$FSNAME-OST0000*MDT0000.max_create_count=20000"
27545
27546         # wait for statfs update to clear OS_STATFS_NOPRECREATE
27547         local maxage=$(do_facet mds1 $LCTL get_param -n \
27548                        osp.$FSNAME-OST0000*MDT0000.maxage)
27549         sleep $((maxage + 1))
27550
27551         #define OBD_FAIL_NET_ERROR_RPC          0x532
27552         do_facet mds1 "$LCTL set_param fail_loc=0x80000532 fail_val=5"
27553
27554         stack_trap "restore_lustre_params < $p; rm $p"
27555
27556         local count=$(do_facet $SINGLEMDS "lctl get_param -n \
27557                       osp.$FSNAME-OST0000*MDT0000.create_count")
27558         for i in $(seq 1 $count); do
27559                 touch $DIR/$tfile.${i} || error "touch failed"
27560         done
27561 }
27562 run_test 822 "test precreate failure"
27563
27564 test_823() {
27565         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
27566         local OST_MAX_PRECREATE=20000
27567
27568         save_lustre_params mds1 \
27569                 "osp.$FSNAME-OST*-osc-MDT0000.max_create_count" > $p
27570         do_facet $SINGLEMDS "$LCTL set_param -n \
27571                 osp.$FSNAME-OST*MDT0000.max_create_count=0"
27572         do_facet $SINGLEMDS "$LCTL set_param -n \
27573                 osp.$FSNAME-OST0000*MDT0000.max_create_count=$OST_MAX_PRECREATE"
27574
27575         stack_trap "restore_lustre_params < $p; rm $p"
27576
27577         do_facet $SINGLEMDS "$LCTL set_param -n \
27578                 osp.$FSNAME-OST*-osc-MDT*.create_count=100200"
27579
27580         local count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
27581                       osp.$FSNAME-OST0000*MDT0000.create_count")
27582         local max=$(do_facet $SINGLEMDS "$LCTL get_param -n \
27583                     osp.$FSNAME-OST0000*MDT0000.max_create_count")
27584         local expect_count=$(((($max/2)/256) * 256))
27585
27586         log "setting create_count to 100200:"
27587         log " -result- count: $count with max: $max, expecting: $expect_count"
27588
27589         [[ $count -eq expect_count ]] ||
27590                 error "Create count not set to max precreate."
27591 }
27592 run_test 823 "Setting create_count > OST_MAX_PRECREATE is lowered to maximum"
27593
27594 test_831() {
27595         local sync_changes=$(do_facet $SINGLEMDS \
27596                 $LCTL get_param -n osp.$FSNAME-OST0000-osc-MDT0000.sync_changes)
27597
27598         [ "$sync_changes" -gt 100 ] &&
27599                 skip "Sync changes $sync_changes > 100 already"
27600
27601         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
27602
27603         $LFS mkdir -i 0 $DIR/$tdir
27604         $LFS setstripe -c 1 -i 0 $DIR/$tdir
27605
27606         save_lustre_params mds1 \
27607                 "osp.$FSNAME-OST*-osc-MDT0000.max_sync_changes" > $p
27608         save_lustre_params mds1 \
27609                 "osp.$FSNAME-OST*-osc-MDT0000.max_rpcs_in_progress" >> $p
27610
27611         do_facet mds1 "$LCTL set_param -n \
27612                 osp.$FSNAME-OST*-osc-MDT0000.max_sync_changes=100 \
27613                 osp.$FSNAME-OST*-osc-MDT0000.max_rpcs_in_progress=128"
27614         stack_trap "restore_lustre_params < $p" EXIT
27615
27616         createmany -o $DIR/$tdir/f- 1000
27617         unlinkmany $DIR/$tdir/f- 1000 &
27618         local UNLINK_PID=$!
27619
27620         while sleep 1; do
27621                 sync_changes=$(do_facet mds1 \
27622                 $LCTL get_param -n osp.$FSNAME-OST0000-osc-MDT0000.sync_changes)
27623                 # the check in the code is racy, fail the test
27624                 # if the value above the limit by 10.
27625                 [ $sync_changes -gt 110 ] && {
27626                         kill -2 $UNLINK_PID
27627                         wait
27628                         error "osp changes throttling failed, $sync_changes>110"
27629                 }
27630                 kill -0 $UNLINK_PID 2> /dev/null || break
27631         done
27632         wait
27633 }
27634 run_test 831 "throttling unlink/setattr queuing on OSP"
27635
27636 #
27637 # tests that do cleanup/setup should be run at the end
27638 #
27639
27640 test_900() {
27641         [ $PARALLEL == "yes" ] && skip "skip parallel run"
27642         local ls
27643
27644         #define OBD_FAIL_MGC_PAUSE_PROCESS_LOG   0x903
27645         $LCTL set_param fail_loc=0x903
27646
27647         cancel_lru_locks MGC
27648
27649         FAIL_ON_ERROR=true cleanup
27650         FAIL_ON_ERROR=true setup
27651 }
27652 run_test 900 "umount should not race with any mgc requeue thread"
27653
27654 # LUS-6253/LU-11185
27655 test_901() {
27656         local oldc
27657         local newc
27658         local olds
27659         local news
27660         [ $PARALLEL == "yes" ] && skip "skip parallel run"
27661
27662         # some get_param have a bug to handle dot in param name
27663         cancel_lru_locks MGC
27664         oldc=$($LCTL get_param -n 'ldlm.namespaces.MGC*.lock_count')
27665         olds=$(do_facet mgs $LCTL get_param -n 'ldlm.namespaces.MGS*.lock_count')
27666         umount_client $MOUNT || error "umount failed"
27667         mount_client $MOUNT || error "mount failed"
27668         cancel_lru_locks MGC
27669         newc=$($LCTL get_param -n 'ldlm.namespaces.MGC*.lock_count')
27670         news=$(do_facet mgs $LCTL get_param -n 'ldlm.namespaces.MGS*.lock_count')
27671
27672         [ $oldc -lt $newc ] && error "mgc lock leak ($oldc != $newc)"
27673         [ $olds -lt $news ] && error "mgs lock leak ($olds != $news)"
27674
27675         return 0
27676 }
27677 run_test 901 "don't leak a mgc lock on client umount"
27678
27679 # LU-13377
27680 test_902() {
27681         [ $CLIENT_VERSION -lt $(version_code 2.13.52) ] &&
27682                 skip "client does not have LU-13377 fix"
27683         #define OBD_FAIL_LLITE_SHORT_COMMIT 0x1415
27684         $LCTL set_param fail_loc=0x1415
27685         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
27686         cancel_lru_locks osc
27687         rm -f $DIR/$tfile
27688 }
27689 run_test 902 "test short write doesn't hang lustre"
27690
27691 # LU-14711
27692 test_903() {
27693         $LFS setstripe -i 0 -c 1 $DIR/$tfile $DIR/${tfile}-2
27694         echo "blah" > $DIR/${tfile}-2
27695         dd if=/dev/zero of=$DIR/$tfile bs=1M count=6 conv=fsync
27696         #define OBD_FAIL_OSC_SLOW_PAGE_EVICT 0x417
27697         $LCTL set_param fail_loc=0x417 fail_val=20
27698
27699         mv $DIR/${tfile}-2 $DIR/$tfile # Destroys the big object
27700         sleep 1 # To start the destroy
27701         wait_destroy_complete 150 || error "Destroy taking too long"
27702         cat $DIR/$tfile > /dev/null || error "Evicted"
27703 }
27704 run_test 903 "Test long page discard does not cause evictions"
27705
27706 complete $SECONDS
27707 [ -f $EXT2_DEV ] && rm $EXT2_DEV || true
27708 check_and_cleanup_lustre
27709 if [ "$I_MOUNTED" != "yes" ]; then
27710         lctl set_param debug="$OLDDEBUG" 2> /dev/null || true
27711 fi
27712 exit_status